From f6ac5cadeaa003b38f4695cedc3ff643ef9031c1 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 30 Jul 2013 16:55:33 +0200 Subject: [PATCH] use dedicated buffers for route (and track) "scratch buffers are by definition scratch and their contents are undefined at all times" "silent buffers are by definition all-zero and should not be used for real data" But track & route were using those for actual data; plugins (which may run in the same thread and may get the same buffers) use them for scratch thereby overwriting real data. In particular get_silent_buffers() (used by LadspaPlugin::connect_and_run) clears the buffer which can holds real data: e.g. via Route::passthru_silence() -> plugin1 -> plugin2 (clears output of plugin1) --- libs/ardour/ardour/process_thread.h | 1 + libs/ardour/ardour/session.h | 1 + libs/ardour/ardour/thread_buffers.h | 1 + libs/ardour/ladspa_plugin.cc | 2 +- libs/ardour/process_thread.cc | 27 +++++++++++++++++++++++++++ libs/ardour/route.cc | 8 ++++---- libs/ardour/session.cc | 7 +++++++ libs/ardour/thread_buffers.cc | 2 ++ libs/ardour/track.cc | 4 ++-- 9 files changed, 46 insertions(+), 7 deletions(-) diff --git a/libs/ardour/ardour/process_thread.h b/libs/ardour/ardour/process_thread.h index 0c197e9fb2..399cd506a3 100644 --- a/libs/ardour/ardour/process_thread.h +++ b/libs/ardour/ardour/process_thread.h @@ -46,6 +46,7 @@ public: static BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO); static BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO); + static BufferSet& get_route_buffers (ChanCount count = ChanCount::ZERO, bool silence = false); static BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO); static gain_t* gain_automation_buffer (); static gain_t* send_gain_automation_buffer (); diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 9ae67bf6b1..3bd57319bb 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -201,6 +201,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO); BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO); + BufferSet& get_route_buffers (ChanCount count = ChanCount::ZERO, bool silence = true); BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO); bool have_rec_enabled_track () const; diff --git a/libs/ardour/ardour/thread_buffers.h b/libs/ardour/ardour/thread_buffers.h index cd0b76511a..9d92454887 100644 --- a/libs/ardour/ardour/thread_buffers.h +++ b/libs/ardour/ardour/thread_buffers.h @@ -38,6 +38,7 @@ public: BufferSet* silent_buffers; BufferSet* scratch_buffers; + BufferSet* route_buffers; BufferSet* mix_buffers; gain_t* gain_automation_buffer; gain_t* send_gain_automation_buffer; diff --git a/libs/ardour/ladspa_plugin.cc b/libs/ardour/ladspa_plugin.cc index 1ab00e0b34..5a6e577f2d 100644 --- a/libs/ardour/ladspa_plugin.cc +++ b/libs/ardour/ladspa_plugin.cc @@ -562,7 +562,7 @@ LadspaPlugin::connect_and_run (BufferSet& bufs, cycles_t then = get_cycles (); BufferSet& silent_bufs = _session.get_silent_buffers(ChanCount(DataType::AUDIO, 1)); - BufferSet& scratch_bufs = _session.get_silent_buffers(ChanCount(DataType::AUDIO, 1)); + BufferSet& scratch_bufs = _session.get_scratch_buffers(ChanCount(DataType::AUDIO, 1)); uint32_t audio_in_index = 0; uint32_t audio_out_index = 0; diff --git a/libs/ardour/process_thread.cc b/libs/ardour/process_thread.cc index e10ccf160c..2ffb47a0df 100644 --- a/libs/ardour/process_thread.cc +++ b/libs/ardour/process_thread.cc @@ -108,6 +108,33 @@ ProcessThread::get_scratch_buffers (ChanCount count) return *sb; } +BufferSet& +ProcessThread::get_route_buffers (ChanCount count, bool silence) +{ + ThreadBuffers* tb = _private_thread_buffers.get(); + assert (tb); + + BufferSet* sb = tb->scratch_buffers; + assert (sb); + + if (count != ChanCount::ZERO) { + assert(sb->available() >= count); + sb->set_count (count); + } else { + sb->set_count (sb->available()); + } + + if (silence) { + for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) { + for (size_t i= 0; i < count.get(*t); ++i) { + sb->get(*t, i).clear(); + } + } + } + + return *sb; +} + BufferSet& ProcessThread::get_mix_buffers (ChanCount count) { diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc index 1eb92c68aa..a394c73d20 100644 --- a/libs/ardour/route.cc +++ b/libs/ardour/route.cc @@ -571,7 +571,7 @@ void Route::monitor_run (framepos_t start_frame, framepos_t end_frame, pframes_t nframes, int declick) { assert (is_monitor()); - BufferSet& bufs (_session.get_scratch_buffers (n_process_buffers())); + BufferSet& bufs (_session.get_route_buffers (n_process_buffers())); passthru (bufs, start_frame, end_frame, nframes, declick); } @@ -597,7 +597,7 @@ Route::passthru (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, void Route::passthru_silence (framepos_t start_frame, framepos_t end_frame, pframes_t nframes, int declick) { - BufferSet& bufs (_session.get_silent_buffers (n_process_buffers())); + BufferSet& bufs (_session.get_route_buffers (n_process_buffers(), true)); bufs.set_count (_input->n_ports()); write_out_of_band_data (bufs, start_frame, end_frame, nframes); @@ -3016,7 +3016,7 @@ Route::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, */ } - BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers()); + BufferSet& bufs = _session.get_route_buffers (n_process_buffers()); fill_buffers_with_input (bufs, _input, nframes); @@ -3055,7 +3055,7 @@ Route::roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, in _silent = false; - BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers()); + BufferSet& bufs = _session.get_route_buffers (n_process_buffers()); fill_buffers_with_input (bufs, _input, nframes); diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 914c6a9a77..ccc694f878 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -4175,6 +4175,13 @@ Session::get_scratch_buffers (ChanCount count) return ProcessThread::get_scratch_buffers (count); } +BufferSet& +Session::get_route_buffers (ChanCount count, bool silence) +{ + return ProcessThread::get_route_buffers (count, silence); +} + + BufferSet& Session::get_mix_buffers (ChanCount count) { diff --git a/libs/ardour/thread_buffers.cc b/libs/ardour/thread_buffers.cc index 34f6f9828b..fd3160bb15 100644 --- a/libs/ardour/thread_buffers.cc +++ b/libs/ardour/thread_buffers.cc @@ -30,6 +30,7 @@ using namespace std; ThreadBuffers::ThreadBuffers () : silent_buffers (new BufferSet) , scratch_buffers (new BufferSet) + , route_buffers (new BufferSet) , mix_buffers (new BufferSet) , gain_automation_buffer (0) , send_gain_automation_buffer (0) @@ -64,6 +65,7 @@ ThreadBuffers::ensure_buffers (ChanCount howmany) scratch_buffers->ensure_buffers (*t, count, size); mix_buffers->ensure_buffers (*t, count, size); silent_buffers->ensure_buffers (*t, count, size); + route_buffers->ensure_buffers (*t, count, size); } delete [] gain_automation_buffer; diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc index 9db8e1ff3a..7d90709b6f 100644 --- a/libs/ardour/track.cc +++ b/libs/ardour/track.cc @@ -451,7 +451,7 @@ Track::no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, } else { - BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers()); + BufferSet& bufs = _session.get_route_buffers (n_process_buffers()); fill_buffers_with_input (bufs, _input, nframes); @@ -496,7 +496,7 @@ Track::silent_roll (pframes_t nframes, framepos_t /*start_frame*/, framepos_t /* framecnt_t playback_distance; - BufferSet& bufs (_session.get_silent_buffers (n_process_buffers())); + BufferSet& bufs (_session.get_route_buffers (n_process_buffers(), true)); int const dret = _diskstream->process (bufs, _session.transport_frame(), nframes, playback_distance, false); need_butler = _diskstream->commit (playback_distance);