From 7103404c5a2c8b8db3d6b8cd7bb8dcce7044f89e Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Wed, 15 Apr 2020 04:30:44 -0400 Subject: [PATCH] CV-MIDI: Add back rate limiting to pitch wheel, mod wheel, velocity, and pan. CV-CC and CV-Gate: Add timestamps to generates MIDI messages. --- src/core/CV_CC.cpp | 22 ++++++++++++++-------- src/core/CV_Gate.cpp | 10 ++++++++++ src/core/CV_MIDI.cpp | 32 +++++++++++++++++--------------- src/engine/Engine.cpp | 2 -- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/core/CV_CC.cpp b/src/core/CV_CC.cpp index d27c3e0f..33b885a4 100644 --- a/src/core/CV_CC.cpp +++ b/src/core/CV_CC.cpp @@ -7,6 +7,7 @@ namespace core { struct CCMidiOutput : midi::Output { int lastValues[128]; + int64_t timestamp = -1; CCMidiOutput() { reset(); @@ -28,8 +29,13 @@ struct CCMidiOutput : midi::Output { m.setStatus(0xb); m.setNote(cc); m.setValue(value); + m.timestamp = timestamp; sendMessage(m); } + + void setTimestamp(int64_t timestamp) { + this->timestamp = timestamp; + } }; @@ -49,7 +55,7 @@ struct CV_CC : Module { }; CCMidiOutput midiOutput; - float rateLimiterPhase = 0.f; + dsp::Timer rateLimiterTimer; int learningId = -1; int learnedCcs[16] = {}; @@ -70,14 +76,14 @@ struct CV_CC : Module { } void process(const ProcessArgs& args) override { - const float rateLimiterPeriod = 0.010f; - rateLimiterPhase += args.sampleTime / rateLimiterPeriod; - if (rateLimiterPhase >= 1.f) { - rateLimiterPhase -= 1.f; - } - else { + const float rateLimiterPeriod = 1 / 200.f; + bool rateLimiterTriggered = (rateLimiterTimer.process(args.sampleTime) >= rateLimiterPeriod); + if (rateLimiterTriggered) + rateLimiterTimer.time -= rateLimiterPeriod; + else return; - } + + midiOutput.setTimestamp(APP->engine->getFrameTime()); for (int i = 0; i < 16; i++) { int value = (int) std::round(inputs[CC_INPUTS + i].getVoltage() / 10.f * 127); diff --git a/src/core/CV_Gate.cpp b/src/core/CV_Gate.cpp index 67f8c5f5..57d63eff 100644 --- a/src/core/CV_Gate.cpp +++ b/src/core/CV_Gate.cpp @@ -8,6 +8,7 @@ namespace core { struct GateMidiOutput : midi::Output { int vels[128]; bool lastGates[128]; + int64_t timestamp = -1; GateMidiOutput() { reset(); @@ -29,6 +30,7 @@ struct GateMidiOutput : midi::Output { m.setStatus(0x8); m.setNote(note); m.setValue(0); + m.timestamp = timestamp; sendMessage(m); lastGates[note] = false; } @@ -45,6 +47,7 @@ struct GateMidiOutput : midi::Output { m.setStatus(0x9); m.setNote(note); m.setValue(vels[note]); + m.timestamp = timestamp; sendMessage(m); } else if (!gate && lastGates[note]) { @@ -53,10 +56,15 @@ struct GateMidiOutput : midi::Output { m.setStatus(0x8); m.setNote(note); m.setValue(vels[note]); + m.timestamp = timestamp; sendMessage(m); } lastGates[note] = gate; } + + void setTimestamp(int64_t timestamp) { + this->timestamp = timestamp; + } }; @@ -99,6 +107,8 @@ struct CV_Gate : Module { } void process(const ProcessArgs& args) override { + midiOutput.setTimestamp(APP->engine->getFrameTime()); + for (int i = 0; i < 16; i++) { int note = learnedNotes[i]; if (velocityMode) { diff --git a/src/core/CV_MIDI.cpp b/src/core/CV_MIDI.cpp index a463f159..b3247e6d 100644 --- a/src/core/CV_MIDI.cpp +++ b/src/core/CV_MIDI.cpp @@ -93,21 +93,23 @@ struct CV_MIDI : Module { midiOutput.setKeyPressure(aft, c); } - int pw = (int) std::round((inputs[PW_INPUT].getVoltage() + 5.f) / 10.f * 0x4000); - pw = clamp(pw, 0, 0x3fff); - midiOutput.setPitchWheel(pw); - - int mw = (int) std::round(inputs[MW_INPUT].getVoltage() / 10.f * 127); - mw = clamp(mw, 0, 127); - midiOutput.setModWheel(mw); - - int vol = (int) std::round(inputs[VOL_INPUT].getNormalVoltage(10.f) / 10.f * 127); - vol = clamp(vol, 0, 127); - midiOutput.setVolume(vol); - - int pan = (int) std::round((inputs[PAN_INPUT].getVoltage() + 5.f) / 10.f * 127); - pan = clamp(pan, 0, 127); - midiOutput.setPan(pan); + if (rateLimiterTriggered) { + int pw = (int) std::round((inputs[PW_INPUT].getVoltage() + 5.f) / 10.f * 0x4000); + pw = clamp(pw, 0, 0x3fff); + midiOutput.setPitchWheel(pw); + + int mw = (int) std::round(inputs[MW_INPUT].getVoltage() / 10.f * 127); + mw = clamp(mw, 0, 127); + midiOutput.setModWheel(mw); + + int vol = (int) std::round(inputs[VOL_INPUT].getNormalVoltage(10.f) / 10.f * 127); + vol = clamp(vol, 0, 127); + midiOutput.setVolume(vol); + + int pan = (int) std::round((inputs[PAN_INPUT].getVoltage() + 5.f) / 10.f * 127); + pan = clamp(pan, 0, 127); + midiOutput.setPan(pan); + } bool clk = inputs[CLK_INPUT].getVoltage() >= 1.f; midiOutput.setClock(clk); diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index d5f722b8..e15eeb8c 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -560,10 +560,8 @@ void Engine::step(int frames) { random::init(); internal->stepFrame = internal->frame; - int64_t oldStepTime = internal->stepTime; internal->stepTime = system::getNanoseconds(); internal->stepFrames = frames; - DEBUG("time %ld", internal->stepTime - oldStepTime); // Set sample rate if (internal->sampleRate != settings::sampleRate) {