From 27f6a546aa7ad5b1c4aff3f7ad80d5929585efc9 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sat, 16 Feb 2019 17:02:54 -0500 Subject: [PATCH] Add dsp::Counter. Rename dsp::VUMeter to VuMeter. Add Light::setSmoothBrightness(), deprecate setBrightnessSmooth(). --- include/dsp/digital.hpp | 24 ++++++++++++++++++++++++ include/dsp/vumeter.hpp | 9 ++++++--- include/engine/Light.hpp | 23 ++++++++++++----------- include/engine/Port.hpp | 2 +- src/engine/Engine.cpp | 7 ++++--- src/engine/Port.cpp | 8 ++++---- 6 files changed, 51 insertions(+), 22 deletions(-) diff --git a/include/dsp/digital.hpp b/include/dsp/digital.hpp index 9152d310..9961974d 100644 --- a/include/dsp/digital.hpp +++ b/include/dsp/digital.hpp @@ -130,5 +130,29 @@ struct Timer { }; +struct Counter { + int count; + int period; + + Counter() { + reset(); + } + + void reset() { + count = 0; + period = 1; + } + + /** Returns true if the counter reaches `period` and resets. */ + bool process() { + if (++count >= period) { + count = 0; + return true; + } + return false; + } +}; + + } // namespace dsp } // namespace rack diff --git a/include/dsp/vumeter.hpp b/include/dsp/vumeter.hpp index 098a4592..c22038c9 100644 --- a/include/dsp/vumeter.hpp +++ b/include/dsp/vumeter.hpp @@ -6,8 +6,8 @@ namespace rack { namespace dsp { -/** Deprecated. Use VUMeter2. */ -struct VUMeter { +/** Deprecated. Use VuMeter2. */ +struct VuMeter { /** Decibel level difference between adjacent meter lights */ float dBInterval = 3.0; float dBScaled; @@ -30,7 +30,10 @@ struct VUMeter { }; -struct VUMeter2 { +DEPRECATED typedef VuMeter VUMeter; + + +struct VuMeter2 { enum Mode { PEAK, RMS diff --git a/include/engine/Light.hpp b/include/engine/Light.hpp index c160dc7b..46029b2c 100644 --- a/include/engine/Light.hpp +++ b/include/engine/Light.hpp @@ -7,12 +7,12 @@ namespace engine { struct Light { - /** The mean-square of the brightness. + /** The square of the brightness. Unstable API. Use set/getBrightness(). */ float value = 0.f; - /** Sets the brightness directly with no LED modeling. */ + /** Sets the brightness immediately with no light decay. */ void setBrightness(float brightness) { value = (brightness > 0.f) ? std::pow(brightness, 2) : 0.f; } @@ -21,23 +21,24 @@ struct Light { return std::sqrt(value); } - /** Emulates slow fall (but immediate rise) of LED brightness. - `frames` rescales the timestep. - For example, if your module calls this method every 16 frames, use 16.f. - */ - void setBrightnessSmooth(float brightness, float frames = 1.f) { + /** Emulates light decay with slow fall but immediate rise. */ + void setSmoothBrightness(float brightness, float deltaTime) { float v = (brightness > 0.f) ? std::pow(brightness, 2) : 0.f; if (v < value) { - // Fade out light with lambda = framerate - // Use 44.1k here to avoid the call to Engine::getSampleRate(). - // This is close enough to look okay up to 96k - value += (v - value) * frames * 30.f / 44100.f; + // Fade out light + const float lambda = 30.f; + value += (v - value) * lambda * deltaTime; } else { // Immediately illuminate light value = v; } } + + /** Use `setSmoothBrightness(brightness, APP->engine->getSampleTime())` instead. */ + DEPRECATED void setBrightnessSmooth(float brightness, float frames = 1.f) { + setSmoothBrightness(brightness, frames / 44100.f); + } }; diff --git a/include/engine/Port.hpp b/include/engine/Port.hpp index ece1002d..df1fde89 100644 --- a/include/engine/Port.hpp +++ b/include/engine/Port.hpp @@ -75,7 +75,7 @@ struct Port { return active; } - void step(); + void process(float deltaTime); /** Use getNormalVoltage() instead. */ DEPRECATED float normalize(float normalVoltage) { diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 77733962..aefb84cc 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -190,6 +190,7 @@ static void Engine_stepModules(Engine *engine, int threadId) { // int threadCount = internal->threadCount; int modulesLen = internal->modules.size(); + float deltaTime = internal->sampleTime; // Step each module // for (int i = threadId; i < modulesLen; i += threadCount) { @@ -211,7 +212,7 @@ static void Engine_stepModules(Engine *engine, int threadId) { float cpuTime = std::chrono::duration(stopTime - startTime).count(); // Smooth CPU time const float cpuTau = 2.f /* seconds */; - module->cpuTime += (cpuTime - module->cpuTime) * internal->sampleTime / cpuTau; + module->cpuTime += (cpuTime - module->cpuTime) * deltaTime / cpuTau; } else { module->step(); @@ -220,10 +221,10 @@ static void Engine_stepModules(Engine *engine, int threadId) { // Iterate ports to step plug lights for (Input &input : module->inputs) { - input.step(); + input.process(deltaTime); } for (Output &output : module->outputs) { - output.step(); + output.process(deltaTime); } } } diff --git a/src/engine/Port.cpp b/src/engine/Port.cpp index 091eb2a8..4b84f105 100644 --- a/src/engine/Port.cpp +++ b/src/engine/Port.cpp @@ -5,7 +5,7 @@ namespace rack { namespace engine { -void Port::step() { +void Port::process(float deltaTime) { // Set plug lights if (!isConnected() || getChannels() == 0) { plugLights[0].setBrightness(0.f); @@ -14,8 +14,8 @@ void Port::step() { } else if (getChannels() == 1) { float v = getVoltage() / 10.f; - plugLights[0].setBrightnessSmooth(v); - plugLights[1].setBrightnessSmooth(-v); + plugLights[0].setSmoothBrightness(v, deltaTime); + plugLights[1].setSmoothBrightness(-v, deltaTime); plugLights[2].setBrightness(0.f); } else { @@ -26,7 +26,7 @@ void Port::step() { float v = std::sqrt(v2) / 10.f; plugLights[0].setBrightness(0.f); plugLights[1].setBrightness(0.f); - plugLights[2].setBrightnessSmooth(v); + plugLights[2].setSmoothBrightness(v, deltaTime); } }