From 9eb15836717db24b2b2e8b7fac018a9bd7a138e9 Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 29 Oct 2021 23:27:30 +0100 Subject: [PATCH] Add time reset signal when transport relocates Signed-off-by: falkTX --- plugins/Cardinal/src/HostTime.cpp | 34 ++++++++++++++++++-------- plugins/Cardinal/src/plugincontext.hpp | 2 +- src/CardinalPlugin.cpp | 11 ++++++++- src/PluginContext.hpp | 3 ++- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/plugins/Cardinal/src/HostTime.cpp b/plugins/Cardinal/src/HostTime.cpp index c9a33c0..5b8fdfa 100644 --- a/plugins/Cardinal/src/HostTime.cpp +++ b/plugins/Cardinal/src/HostTime.cpp @@ -26,13 +26,14 @@ struct HostTime : Module { }; enum HostTimeIds { kHostTimeRolling, + kHostTimeReset, kHostTimeBar, kHostTimeBeat, kHostTimeClock, kHostTimeCount }; - rack::dsp::PulseGenerator pulseBar, pulseBeat, pulseClock; + rack::dsp::PulseGenerator pulseReset, pulseBar, pulseBeat, pulseClock; float sampleTime = 0.0f; HostTime() @@ -55,12 +56,19 @@ struct HostTime : Module { { if (pcontext->tick == 0.0) { + pulseReset.trigger(); pulseClock.trigger(); pulseBeat.trigger(); if (pcontext->beat == 1) pulseBar.trigger(); } + if (pcontext->reset) + { + pcontext->reset = false; + pulseReset.trigger(); + } + if ((pcontext->tick += pcontext->ticksPerFrame) >= pcontext->ticksPerBeat) { pcontext->tick -= pcontext->ticksPerBeat; @@ -81,16 +89,19 @@ struct HostTime : Module { } } + const bool hasReset = pulseReset.process(args.sampleTime); const bool hasBar = pulseBar.process(args.sampleTime); const bool hasBeat = pulseBeat.process(args.sampleTime); const bool hasClock = pulseClock.process(args.sampleTime); lights[kHostTimeRolling].setBrightness(playing ? 1.0f : 0.0f); + lights[kHostTimeReset].setBrightnessSmooth(hasReset ? 1.0f : 0.0f, args.sampleTime * 0.5f); lights[kHostTimeBar].setBrightnessSmooth(hasBar ? 1.0f : 0.0f, args.sampleTime * 0.5f); lights[kHostTimeBeat].setBrightnessSmooth(hasBeat ? 1.0f : 0.0f, args.sampleTime); lights[kHostTimeClock].setBrightnessSmooth(hasClock ? 1.0f : 0.0f, args.sampleTime * 2.0f); outputs[kHostTimeRolling].setVoltage(playing ? 10.0f : 0.0f); + outputs[kHostTimeReset].setVoltage(hasReset ? 10.0f : 0.0f); outputs[kHostTimeBar].setVoltage(hasBar ? 10.0f : 0.0f); outputs[kHostTimeBeat].setVoltage(hasBeat ? 10.0f : 0.0f); outputs[kHostTimeClock].setVoltage(hasClock ? 10.0f : 0.0f); @@ -114,15 +125,17 @@ struct HostTimeWidget : ModuleWidget { addChild(createWidget(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH))); addOutput(createOutput(Vec(startX, startY + 0 * padding), module, HostTime::kHostTimeRolling)); - addOutput(createOutput(Vec(startX, startY + 1 * padding), module, HostTime::kHostTimeBar)); - addOutput(createOutput(Vec(startX, startY + 2 * padding), module, HostTime::kHostTimeBeat)); - addOutput(createOutput(Vec(startX, startY + 3 * padding), module, HostTime::kHostTimeClock)); + addOutput(createOutput(Vec(startX, startY + 1 * padding), module, HostTime::kHostTimeReset)); + addOutput(createOutput(Vec(startX, startY + 2 * padding), module, HostTime::kHostTimeBar)); + addOutput(createOutput(Vec(startX, startY + 3 * padding), module, HostTime::kHostTimeBeat)); + addOutput(createOutput(Vec(startX, startY + 4 * padding), module, HostTime::kHostTimeClock)); const float x = startX + 28; addChild(createLightCentered> (Vec(x, startY + 0 * padding + 12), module, HostTime::kHostTimeRolling)); - addChild(createLightCentered> (Vec(x, startY + 1 * padding + 12), module, HostTime::kHostTimeBar)); - addChild(createLightCentered>(Vec(x, startY + 2 * padding + 12), module, HostTime::kHostTimeBeat)); - addChild(createLightCentered>(Vec(x, startY + 3 * padding + 12), module, HostTime::kHostTimeClock)); + addChild(createLightCentered> (Vec(x, startY + 1 * padding + 12), module, HostTime::kHostTimeReset)); + addChild(createLightCentered> (Vec(x, startY + 2 * padding + 12), module, HostTime::kHostTimeBar)); + addChild(createLightCentered>(Vec(x, startY + 3 * padding + 12), module, HostTime::kHostTimeBeat)); + addChild(createLightCentered>(Vec(x, startY + 4 * padding + 12), module, HostTime::kHostTimeClock)); } void drawOutputLine(NVGcontext* const vg, const uint offset, const char* const text) @@ -151,9 +164,10 @@ struct HostTimeWidget : ModuleWidget { nvgFontSize(args.vg, 14); drawOutputLine(args.vg, 0, "Playing"); - drawOutputLine(args.vg, 1, "Bar"); - drawOutputLine(args.vg, 2, "Beat"); - drawOutputLine(args.vg, 3, "Clock"); + drawOutputLine(args.vg, 1, "Reset"); + drawOutputLine(args.vg, 2, "Bar"); + drawOutputLine(args.vg, 3, "Beat"); + drawOutputLine(args.vg, 4, "Clock"); ModuleWidget::draw(args); } diff --git a/plugins/Cardinal/src/plugincontext.hpp b/plugins/Cardinal/src/plugincontext.hpp index 337168d..dd26ff7 100644 --- a/plugins/Cardinal/src/plugincontext.hpp +++ b/plugins/Cardinal/src/plugincontext.hpp @@ -33,7 +33,7 @@ struct CardinalPluginContext : rack::Context { uint32_t bufferSize; double sampleRate; float parameters[kModuleParameters]; - bool playing; + bool playing, reset; int32_t bar, beat, beatsPerBar; double tick, tickClock, ticksPerBeat, ticksPerClock, ticksPerFrame; Plugin* const plugin; diff --git a/src/CardinalPlugin.cpp b/src/CardinalPlugin.cpp index 3eb6662..7b4556f 100644 --- a/src/CardinalPlugin.cpp +++ b/src/CardinalPlugin.cpp @@ -316,6 +316,7 @@ class CardinalPlugin : public CardinalBasePlugin CardinalAudioDevice* fCurrentAudioDevice; CardinalMidiOutputDevice* fCurrentMidiOutput; std::list fMidiInputs; + uint64_t fPreviousFrame; Mutex fDeviceMutex; // real values, not VCV interpreted ones @@ -331,7 +332,8 @@ public: fAudioBufferOut(nullptr), fIsActive(false), fCurrentAudioDevice(nullptr), - fCurrentMidiOutput(nullptr) + fCurrentMidiOutput(nullptr), + fPreviousFrame(0) { fWindowParameters[kWindowParameterShowTooltips] = 1.0f; fWindowParameters[kWindowParameterCableOpacity] = 50.0f; @@ -760,6 +762,8 @@ protected: std::memset(fAudioBufferIn, 0, sizeof(float)*bufferSize); #endif + fPreviousFrame = 0; + { const MutexLocker cml(fDeviceMutex); @@ -829,6 +833,11 @@ protected: context->ticksPerFrame = 1.0 / samplesPerTick; context->tickClock = std::fmod(timePos.bbt.tick, context->ticksPerClock); } + + if (timePos.playing && fPreviousFrame + frames != timePos.frame) + context->reset = true; + + fPreviousFrame = timePos.frame; } std::memset(fAudioBufferOut, 0, sizeof(float)*frames*DISTRHO_PLUGIN_NUM_OUTPUTS); diff --git a/src/PluginContext.hpp b/src/PluginContext.hpp index 4975bcf..9ec6e31 100644 --- a/src/PluginContext.hpp +++ b/src/PluginContext.hpp @@ -40,7 +40,7 @@ struct CardinalPluginContext : rack::Context { uint32_t bufferSize; double sampleRate; float parameters[kModuleParameters]; - bool playing; + bool playing, reset; int32_t bar, beat, beatsPerBar; double tick, tickClock, ticksPerBeat, ticksPerClock, ticksPerFrame; Plugin* const plugin; @@ -49,6 +49,7 @@ struct CardinalPluginContext : rack::Context { : bufferSize(p->getBufferSize()), sampleRate(p->getSampleRate()), playing(false), + reset(false), bar(0), beat(0), beatsPerBar(0),