diff --git a/carla b/carla index f7dda03..1e3b910 160000 --- a/carla +++ b/carla @@ -1 +1 @@ -Subproject commit f7dda0396aa447d035b0d60f073f8de093e25492 +Subproject commit 1e3b910d014f7f7d44e8b3b76eb47efad2121e4f diff --git a/dpf b/dpf index 4772a38..637870a 160000 --- a/dpf +++ b/dpf @@ -1 +1 @@ -Subproject commit 4772a3846a83e194d136f84305b5a054a8be2f35 +Subproject commit 637870a30301a37c0462b929717409b53a479321 diff --git a/plugins/Cardinal/src/HostMIDI.cpp b/plugins/Cardinal/src/HostMIDI.cpp index 6d13ea3..ebb8105 100644 --- a/plugins/Cardinal/src/HostMIDI.cpp +++ b/plugins/Cardinal/src/HostMIDI.cpp @@ -103,6 +103,8 @@ struct HostMIDI : TerminalModule { // Indexed by channel uint8_t notes[16]; bool gates[16]; + bool gatesForceGap[16]; + bool gateForceGaps; uint8_t velocities[16]; uint8_t aftertouches[16]; std::vector heldNotes; @@ -148,6 +150,7 @@ struct HostMIDI : TerminalModule { channels = 1; polyMode = ROTATE_MODE; pwRange = 0; + gateForceGaps = false; panic(true); } @@ -157,6 +160,7 @@ struct HostMIDI : TerminalModule { for (int c = 0; c < 16; c++) { notes[c] = 60; gates[c] = false; + gatesForceGap[c] = false; velocities[c] = 0; aftertouches[c] = 0; pwFilters[c].reset(); @@ -290,10 +294,11 @@ struct HostMIDI : TerminalModule { float pw = pwValues[(polyMode == MPE_MODE) ? c : 0]; float pitch = (notes[c] - 60.f + pw * pwRange) / 12.f; outputs[PITCH_OUTPUT].setVoltage(pitch, c); - outputs[GATE_OUTPUT].setVoltage(gates[c] ? 10.f : 0.f, c); + outputs[GATE_OUTPUT].setVoltage(gates[c] && !gatesForceGap[c] ? 10.f : 0.f, c); outputs[VELOCITY_OUTPUT].setVoltage(rescale(velocities[c], 0, 127, 0.f, 10.f), c); outputs[AFTERTOUCH_OUTPUT].setVoltage(rescale(aftertouches[c], 0, 127, 0.f, 10.f), c); outputs[RETRIGGER_OUTPUT].setVoltage(retriggerPulses[c].process(args.sampleTime) ? 10.f : 0.f, c); + gatesForceGap[c] = false; } outputs[START_OUTPUT].setVoltage(startPulse.process(args.sampleTime) ? 10.f : 0.f); @@ -483,6 +488,9 @@ struct HostMIDI : TerminalModule { for (int c = 0; c < channels; c++) { if (notes[c] == note) { gates[c] = false; + // this will stay low even when gates[c] = true + // is set by a note on before the gate is sent as low + gatesForceGap[c] = gateForceGaps; } } // Set last note if monophonic @@ -709,6 +717,7 @@ struct HostMIDI : TerminalModule { json_object_set_new(rootJ, "pwRange", json_real(midiInput.pwRange)); json_object_set_new(rootJ, "smooth", json_boolean(midiInput.smooth)); + json_object_set_new(rootJ, "forceGateGaps", json_boolean(midiInput.gateForceGaps)); json_object_set_new(rootJ, "channels", json_integer(midiInput.channels)); json_object_set_new(rootJ, "polyMode", json_integer(midiInput.polyMode)); @@ -736,6 +745,9 @@ struct HostMIDI : TerminalModule { if (json_t* const smoothJ = json_object_get(rootJ, "smooth")) midiInput.smooth = json_boolean_value(smoothJ); + if (json_t* const forceGateGapsJ = json_object_get(rootJ, "forceGateGaps")) + midiInput.gateForceGaps = json_boolean_value(forceGateGapsJ); + if (json_t* const channelsJ = json_object_get(rootJ, "channels")) midiInput.setChannels(json_integer_value(channelsJ)); @@ -817,6 +829,8 @@ struct HostMIDIWidget : ModuleWidgetWith9HP { menu->addChild(new MenuSeparator); menu->addChild(createMenuLabel("MIDI Input")); + menu->addChild(createBoolPtrMenuItem("Force gate gaps between notes", "", &module->midiInput.gateForceGaps)); + menu->addChild(createBoolPtrMenuItem("Smooth pitch/mod wheel", "", &module->midiInput.smooth)); static const std::vector pwRanges = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 24, 36, 48};