@@ -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); | |||
@@ -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) { | |||
@@ -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); | |||
@@ -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) { | |||