@@ -29,6 +29,21 @@ struct atk::DeviceIo::Impl
2929
3030 void process (float ** buffer, int numChannels, int numSamples, double sampleRate)
3131 {
32+ bool currentBypass = bypass.load (std::memory_order_acquire);
33+ bool wasJustBypassed = wasBypassed.exchange (currentBypass, std::memory_order_acq_rel);
34+
35+ if (currentBypass)
36+ return ;
37+
38+ // Clear stale data from buffers when transitioning from bypassed to active
39+ if (wasJustBypassed)
40+ {
41+ auto & toObsBuffer = deviceIoApp->getToObsBuffer ();
42+ auto & fromObsBuffer = deviceIoApp->getFromObsBuffer ();
43+ toObsBuffer.reset ();
44+ fromObsBuffer.reset ();
45+ }
46+
3247 if (tempBuffer.getNumChannels () < numChannels || tempBuffer.getNumSamples () < numSamples)
3348 tempBuffer.setSize (numChannels, numSamples, false , false , true );
3449
@@ -207,13 +222,37 @@ struct atk::DeviceIo::Impl
207222 bool delayPrepared = false ;
208223
209224 bool mixInput = false ;
225+ std::atomic<bool > bypass{false };
226+ std::atomic<bool > wasBypassed{false };
227+
228+ public:
229+ void setBypass (bool v)
230+ {
231+ bypass.store (v, std::memory_order_release);
232+ }
233+
234+ bool isBypassed () const
235+ {
236+ return bypass.load (std::memory_order_acquire);
237+ }
210238};
211239
212240void atk::DeviceIo::process (float ** buffer, int numChannels, int numSamples, double sampleRate)
213241{
214242 pImpl->process (buffer, numChannels, numSamples, sampleRate);
215243}
216244
245+ void atk::DeviceIo::setBypass (bool shouldBypass)
246+ {
247+ if (pImpl)
248+ pImpl->setBypass (shouldBypass);
249+ }
250+
251+ bool atk::DeviceIo::isBypassed () const
252+ {
253+ return pImpl ? pImpl->isBypassed () : false ;
254+ }
255+
217256void atk::DeviceIo::setMixInput (bool mixInput)
218257{
219258 pImpl->setMixInput (mixInput);
0 commit comments