use zeroed scratch buffers for "silent" plugin runs
authorRobin Gareus <robin@gareus.org>
Wed, 31 Jul 2013 22:35:24 +0000 (00:35 +0200)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 8 Aug 2013 19:26:18 +0000 (15:26 -0400)
Plugins rewrite the buffer data in-place and some plugins
can produce output even when fed with silence.

Hence, during a PluginInsert::silence() run a plugin can
inject data into the "silent" buffers which causes side-effects.

Kudos to Chris 'oofus' Goddard for finding this issue.

libs/ardour/ardour/process_thread.h
libs/ardour/ardour/session.h
libs/ardour/plugin_insert.cc
libs/ardour/process_thread.cc
libs/ardour/session.cc

index 399cd506a330c099b3c8afdf836a7e64c3e37785..f96595fbbf9a558919dbc15e1b217498c39c3997 100644 (file)
@@ -45,7 +45,7 @@ public:
         */
 
        static BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
-       static BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
+       static BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO, bool silence = false);
        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 ();
index 3bd57319bb8718d0ac376cd84b7f4fdc45221d8f..8012970133bca81a85b83cc610fe1b6a116ff05c 100644 (file)
@@ -200,7 +200,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        void process (pframes_t nframes);
 
        BufferSet& get_silent_buffers (ChanCount count = ChanCount::ZERO);
-       BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO);
+       BufferSet& get_scratch_buffers (ChanCount count = ChanCount::ZERO, bool silence = true );
        BufferSet& get_route_buffers (ChanCount count = ChanCount::ZERO, bool silence = true);
        BufferSet& get_mix_buffers (ChanCount count = ChanCount::ZERO);
 
index 998a03e3aa13a5583a4910dd25c6e8665236493e..d519dbd7a7d4d152ac2ba0800436424224e3f6cc 100644 (file)
@@ -448,7 +448,7 @@ PluginInsert::silence (framecnt_t nframes)
        }
 
        for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
-               (*i)->connect_and_run (_session.get_silent_buffers ((*i)->get_info()->n_inputs), in_map, out_map, nframes, 0);
+               (*i)->connect_and_run (_session.get_scratch_buffers ((*i)->get_info()->n_inputs, true), in_map, out_map, nframes, 0);
        }
 }
 
index 5d8d6f34fdfd51393451f544fed1c72b9aecff77..d4a3d2f3908e3b89adabcf9e8a0d7683769be01f 100644 (file)
@@ -90,7 +90,7 @@ ProcessThread::get_silent_buffers (ChanCount count)
 }
 
 BufferSet&
-ProcessThread::get_scratch_buffers (ChanCount count)
+ProcessThread::get_scratch_buffers (ChanCount count, bool silence)
 {
         ThreadBuffers* tb = _private_thread_buffers.get();
         assert (tb);
@@ -105,6 +105,14 @@ ProcessThread::get_scratch_buffers (ChanCount count)
                sb->set_count (sb->available());
        }
 
+       if (silence) {
+               for (DataType::iterator t = DataType::begin(); t != DataType::end(); ++t) {
+                       for (uint32_t i = 0; i < sb->count().get(*t); ++i) {
+                               sb->get(*t, i).clear();
+                       }
+               }
+       }
+
        return *sb;
 }
 
index ccc694f8788a60a5490a32ed393c88a216d62cde..ce82f79bb5a122edf4b33a9b340137beca47ce59 100644 (file)
@@ -4170,9 +4170,9 @@ Session::get_silent_buffers (ChanCount count)
 }
 
 BufferSet&
-Session::get_scratch_buffers (ChanCount count)
+Session::get_scratch_buffers (ChanCount count, bool silence)
 {
-       return ProcessThread::get_scratch_buffers (count);
+       return ProcessThread::get_scratch_buffers (count, silence);
 }
 
 BufferSet&