summaryrefslogtreecommitdiff
path: root/libs/ardour/audio_track.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2013-03-27 21:50:18 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2013-03-27 21:50:18 -0400
commit4abbabdcf9c6d6d98ba261d91846577a2fa2f05e (patch)
tree5a7134ccc9508a6f1da25ef3dc6d432bdc25a04f /libs/ardour/audio_track.cc
parent78aa7a13fd5e5abac70637ce6641b7d2e73dd541 (diff)
Squashed commit of the following:
commit fdbae82077db53add90df7448a06869dac89acc6 Author: Paul Davis <paul@linuxaudiosystems.com> Date: Wed Mar 27 21:45:28 2013 -0400 mammoth changes in basic signal flow, total redesign of MIDI channel filtering and more. commit 59343a8283698e02bc0f622313b29e98f449e4c8 Author: Paul Davis <paul@linuxaudiosystems.com> Date: Wed Mar 27 01:58:53 2013 -0400 initial working version after changes to MIDI channel filtering. may affect metering input too. testing not yet finished this commit merges many deep changes in ardour's internal architecture, combined with a total redesign of how MIDI channel filtering works. data in a track used to flow from JACK port buffers to diskstream's ringbuffers and was then copied from the ringbuffers into a BufferSet for use during Route::process_output_buffers(). The butler thread would handle the movement of data between the ringbuffers and disk. with this commit, data now flows from JACK port buffers into the BufferSet used for Route processing, and is copied from the BufferSet into the diskstream's ringbuffers (the butler thread continues to handle interactions with disk as usual). this change allowed a dramatic consolidation of code and simplification of most aspects of Track/Route::roll() and Track/Route::no_roll(). in particular, see Route::fill_buffers_with_input() which now concisely describes how we move data from JACK port buffers into the BufferSet for all Route types (including Tracks). this work was initially motivated by changing MIDI channel filtering so that we can process capture and playback independently. there is now a very clean pathway for this - see MidiTrack::roll() (NOTE: This needs implementing in the no-roll case too - a TODO item). the channel selector for MIDI tracks has been moved out of the track header and is now accessible via the context menu. more work is likely here, to make it (more) obvious to the user when filtering is going on.
Diffstat (limited to 'libs/ardour/audio_track.cc')
-rw-r--r--libs/ardour/audio_track.cc128
1 files changed, 12 insertions, 116 deletions
diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc
index 90439f46e9..070a7453fb 100644
--- a/libs/ardour/audio_track.cc
+++ b/libs/ardour/audio_track.cc
@@ -316,8 +316,6 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram
return 0;
}
- Sample* b;
- Sample* tmpb;
framepos_t transport_frame;
boost::shared_ptr<AudioDiskstream> diskstream = audio_diskstream();
@@ -342,7 +340,9 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram
to do nothing.
*/
- dret = diskstream->process (transport_frame, 0, playback_distance);
+ BufferSet bufs; /* empty set, no matter - nothing will happen */
+
+ dret = diskstream->process (bufs, transport_frame, 0, playback_distance, false);
need_butler = diskstream->commit (playback_distance);
return dret;
}
@@ -350,126 +350,22 @@ AudioTrack::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_fram
_silent = false;
_amp->apply_gain_automation(false);
- if ((dret = diskstream->process (transport_frame, nframes, playback_distance)) != 0) {
- need_butler = diskstream->commit (playback_distance);
- silence (nframes);
- return dret;
- }
-
- /* special condition applies */
+ BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers ());
+ fill_buffers_with_input (bufs, _input, nframes);
+
if (_meter_point == MeterInput) {
- _input->process_input (_meter, start_frame, end_frame, nframes);
+ _meter->run (bufs, start_frame, end_frame, nframes, true);
}
- if (monitoring_state() == MonitoringInput) {
-
- passthru (start_frame, end_frame, nframes, false);
-
- } else if ((b = diskstream->playback_buffer(0)) != 0) {
-
- /*
- XXX is it true that the earlier test on n_outputs()
- means that we can avoid checking it again here? i think
- so, because changing the i/o configuration of an IO
- requires holding the AudioEngine lock, which we hold
- while in the process() tree.
- */
-
-
- /* copy the diskstream data to all output buffers */
-
- size_t limit = input_streams ().n_audio();
- BufferSet& bufs = _session.get_scratch_buffers ();
- const size_t blimit = bufs.count().n_audio();
-
- uint32_t n;
- uint32_t i;
-
- if (limit > blimit) {
-
- /* example case: auditioner configured for stereo output,
- but loaded with an 8 channel file. there are only
- 2 passthrough buffers, but n_process_buffers() will
- return 8.
-
- arbitrary decision: map all channels in the diskstream
- to the outputs available.
- */
-
- float scaling = limit/blimit;
-
- for (i = 0, n = 1; i < blimit; ++i, ++n) {
-
- /* first time through just copy a channel into
- the output buffer.
- */
-
- Sample* bb = bufs.get_audio (i).data();
-
- for (pframes_t xx = 0; xx < nframes; ++xx) {
- bb[xx] = b[xx] * scaling;
- }
-
- if (n < diskstream->n_channels().n_audio()) {
- tmpb = diskstream->playback_buffer(n);
- if (tmpb!=0) {
- b = tmpb;
- }
- }
- }
-
- for (;i < limit; ++i, ++n) {
-
- /* for all remaining channels, sum with existing
- data in the output buffers
- */
-
- bufs.get_audio (i%blimit).accumulate_with_gain_from (b, nframes, 0, scaling);
-
- if (n < diskstream->n_channels().n_audio()) {
- tmpb = diskstream->playback_buffer(n);
- if (tmpb!=0) {
- b = tmpb;
- }
- }
-
- }
-
- limit = blimit;
-
- } else {
- for (i = 0, n = 1; i < limit; ++i, ++n) {
- memcpy (bufs.get_audio (i).data(), b, sizeof (Sample) * nframes);
- if (n < diskstream->n_channels().n_audio()) {
- tmpb = diskstream->playback_buffer(n);
- if (tmpb!=0) {
- b = tmpb;
- }
- }
- }
-
- /* try to leave any MIDI buffers alone */
-
- ChanCount chn;
- chn.set_audio (limit);
- chn.set_midi (_input->n_ports().n_midi());
- bufs.set_count (chn);
- }
-
- /* final argument: don't waste time with automation if we're recording or we've just stopped (yes it can happen) */
-
- process_output_buffers (
- bufs, start_frame, end_frame, nframes,
- declick,
- (!diskstream->record_enabled() && _session.transport_rolling())
- );
-
- } else {
- /* problem with the diskstream; just be quiet for a bit */
+ if ((dret = diskstream->process (bufs, transport_frame, nframes, playback_distance, (monitoring_state() == MonitoringDisk))) != 0) {
+ need_butler = diskstream->commit (playback_distance);
silence (nframes);
+ return dret;
}
+ process_output_buffers (bufs, start_frame, end_frame, nframes, declick, (!diskstream->record_enabled() && _session.transport_rolling()));
+
need_butler = diskstream->commit (playback_distance);
return 0;