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)
This commit is contained in:
Robin Gareus 2013-07-30 16:55:33 +02:00
parent 44fc92c33d
commit 00f26394a9
9 changed files with 46 additions and 7 deletions

View File

@ -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 ();

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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)
{

View File

@ -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);

View File

@ -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)
{

View File

@ -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;

View File

@ -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);