From ffa5b5d760d64d2fd13d0b8ae96044095d02f0b5 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Fri, 25 May 2018 08:20:00 -0400 Subject: [PATCH] Add velocity mode to MIDI-Trig --- src/Core/MIDITriggerToCVInterface.cpp | 33 +++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/Core/MIDITriggerToCVInterface.cpp b/src/Core/MIDITriggerToCVInterface.cpp index 82e232cd..5d708127 100644 --- a/src/Core/MIDITriggerToCVInterface.cpp +++ b/src/Core/MIDITriggerToCVInterface.cpp @@ -21,8 +21,10 @@ struct MIDITriggerToCVInterface : Module { bool gates[16]; float gateTimes[16]; + uint8_t velocities[16]; int learningId = -1; uint8_t learnedNotes[16] = {}; + bool velocity = false; MIDITriggerToCVInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { onReset(); @@ -37,7 +39,7 @@ struct MIDITriggerToCVInterface : Module { learningId = -1; } - void pressNote(uint8_t note) { + void pressNote(uint8_t note, uint8_t vel) { // Learn if (learningId >= 0) { learnedNotes[learningId] = note; @@ -48,6 +50,7 @@ struct MIDITriggerToCVInterface : Module { if (learnedNotes[i] == note) { gates[i] = true; gateTimes[i] = 1e-3f; + velocities[i] = vel; } } } @@ -70,7 +73,7 @@ struct MIDITriggerToCVInterface : Module { for (int i = 0; i < 16; i++) { if (gateTimes[i] > 0.f) { - outputs[TRIG_OUTPUT + i].value = 10.f; + outputs[TRIG_OUTPUT + i].value = velocities ? rescale(velocities[i], 0, 127, 0.f, 10.f) : 10.f; // If the gate is off, wait 1 ms before turning the pulse off. // This avoids drum controllers sending a pulse with 0 ms duration. if (!gates[i]) { @@ -92,7 +95,7 @@ struct MIDITriggerToCVInterface : Module { // note on case 0x9: { if (msg.value() > 0) { - pressNote(msg.note()); + pressNote(msg.note(), msg.value()); } else { // Many stupid keyboards send a "note on" command with 0 velocity to mean "note release" @@ -114,6 +117,7 @@ struct MIDITriggerToCVInterface : Module { json_object_set_new(rootJ, "notes", notesJ); json_object_set_new(rootJ, "midi", midiInput.toJson()); + json_object_set_new(rootJ, "velocity", json_boolean(velocity)); return rootJ; } @@ -123,13 +127,17 @@ struct MIDITriggerToCVInterface : Module { for (int i = 0; i < 16; i++) { json_t *noteJ = json_array_get(notesJ, i); if (noteJ) - learnedNotes[i] = json_integer_value(noteJ) & 0x7f; + learnedNotes[i] = json_integer_value(noteJ); } } json_t *midiJ = json_object_get(rootJ, "midi"); if (midiJ) midiInput.fromJson(midiJ); + + json_t *velocityJ = json_object_get(rootJ, "velocity"); + if (velocityJ) + velocity = json_boolean_value(velocityJ); } }; @@ -221,9 +229,24 @@ struct MIDITriggerToCVInterfaceWidget : ModuleWidget { midiWidget->midiIO = &module->midiInput; midiWidget->createGridChoices(); addChild(midiWidget); + } + + void appendContextMenu(Menu *menu) override { + MIDITriggerToCVInterface *module = dynamic_cast(this->module); + + struct VelocityItem : MenuItem { + MIDITriggerToCVInterface *module; + void onAction(EventAction &e) override { + module->velocity ^= true; + } + }; + menu->addChild(MenuEntry::create()); + VelocityItem *velocityItem = MenuItem::create("Velocity", CHECKMARK(module->velocity)); + velocityItem->module = module; + menu->addChild(velocityItem); } }; -Model *modelMIDITriggerToCVInterface = Model::create("Core", "MIDITriggerToCVInterface", "MIDI-TRIG", MIDI_TAG, EXTERNAL_TAG); +Model *modelMIDITriggerToCVInterface = Model::create("Core", "MIDITriggerToCVInterface", "MIDI-Trig", MIDI_TAG, EXTERNAL_TAG);