diff --git a/src/core/MIDI_CV.cpp b/src/core/MIDI_CV.cpp index 5f955942..bb6012da 100644 --- a/src/core/MIDI_CV.cpp +++ b/src/core/MIDI_CV.cpp @@ -166,7 +166,6 @@ struct MIDI_CVWidget : ModuleWidget { } })); - // TODO Panic when set menu->addChild(createIndexSubmenuItem("Monophonic priority", { "Last", "First", @@ -175,12 +174,11 @@ struct MIDI_CVWidget : ModuleWidget { }, [=]() { return module->midiParser.monoMode; }, [=](size_t monoMode) { - module->midiParser.setMonoMode((dsp::MidiParser<16>::MonoMode) monoMode); + module->midiParser.setMonoMode(decltype(module->midiParser)::MonoMode(monoMode)); })); menu->addChild(createBoolPtrMenuItem("Release retrigger", "", &module->midiParser.retriggerOnResume)); - // TODO Panic when set menu->addChild(createIndexSubmenuItem("Polyphony mode", { "Rotate", "Reuse", @@ -189,7 +187,7 @@ struct MIDI_CVWidget : ModuleWidget { }, [=]() { return module->midiParser.polyMode; }, [=](size_t polyMode) { - module->midiParser.setPolyMode((dsp::MidiParser<16>::PolyMode) polyMode); + module->midiParser.setPolyMode(decltype(module->midiParser)::PolyMode(polyMode)); })); menu->addChild(new MenuSeparator); diff --git a/src/core/MIDI_Gate.cpp b/src/core/MIDI_Gate.cpp index b90fe5f4..d1e71ace 100644 --- a/src/core/MIDI_Gate.cpp +++ b/src/core/MIDI_Gate.cpp @@ -22,18 +22,22 @@ struct MIDI_Gate : Module { midi::InputQueue midiInput; - /** [cell][channel] */ + /** True when a cell's gate is held. [cell][channel] */ bool gates[16][16]; - /** [cell][channel] */ - float gateTimes[16][16]; - /** [cell][channel] */ + /** Last velocity value of cell. [cell][channel] */ uint8_t velocities[16][16]; + /** Triggered when a cell's note is played. [cell][channel] */ + dsp::PulseGenerator trigPulses[16][16]; /** Cell ID in learn mode, or -1 if none. */ int learningId; /** [cell] */ int8_t learnedNotes[16]; + + // Settings + bool velocityMode; bool mpeMode; + bool trigMode; MIDI_Gate() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); @@ -50,17 +54,19 @@ struct MIDI_Gate : Module { } } learningId = -1; - panic(); midiInput.reset(); velocityMode = false; mpeMode = false; + trigMode = false; + panic(); } void panic() { for (int i = 0; i < 16; i++) { for (int c = 0; c < 16; c++) { gates[i][c] = false; - gateTimes[i][c] = 0.f; + velocities[i][c] = 0; + trigPulses[i][c].reset(); } } } @@ -74,18 +80,13 @@ struct MIDI_Gate : Module { int channels = mpeMode ? 16 : 1; for (int i = 0; i < 16; i++) { - outputs[GATE_OUTPUTS + i].setChannels(channels); for (int c = 0; c < channels; c++) { - // Make sure all pulses last longer than 1ms - if (gates[i][c] || gateTimes[i][c] > 0.f) { - float velocity = velocityMode ? (velocities[i][c] / 127.f) : 1.f; - outputs[GATE_OUTPUTS + i].setVoltage(velocity * 10.f, c); - gateTimes[i][c] -= args.sampleTime; - } - else { - outputs[GATE_OUTPUTS + i].setVoltage(0.f, c); - } + bool pulse = trigPulses[i][c].process(args.sampleTime); + bool gate = pulse || (!trigMode && gates[i][c]); + float velocity = gate ? velocityMode ? (velocities[i][c] / 127.f) : 1.f : 0.f; + outputs[GATE_OUTPUTS + i].setVoltage(velocity * 10.f, c); } + outputs[GATE_OUTPUTS + i].setChannels(channels); } } @@ -101,7 +102,7 @@ struct MIDI_Gate : Module { pressNote(msg.getChannel(), msg.getNote(), msg.getValue()); } else { - // Many stupid keyboards send a "note on" command with 0 velocity to mean "note release" + // Note-on event with velocity 0 is an alternative for note-off event. releaseNote(msg.getChannel(), msg.getNote()); } } break; @@ -120,8 +121,8 @@ struct MIDI_Gate : Module { for (int i = 0; i < 16; i++) { if (learnedNotes[i] == note) { gates[i][c] = true; - gateTimes[i][c] = 1e-3f; velocities[i][c] = vel; + trigPulses[i][c].trigger(1e-3f); } } } @@ -159,9 +160,12 @@ struct MIDI_Gate : Module { json_object_set_new(rootJ, "velocity", json_boolean(velocityMode)); + json_object_set_new(rootJ, "mpeMode", json_boolean(mpeMode)); + + json_object_set_new(rootJ, "trigMode", json_boolean(trigMode)); + json_object_set_new(rootJ, "midi", midiInput.toJson()); - json_object_set_new(rootJ, "mpeMode", json_boolean(mpeMode)); return rootJ; } @@ -179,13 +183,17 @@ struct MIDI_Gate : Module { if (velocityJ) velocityMode = json_boolean_value(velocityJ); - json_t* midiJ = json_object_get(rootJ, "midi"); - if (midiJ) - midiInput.fromJson(midiJ); - json_t* mpeModeJ = json_object_get(rootJ, "mpeMode"); if (mpeModeJ) mpeMode = json_boolean_value(mpeModeJ); + + json_t* trigModeJ = json_object_get(rootJ, "trigMode"); + if (trigModeJ) + trigMode = json_boolean_value(trigModeJ); + + json_t* midiJ = json_object_get(rootJ, "midi"); + if (midiJ) + midiInput.fromJson(midiJ); } }; @@ -234,9 +242,13 @@ struct MIDI_GateWidget : ModuleWidget { menu->addChild(createBoolPtrMenuItem("MPE mode", "", &module->mpeMode)); - menu->addChild(createMenuItem("Panic", "", - [=]() {module->panic();} - )); + menu->addChild(createBoolPtrMenuItem("Trigger mode", "", &module->trigMode)); + + menu->addChild(new MenuSeparator); + + menu->addChild(createMenuItem("Panic", "", [=]() { + module->panic(); + })); } }; diff --git a/src/rtmidi.cpp b/src/rtmidi.cpp index e3e491b3..581a3ac4 100644 --- a/src/rtmidi.cpp +++ b/src/rtmidi.cpp @@ -405,7 +405,7 @@ void rtmidiInit() { midi::addDriver(driverId, driver); } catch (Exception& e) { - WARN("Could not create RtMidiDriver %d", api); + WARN("%s", e.what()); } } }