Skip to content

Commit 969379b

Browse files
committed
0.31.9
1 parent 7fd74d7 commit 969379b

File tree

10 files changed

+98
-1
lines changed

10 files changed

+98
-1
lines changed

buildspec.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@
4747
"uuids": {
4848
"windowsApp": "ad885c58-5ca9-44de-8f4f-1c12676626a9"
4949
},
50-
"version": "0.31.8",
50+
"version": "0.31.9",
5151
"website": "https://www.atkaudio.com"
5252
}

lib/atkaudio/src/atkaudio/DeviceIo/DeviceIo.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

212240
void 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+
217256
void atk::DeviceIo::setMixInput(bool mixInput)
218257
{
219258
pImpl->setMixInput(mixInput);

lib/atkaudio/src/atkaudio/DeviceIo/DeviceIo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ class DeviceIo : public atkAudioModule
1414

1515
void process(float** buffer, int numChannels, int numSamples, double sampleRate) override;
1616

17+
// Bypass processing when filter should be inactive (e.g., not in scene)
18+
void setBypass(bool shouldBypass);
19+
bool isBypassed() const;
20+
1721
void setMixInput(bool mixInput);
1822
void setOutputDelay(float delayMs);
1923
float getOutputDelay() const;

lib/atkaudio/src/atkaudio/DeviceIo2/DeviceIo2.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ struct atk::DeviceIo2::Impl : public juce::AsyncUpdater
3131
std::vector<juce::dsp::DelayLine<float, juce::dsp::DelayLineInterpolationTypes::Linear>> outputDelayLines;
3232
std::vector<juce::SmoothedValue<float, juce::ValueSmoothingTypes::Linear>> outputDelaySmooth;
3333
bool delayPrepared = false;
34+
std::atomic<bool> bypass{false};
35+
std::atomic<bool> wasBypassed{false};
3436

3537
enum class UpdateType
3638
{
@@ -194,6 +196,16 @@ struct atk::DeviceIo2::Impl : public juce::AsyncUpdater
194196

195197
void process(float** buffer, int numChannels, int numSamples, double sampleRate)
196198
{
199+
bool currentBypass = bypass.load(std::memory_order_acquire);
200+
bool wasJustBypassed = wasBypassed.exchange(currentBypass, std::memory_order_acq_rel);
201+
202+
// When bypassed, leave buffer as-is and skip IO routing
203+
if (currentBypass)
204+
return;
205+
206+
// Clear stale data from AudioClient buffers when transitioning from bypassed to active
207+
if (wasJustBypassed)
208+
audioClient.clearBuffers();
197209
bool needsReconfiguration =
198210
preparedNumChannels != numChannels || preparedNumSamples < numSamples || preparedSampleRate != sampleRate;
199211

@@ -543,6 +555,17 @@ void atk::DeviceIo2::process(float** buffer, int numChannels, int numSamples, do
543555
pImpl->process(buffer, numChannels, numSamples, sampleRate);
544556
}
545557

558+
void atk::DeviceIo2::setBypass(bool shouldBypass)
559+
{
560+
if (pImpl)
561+
pImpl->bypass.store(shouldBypass, std::memory_order_release);
562+
}
563+
564+
bool atk::DeviceIo2::isBypassed() const
565+
{
566+
return pImpl ? pImpl->bypass.load(std::memory_order_acquire) : false;
567+
}
568+
546569
void atk::DeviceIo2::setOutputDelay(float delayMs)
547570
{
548571
if (pImpl)

lib/atkaudio/src/atkaudio/DeviceIo2/DeviceIo2.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ class DeviceIo2 : public atkAudioModule
1515

1616
void process(float** buffer, int numChannels, int numSamples, double sampleRate) override;
1717

18+
// When bypassed, DeviceIo2 does no processing and leaves the buffer untouched
19+
void setBypass(bool shouldBypass);
20+
bool isBypassed() const;
21+
1822
void setOutputDelay(float delayMs);
1923
float getOutputDelay() const;
2024

lib/atkaudio/src/atkaudio/ModuleInfrastructure/AudioServer/AudioServer.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,23 @@ void AudioClient::pushSubscribedOutputs(const juce::AudioBuffer<float>& deviceBu
419419
}
420420
}
421421

422+
void AudioClient::clearBuffers()
423+
{
424+
auto snapshot = bufferSnapshot.load(std::memory_order_acquire);
425+
if (!snapshot)
426+
return;
427+
428+
// Clear all input buffers
429+
for (const auto& bufRef : snapshot->inputBuffers)
430+
if (bufRef.buffer)
431+
bufRef.buffer->reset();
432+
433+
// Clear all output buffers
434+
for (const auto& bufRef : snapshot->outputBuffers)
435+
if (bufRef.buffer)
436+
bufRef.buffer->reset();
437+
}
438+
422439
void AudioClient::setSubscriptions(const AudioClientState& state)
423440
{
424441
if (auto* server = AudioServer::getInstanceWithoutCreating())

lib/atkaudio/src/atkaudio/ModuleInfrastructure/AudioServer/AudioServer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ class AudioClient
146146

147147
void pullSubscribedInputs(juce::AudioBuffer<float>& deviceBuffer, int numSamples, double sampleRate);
148148
void pushSubscribedOutputs(const juce::AudioBuffer<float>& deviceBuffer, int numSamples, double sampleRate);
149+
void clearBuffers();
149150
void setSubscriptions(const AudioClientState& state);
150151
AudioClientState getSubscriptions() const;
151152

lib/atkaudio/src/atkaudio/PluginHost2/Core/DeviceIo2Plugin.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ class DeviceIo2Plugin final : public juce::AudioProcessor
8282
if (!deviceIo2)
8383
return;
8484

85+
if (deviceIo2->isBypassed())
86+
return;
87+
8588
// Convert JUCE buffer to raw pointer format expected by DeviceIo2
8689
const int numChannels = buffer.getNumChannels();
8790
const int numSamples = buffer.getNumSamples();

src/device_io.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,9 @@ static struct obs_audio_data* devio_filter(void* data, struct obs_audio_data* au
194194
for (size_t j = 0; j < frames; j++)
195195
adata[i][j] *= outputGain;
196196

197+
if (obs_source_t* parent = obs_filter_get_parent(adio->context))
198+
adio->deviceIo.setBypass(!obs_source_active(parent));
199+
197200
adio->deviceIo.setMixInput(adio->mixInput.load(std::memory_order_acquire));
198201
adio->deviceIo.process(adata, channels, frames, adio->sampleRate);
199202

src/device_io2.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ static struct obs_audio_data* deviceio2_filter(void* data, struct obs_audio_data
187187
for (size_t j = 0; j < frames; j++)
188188
adata[i][j] *= outputGain;
189189

190+
if (obs_source_t* parent = obs_filter_get_parent(adio->context))
191+
adio->deviceIo2.setBypass(!obs_source_active(parent));
192+
190193
adio->deviceIo2.process(adata, channels, frames, adio->sampleRate);
191194

192195
auto inputGain = adio->inputGain.load(std::memory_order_acquire);

0 commit comments

Comments
 (0)