From 124cefd0d7e776431ee7102dd874c965c00b9927 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Fri, 15 Jan 2021 16:38:20 -0500 Subject: [PATCH] Add DC blocker to AudioInterface. --- src/core/AudioInterface.cpp | 44 +++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/core/AudioInterface.cpp b/src/core/AudioInterface.cpp index 3ec5f868..a19b9685 100644 --- a/src/core/AudioInterface.cpp +++ b/src/core/AudioInterface.cpp @@ -36,6 +36,9 @@ struct AudioInterface : Module, audio::Port { NUM_LIGHTS }; + dsp::RCFilter dcFilters[NUM_AUDIO_INPUTS]; + bool dcFilterEnabled = false; + dsp::DoubleRingBuffer, 32768> engineInputBuffer; dsp::DoubleRingBuffer, 32768> engineOutputBuffer; @@ -71,6 +74,13 @@ struct AudioInterface : Module, audio::Port { maxChannels = std::max(NUM_AUDIO_INPUTS, NUM_AUDIO_OUTPUTS); inputSrc.setQuality(6); outputSrc.setQuality(6); + + float sampleTime = APP->engine->getSampleTime(); + for (int i = 0; i < NUM_AUDIO_INPUTS; i++) { + dcFilters[i].setCutoffFreq(10.f * sampleTime); + } + + reset(); } ~AudioInterface() { @@ -80,11 +90,20 @@ struct AudioInterface : Module, audio::Port { void onReset() override { setDriverId(-1); + + if (NUM_AUDIO_INPUTS == 2) + dcFilterEnabled = true; + else + dcFilterEnabled = false; } void onSampleRateChange(const SampleRateChangeEvent& e) override { engineInputBuffer.clear(); engineOutputBuffer.clear(); + + for (int i = 0; i < NUM_AUDIO_INPUTS; i++) { + dcFilters[i].setCutoffFreq(10.f * e.sampleTime); + } } void process(const ProcessArgs& args) override { @@ -102,6 +121,12 @@ struct AudioInterface : Module, audio::Port { else if (i == 1 && NUM_AUDIO_INPUTS == 2) v = inputFrame.samples[0]; + // Apply DC filter + if (dcFilterEnabled) { + dcFilters[i].process(v); + v = dcFilters[i].highpass(); + } + // Detect clipping if (NUM_AUDIO_INPUTS > 2) { if (std::fabs(v) >= 1.f) @@ -195,6 +220,8 @@ struct AudioInterface : Module, audio::Port { if (isPrimary()) json_object_set_new(rootJ, "primary", json_boolean(true)); + json_object_set_new(rootJ, "dcFilter", json_boolean(dcFilterEnabled)); + return rootJ; } @@ -206,6 +233,10 @@ struct AudioInterface : Module, audio::Port { json_t* primaryJ = json_object_get(rootJ, "primary"); if (primaryJ) setPrimary(); + + json_t* dcFilterJ = json_object_get(rootJ, "dcFilter"); + if (dcFilterJ) + dcFilterEnabled = json_boolean_value(dcFilterJ); } /** Must be called when the Engine mutex is unlocked. @@ -513,6 +544,19 @@ struct AudioInterfaceWidget : ModuleWidget { primaryModuleItem->rightText = CHECKMARK(module->isPrimary()); primaryModuleItem->module = module; menu->addChild(primaryModuleItem); + + struct DCFilterItem : MenuItem { + TAudioInterface* module; + void onAction(const event::Action& e) override { + module->dcFilterEnabled ^= true; + } + }; + + DCFilterItem* dcFilterItem = new DCFilterItem; + dcFilterItem->text = "DC blocker"; + dcFilterItem->rightText = CHECKMARK(module->dcFilterEnabled); + dcFilterItem->module = module; + menu->addChild(dcFilterItem); } };