From 4c7c5b16940c29b2eff5de3c58e51b8c012ac481 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Mon, 4 Jan 2021 08:23:51 -0500 Subject: [PATCH] Add auto engine sample rate setting. --- include/engine/Engine.hpp | 3 ++- src/app/MenuBar.cpp | 12 ++++++++++- src/core/AudioInterface.cpp | 2 +- src/engine/Engine.cpp | 41 +++++++++++++++++++++++++------------ src/settings.cpp | 2 +- 5 files changed, 43 insertions(+), 17 deletions(-) diff --git a/include/engine/Engine.hpp b/include/engine/Engine.hpp index e5d46f9d..c800596b 100644 --- a/include/engine/Engine.hpp +++ b/include/engine/Engine.hpp @@ -30,13 +30,14 @@ struct Engine { /** Advances the engine by `frames` frames. Only call this method from the primary module. */ - void stepBlock(int frames); + void stepBlock(int frames, float suggestedSampleRate = 0.f); void setPrimaryModule(Module* module); Module* getPrimaryModule(); /** Returns the sample rate used by the engine for stepping each module. */ float getSampleRate(); + PRIVATE void setSampleRate(float sampleRate); /** Returns the inverse of the current sample rate. */ float getSampleTime(); diff --git a/src/app/MenuBar.cpp b/src/app/MenuBar.cpp index f6e3b93d..e23e8383 100644 --- a/src/app/MenuBar.cpp +++ b/src/app/MenuBar.cpp @@ -492,6 +492,16 @@ struct SampleRateItem : ui::MenuItem { ui::Menu* createChildMenu() override { ui::Menu* menu = new ui::Menu; + SampleRateValueItem* autoItem = new SampleRateValueItem; + autoItem->sampleRate = 0; + autoItem->text = "Auto"; + if (settings::sampleRate == 0) { + float sampleRate = APP->engine->getSampleRate(); + autoItem->rightText = string::f("(%g kHz) ", sampleRate / 1000.f); + autoItem->rightText += CHECKMARK_STRING; + } + menu->addChild(autoItem); + for (int i = -2; i <= 4; i++) { for (int j = 0; j < 2; j++) { float oversample = std::pow(2.f, i); @@ -500,7 +510,7 @@ struct SampleRateItem : ui::MenuItem { SampleRateValueItem* item = new SampleRateValueItem; item->sampleRate = sampleRate; - item->text = string::f("%g kHz", sampleRate / 1000.0); + item->text = string::f("%g kHz", sampleRate / 1000.f); if (oversample > 1.f) { item->rightText += string::f("(%.0fx)", oversample); } diff --git a/src/core/AudioInterface.cpp b/src/core/AudioInterface.cpp index 9f3063d9..cd92469d 100644 --- a/src/core/AudioInterface.cpp +++ b/src/core/AudioInterface.cpp @@ -245,7 +245,7 @@ struct AudioInterface : Module, audio::Port { bool isPrimary = (APP->engine->getPrimaryModule() == this); // Step engine if (isPrimary && requestedEngineFrames > 0) { - APP->engine->stepBlock(requestedEngineFrames); + APP->engine->stepBlock(requestedEngineFrames, getSampleRate()); } } diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 845ad18f..d9230a95 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -182,6 +182,9 @@ struct EngineWorker { }; +static const float FALLBACK_SAMPLE_RATE = 44100; + + struct Engine::Internal { std::vector modules; std::vector cables; @@ -453,8 +456,7 @@ Engine::Engine() { internal = new Internal; internal->context = contextGet(); - internal->sampleRate = 44100.f; - internal->sampleTime = 1 / internal->sampleRate; + setSampleRate(FALLBACK_SAMPLE_RATE); } @@ -498,7 +500,7 @@ void Engine::clear() { } -void Engine::stepBlock(int frames) { +void Engine::stepBlock(int frames, float suggestedSampleRate) { std::lock_guard stepLock(internal->blockMutex); SharedLock lock(internal->mutex); // Configure thread @@ -510,16 +512,14 @@ void Engine::stepBlock(int frames) { internal->blockFrames = frames; // Set sample rate - if (internal->sampleRate != settings::sampleRate) { - internal->sampleRate = settings::sampleRate; - internal->sampleTime = 1.f / internal->sampleRate; - // Trigger SampleRateChangeEvent - Module::SampleRateChangeEvent e; - e.sampleRate = internal->sampleRate; - e.sampleTime = internal->sampleTime; - for (Module* module : internal->modules) { - module->onSampleRateChange(e); - } + if (settings::sampleRate > 0) { + setSampleRate(settings::sampleRate); + } + else if (suggestedSampleRate > 0) { + setSampleRate(suggestedSampleRate); + } + else { + setSampleRate(FALLBACK_SAMPLE_RATE); } // Update expander pointers @@ -570,6 +570,21 @@ float Engine::getSampleRate() { } +void Engine::setSampleRate(float sampleRate) { + if (sampleRate == internal->sampleRate) + return; + internal->sampleRate = sampleRate; + internal->sampleTime = 1.f / sampleRate; + // Trigger SampleRateChangeEvent + Module::SampleRateChangeEvent e; + e.sampleRate = internal->sampleRate; + e.sampleTime = internal->sampleTime; + for (Module* module : internal->modules) { + module->onSampleRateChange(e); + } +} + + float Engine::getSampleTime() { return internal->sampleTime; } diff --git a/src/settings.cpp b/src/settings.cpp index ff18861b..150930f9 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -26,7 +26,7 @@ float cableTension = 0.5; bool allowCursorLock = true; KnobMode knobMode = KNOB_MODE_LINEAR; float knobLinearSensitivity = 0.001f; -float sampleRate = 44100.0; +float sampleRate = 0; int threadCount = 1; bool tooltips = true; bool cpuMeter = false;