diff --git a/src/Core/CV_CC.cpp b/src/Core/CV_CC.cpp index fce7d450..da124588 100644 --- a/src/Core/CV_CC.cpp +++ b/src/Core/CV_CC.cpp @@ -1,34 +1,27 @@ #include "Core.hpp" -template struct CCMidiOutput : midi::Output { - int ccs[N]; - int lastValues[N]; + int lastValues[128]; CCMidiOutput() { reset(); } void reset() { - for (int n = 0; n < N; n++) { - ccs[n] = n; + for (int n = 0; n < 128; n++) { lastValues[n] = -1; } } - void setCC(int cc, int n) { - ccs[n] = cc; - } - - void setValue(int value, int n) { - if (value == lastValues[n]) + void setValue(int value, int cc) { + if (value == lastValues[cc]) return; - lastValues[n] = value; + lastValues[cc] = value; // CC midi::Message m; m.setStatus(0xb); - m.setNote(ccs[n]); + m.setNote(cc); m.setValue(value); sendMessage(m); } @@ -50,11 +43,23 @@ struct CV_CC : Module { NUM_LIGHTS }; - CCMidiOutput<16> midiOutput; + CCMidiOutput midiOutput; float rateLimiterPhase = 0.f; + int learningId = -1; + int learnedCcs[16] = {}; CV_CC() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + onReset(); + } + + void onReset() override { + for (int i = 0; i < 16; i++) { + learnedCcs[i] = i; + } + learningId = -1; + midiOutput.reset(); + midiOutput.midi::Output::reset(); } void step() override { @@ -67,11 +72,39 @@ struct CV_CC : Module { return; } - for (int n = 0; n < 16; n++) { - int value = (int) std::round(inputs[CC_INPUTS + n].getVoltage() / 10.f * 127); + for (int i = 0; i < 16; i++) { + int value = (int) std::round(inputs[CC_INPUTS + i].getVoltage() / 10.f * 127); value = clamp(value, 0, 127); - midiOutput.setValue(value, n); + midiOutput.setValue(value, learnedCcs[i]); + } + } + + json_t *dataToJson() override { + json_t *rootJ = json_object(); + + json_t *ccsJ = json_array(); + for (int i = 0; i < 16; i++) { + json_array_append_new(ccsJ, json_integer(learnedCcs[i])); } + json_object_set_new(rootJ, "ccs", ccsJ); + + json_object_set_new(rootJ, "midi", midiOutput.toJson()); + return rootJ; + } + + void dataFromJson(json_t *rootJ) override { + json_t *ccsJ = json_object_get(rootJ, "ccs"); + if (ccsJ) { + for (int i = 0; i < 16; i++) { + json_t *ccJ = json_array_get(ccsJ, i); + if (ccJ) + learnedCcs[i] = json_integer_value(ccJ); + } + } + + json_t *midiJ = json_object_get(rootJ, "midi"); + if (midiJ) + midiOutput.fromJson(midiJ); } }; @@ -103,11 +136,12 @@ struct CV_CCWidget : ModuleWidget { addInput(createInputCentered(mm2px(Vec(31, 112)), module, CV_CC::CC_INPUTS + 14)); addInput(createInputCentered(mm2px(Vec(43, 112)), module, CV_CC::CC_INPUTS + 15)); - MidiWidget *midiWidget = createWidget(mm2px(Vec(3.4, 14.839))); + typedef Grid16MidiWidget> TMidiWidget; + TMidiWidget *midiWidget = createWidget(mm2px(Vec(3.399621, 14.837339))); midiWidget->box.size = mm2px(Vec(44, 54.667)); if (module) midiWidget->midiIO = &module->midiOutput; - // midiWidget->createGridChoices(); + midiWidget->setModule(module); addChild(midiWidget); } }; diff --git a/src/Core/CV_Gate.cpp b/src/Core/CV_Gate.cpp index 21e5d182..5663e49b 100644 --- a/src/Core/CV_Gate.cpp +++ b/src/Core/CV_Gate.cpp @@ -1,28 +1,25 @@ #include "Core.hpp" -template struct GateMidiOutput : midi::Output { - int vels[N]; - bool lastGates[N]; - int notes[N]; + int vels[128]; + bool lastGates[128]; GateMidiOutput() { reset(); } void reset() { - for (int n = 0; n < N; n++) { - vels[n] = 100; - lastGates[n] = false; - notes[n] = 60 + n; + for (int note = 0; note < 128; note++) { + vels[note] = 100; + lastGates[note] = false; } } void panic() { reset(); // Send all note off commands - for (int note = 0; note <= 127; note++) { + for (int note = 0; note < 128; note++) { // Note off midi::Message m; m.setStatus(0x8); @@ -32,48 +29,28 @@ struct GateMidiOutput : midi::Output { } } - void setVelocity(int vel, int n) { - vels[n] = vel; + void setVelocity(int vel, int note) { + vels[note] = vel; } - void setGate(bool gate, int n) { - if (gate && !lastGates[n]) { + void setGate(bool gate, int note) { + if (gate && !lastGates[note]) { // Note on midi::Message m; m.setStatus(0x9); - m.setNote(notes[n]); - m.setValue(vels[n]); + m.setNote(note); + m.setValue(vels[note]); sendMessage(m); } - else if (!gate && lastGates[n]) { + else if (!gate && lastGates[note]) { // Note off midi::Message m; m.setStatus(0x8); - m.setNote(notes[n]); - m.setValue(vels[n]); + m.setNote(note); + m.setValue(vels[note]); sendMessage(m); } - lastGates[n] = gate; - } - - void setNote(int note, int n) { - if (note == notes[n]) - return; - if (lastGates[n]) { - // Note off - midi::Message m1; - m1.setStatus(0x8); - m1.setNote(notes[n]); - m1.setValue(vels[n]); - sendMessage(m1); - // Note on - midi::Message m2; - m2.setStatus(0x9); - m2.setNote(note); - m2.setValue(vels[n]); - sendMessage(m2); - } - notes[n] = note; + lastGates[note] = gate; } }; @@ -93,27 +70,75 @@ struct CV_Gate : Module { NUM_LIGHTS }; - GateMidiOutput<16> midiOutput; + GateMidiOutput midiOutput; bool velocityMode = false; + int learningId = -1; + uint8_t learnedNotes[16] = {}; CV_Gate() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + onReset(); + } + + void onReset() override { + for (int i = 0; i < 16; i++) { + learnedNotes[i] = i + 36; + } + learningId = -1; + midiOutput.reset(); + midiOutput.midi::Output::reset(); } void step() override { - for (int n = 0; n < 16; n++) { + for (int i = 0; i < 16; i++) { + int note = learnedNotes[i]; if (velocityMode) { - int vel = (int) std::round(inputs[GATE_INPUTS + n].getVoltage() / 10.f * 127); + int vel = (int) std::round(inputs[GATE_INPUTS + i].getVoltage() / 10.f * 127); vel = clamp(vel, 0, 127); - midiOutput.setVelocity(vel, n); - midiOutput.setGate(vel > 0, n); + midiOutput.setVelocity(vel, note); + midiOutput.setGate(vel > 0, note); } else { - bool gate = inputs[GATE_INPUTS + n].getVoltage() >= 1.f; - midiOutput.setVelocity(100, n); - midiOutput.setGate(gate, n); + bool gate = inputs[GATE_INPUTS + i].getVoltage() >= 1.f; + midiOutput.setVelocity(100, note); + midiOutput.setGate(gate, note); + } + } + } + + json_t *dataToJson() override { + json_t *rootJ = json_object(); + + json_t *notesJ = json_array(); + for (int i = 0; i < 16; i++) { + json_t *noteJ = json_integer(learnedNotes[i]); + json_array_append_new(notesJ, noteJ); + } + json_object_set_new(rootJ, "notes", notesJ); + + json_object_set_new(rootJ, "velocity", json_boolean(velocityMode)); + + json_object_set_new(rootJ, "midi", midiOutput.toJson()); + return rootJ; + } + + void dataFromJson(json_t *rootJ) override { + json_t *notesJ = json_object_get(rootJ, "notes"); + if (notesJ) { + for (int i = 0; i < 16; i++) { + json_t *noteJ = json_array_get(notesJ, i); + if (noteJ) + learnedNotes[i] = json_integer_value(noteJ); } } + + json_t *velocityJ = json_object_get(rootJ, "velocity"); + if (velocityJ) + velocityMode = json_boolean_value(velocityJ); + + json_t *midiJ = json_object_get(rootJ, "midi"); + if (midiJ) + midiOutput.fromJson(midiJ); } }; @@ -145,11 +170,12 @@ struct CV_GateWidget : ModuleWidget { addInput(createInputCentered(mm2px(Vec(31, 112)), module, CV_Gate::GATE_INPUTS + 14)); addInput(createInputCentered(mm2px(Vec(43, 112)), module, CV_Gate::GATE_INPUTS + 15)); - MidiWidget *midiWidget = createWidget(mm2px(Vec(3.4, 14.839))); + typedef Grid16MidiWidget> TMidiWidget; + TMidiWidget *midiWidget = createWidget(mm2px(Vec(3.399621, 14.837339))); midiWidget->box.size = mm2px(Vec(44, 54.667)); if (module) midiWidget->midiIO = &module->midiOutput; - // midiWidget->createGridChoices(); + midiWidget->setModule(module); addChild(midiWidget); } }; diff --git a/src/Core/CV_MIDI.cpp b/src/Core/CV_MIDI.cpp index a4f33a7c..15b59271 100644 --- a/src/Core/CV_MIDI.cpp +++ b/src/Core/CV_MIDI.cpp @@ -233,6 +233,12 @@ struct CV_MIDI : Module { CV_MIDI() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); + onReset(); + } + + void onReset() override { + midiOutput.reset(); + midiOutput.midi::Output::reset(); } void step() override { @@ -292,6 +298,18 @@ struct CV_MIDI : Module { bool cont = inputs[CONTINUE_INPUT].value >= 1.f; midiOutput.setContinue(cont); } + + json_t *dataToJson() override { + json_t *rootJ = json_object(); + json_object_set_new(rootJ, "midi", midiOutput.toJson()); + return rootJ; + } + + void dataFromJson(json_t *rootJ) override { + json_t *midiJ = json_object_get(rootJ, "midi"); + if (midiJ) + midiOutput.fromJson(midiJ); + } }; diff --git a/src/Core/Core.hpp b/src/Core/Core.hpp index 06bfeb72..805eefc4 100644 --- a/src/Core/Core.hpp +++ b/src/Core/Core.hpp @@ -16,40 +16,36 @@ extern Model *modelBlank; extern Model *modelNotes; - -struct GridChoice : LedDisplayChoice { - virtual void setId(int id) {} -}; - - +template struct Grid16MidiWidget : MidiWidget { LedDisplaySeparator *hSeparators[4]; LedDisplaySeparator *vSeparators[4]; - GridChoice *gridChoices[4][4]; + TChoice *choices[4][4]; - void createGridChoices() { + Grid16MidiWidget() { Vec pos = channelChoice->box.getBottomLeft(); + // Add vSeparators for (int x = 1; x < 4; x++) { vSeparators[x] = createWidget(pos); addChild(vSeparators[x]); } + // Add hSeparators and choice widgets for (int y = 0; y < 4; y++) { hSeparators[y] = createWidget(pos); addChild(hSeparators[y]); for (int x = 0; x < 4; x++) { - GridChoice *gridChoice = createGridChoice(); - assert(gridChoice); - gridChoice->box.pos = pos; - gridChoice->setId(4*y + x); - gridChoices[x][y] = gridChoice; - addChild(gridChoice); + choices[x][y] = new TChoice; + choices[x][y]->box.pos = pos; + choices[x][y]->setId(4*y + x); + addChild(choices[x][y]); } - pos = gridChoices[0][y]->box.getBottomLeft(); + pos = choices[0][y]->box.getBottomLeft(); } for (int x = 1; x < 4; x++) { vSeparators[x]->box.size.y = pos.y - vSeparators[x]->box.pos.y; } } + void step() override { MidiWidget::step(); for (int x = 1; x < 4; x++) { @@ -58,10 +54,145 @@ struct Grid16MidiWidget : MidiWidget { for (int y = 0; y < 4; y++) { hSeparators[y]->box.size.x = box.size.x; for (int x = 0; x < 4; x++) { - gridChoices[x][y]->box.size.x = box.size.x / 4; - gridChoices[x][y]->box.pos.x = box.size.x / 4 * x; + choices[x][y]->box.size.x = box.size.x / 4; + choices[x][y]->box.pos.x = box.size.x / 4 * x; + } + } + } + + template + void setModule(TModule *module) { + for (int y = 0; y < 4; y++) { + for (int x = 0; x < 4; x++) { + choices[x][y]->module = module; } } } - virtual GridChoice *createGridChoice() {return NULL;} -}; \ No newline at end of file +}; + + +template +struct CcChoice : LedDisplayChoice { + TModule *module; + int id; + int focusCc; + + CcChoice() { + box.size.y = mm2px(6.666); + textOffset.y -= 4; + } + + void setId(int id) { + this->id = id; + } + + void step() override { + if (!module) { + text = ""; + return; + } + if (module->learningId == id) { + if (0 <= focusCc) + text = string::f("%d", focusCc); + else + text = "LRN"; + color.a = 0.5; + } + else { + text = string::f("%d", module->learnedCcs[id]); + color.a = 1.0; + if (app()->event->selectedWidget == this) + app()->event->selectedWidget = NULL; + } + } + + void onSelect(const event::Select &e) override { + e.consume(this); + if (!module) + return; + module->learningId = id; + focusCc = -1; + } + + void onDeselect(const event::Deselect &e) override { + if (!module) + return; + if (0 <= focusCc && focusCc < 128) { + module->learnedCcs[id] = focusCc; + } + module->learningId = -1; + } + + void onSelectText(const event::SelectText &e) override { + int c = e.codepoint - '0'; + if (0 <= c && c <= 9) { + if (focusCc < 0) + focusCc = 0; + focusCc = focusCc * 10 + c; + } + if (focusCc >= 128) + focusCc = 0; + e.consume(this); + } + + void onSelectKey(const event::SelectKey &e) override { + if ((e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER) && e.action == GLFW_PRESS && (e.mods & WINDOW_MOD_MASK) == 0) { + event::Deselect eDeselect; + onDeselect(eDeselect); + app()->event->selectedWidget = NULL; + e.consume(this); + } + } +}; + + +template +struct NoteChoice : LedDisplayChoice { + TModule *module; + int id; + + NoteChoice() { + box.size.y = mm2px(6.666); + textOffset.y -= 4; + textOffset.x -= 4; + } + + void setId(int id) { + this->id = id; + } + + void step() override { + if (!module) + return; + if (module->learningId == id) { + text = "LRN"; + color.a = 0.5; + } + else { + uint8_t note = module->learnedNotes[id]; + static const char *noteNames[] = { + "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" + }; + int oct = note / 12 - 1; + int semi = note % 12; + text = string::f("%s%d", noteNames[semi], oct); + color.a = 1.0; + + if (app()->event->selectedWidget == this) + app()->event->selectedWidget = NULL; + } + } + + void onSelect(const event::Select &e) override { + e.consume(this); + if (!module) + return; + module->learningId = id; + } + + void onDeselect(const event::Deselect &e) override { + if (!module) + return; + module->learningId = -1; + } +}; diff --git a/src/Core/MIDI_CC.cpp b/src/Core/MIDI_CC.cpp index f4219a6b..48648ebd 100644 --- a/src/Core/MIDI_CC.cpp +++ b/src/Core/MIDI_CC.cpp @@ -1,5 +1,4 @@ #include "Core.hpp" -#include "midi.hpp" struct MIDI_CC : Module { @@ -20,7 +19,7 @@ struct MIDI_CC : Module { midi::InputQueue midiInput; int8_t values[128]; int learningId = -1; - int ccs[16] = {}; + int learnedCcs[16] = {}; dsp::ExponentialFilter valueFilters[16]; int8_t lastValues[16] = {}; @@ -34,7 +33,7 @@ struct MIDI_CC : Module { values[i] = 0; } for (int i = 0; i < 16; i++) { - ccs[i] = i; + learnedCcs[i] = i; } learningId = -1; midiInput.reset(); @@ -51,7 +50,7 @@ struct MIDI_CC : Module { if (!outputs[CC_OUTPUT + i].active) continue; - int cc = ccs[i]; + int cc = learnedCcs[i]; float value = rescale(values[cc], 0, 127, 0.f, 10.f); valueFilters[i].lambda = lambda; @@ -77,7 +76,7 @@ struct MIDI_CC : Module { uint8_t cc = msg.getNote(); // Learn if (learningId >= 0 && values[cc] != msg.data2) { - ccs[learningId] = cc; + learnedCcs[learningId] = cc; learningId = -1; } // Allow CC to be negative if the 8th bit is set. @@ -93,7 +92,7 @@ struct MIDI_CC : Module { json_t *ccsJ = json_array(); for (int i = 0; i < 16; i++) { - json_array_append_new(ccsJ, json_integer(ccs[i])); + json_array_append_new(ccsJ, json_integer(learnedCcs[i])); } json_object_set_new(rootJ, "ccs", ccsJ); @@ -114,7 +113,7 @@ struct MIDI_CC : Module { for (int i = 0; i < 16; i++) { json_t *ccJ = json_array_get(ccsJ, i); if (ccJ) - ccs[i] = json_integer_value(ccJ); + learnedCcs[i] = json_integer_value(ccJ); } } @@ -135,90 +134,6 @@ struct MIDI_CC : Module { }; -struct MidiCcChoice : GridChoice { - MIDI_CC *module; - int id; - int focusCc; - - MidiCcChoice() { - box.size.y = mm2px(6.666); - textOffset.y -= 4; - } - - void setId(int id) override { - this->id = id; - } - - void step() override { - if (!module) { - text = ""; - return; - } - if (module->learningId == id) { - if (0 <= focusCc) - text = string::f("%d", focusCc); - else - text = "LRN"; - color.a = 0.5; - } - else { - text = string::f("%d", module->ccs[id]); - color.a = 1.0; - if (app()->event->selectedWidget == this) - app()->event->selectedWidget = NULL; - } - } - - void onSelect(const event::Select &e) override { - e.consume(this); - if (!module) - return; - module->learningId = id; - focusCc = -1; - } - - void onDeselect(const event::Deselect &e) override { - if (!module) - return; - if (0 <= focusCc && focusCc < 128) { - module->ccs[id] = focusCc; - } - module->learningId = -1; - } - - void onSelectText(const event::SelectText &e) override { - char c = e.codepoint; - if ('0' <= c && c <= '9') { - if (focusCc < 0) - focusCc = 0; - focusCc = focusCc * 10 + (c - '0'); - } - e.consume(this); - } - - void onSelectKey(const event::SelectKey &e) override { - if (app()->event->selectedWidget == this) { - if (e.action == GLFW_PRESS && (e.key == GLFW_KEY_ENTER || e.key == GLFW_KEY_KP_ENTER)) { - event::Deselect eDeselect; - onDeselect(eDeselect); - app()->event->selectedWidget = NULL; - e.consume(this); - } - } - } -}; - - -struct MidiCcWidget : Grid16MidiWidget { - MIDI_CC *module; - GridChoice *createGridChoice() override { - MidiCcChoice *gridChoice = new MidiCcChoice; - gridChoice->module = module; - return gridChoice; - } -}; - - struct MIDI_CCWidget : ModuleWidget { MIDI_CCWidget(MIDI_CC *module) { setModule(module); @@ -246,12 +161,12 @@ struct MIDI_CCWidget : ModuleWidget { addOutput(createOutput(mm2px(Vec(27.09498, 108.14429)), module, MIDI_CC::CC_OUTPUT + 14)); addOutput(createOutput(mm2px(Vec(38.693932, 108.14429)), module, MIDI_CC::CC_OUTPUT + 15)); - MidiCcWidget *midiWidget = createWidget(mm2px(Vec(3.399621, 14.837339))); - midiWidget->module = module; + typedef Grid16MidiWidget> TMidiWidget; + TMidiWidget *midiWidget = createWidget(mm2px(Vec(3.399621, 14.837339))); midiWidget->box.size = mm2px(Vec(44, 54.667)); if (module) midiWidget->midiIO = &module->midiInput; - midiWidget->createGridChoices(); + midiWidget->setModule(module); addChild(midiWidget); } }; diff --git a/src/Core/MIDI_CV.cpp b/src/Core/MIDI_CV.cpp index cb42aecf..7225a29f 100644 --- a/src/Core/MIDI_CV.cpp +++ b/src/Core/MIDI_CV.cpp @@ -1,5 +1,4 @@ #include "Core.hpp" -#include "midi.hpp" #include diff --git a/src/Core/MIDI_Gate.cpp b/src/Core/MIDI_Gate.cpp index c5d99316..a1350553 100644 --- a/src/Core/MIDI_Gate.cpp +++ b/src/Core/MIDI_Gate.cpp @@ -1,6 +1,4 @@ #include "Core.hpp" -#include "midi.hpp" -#include "event.hpp" struct MIDI_Gate : Module { @@ -25,7 +23,7 @@ struct MIDI_Gate : Module { uint8_t velocities[16]; int learningId = -1; uint8_t learnedNotes[16] = {}; - bool velocity = false; + bool velocityMode = false; MIDI_Gate() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); @@ -76,7 +74,7 @@ struct MIDI_Gate : Module { for (int i = 0; i < 16; i++) { if (gateTimes[i] > 0.f) { - outputs[TRIG_OUTPUT + i].setVoltage(velocity ? rescale(velocities[i], 0, 127, 0.f, 10.f) : 10.f); + outputs[TRIG_OUTPUT + i].setVoltage(velocityMode ? 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]) { @@ -119,8 +117,9 @@ struct MIDI_Gate : Module { } json_object_set_new(rootJ, "notes", notesJ); + json_object_set_new(rootJ, "velocity", json_boolean(velocityMode)); + json_object_set_new(rootJ, "midi", midiInput.toJson()); - json_object_set_new(rootJ, "velocity", json_boolean(velocity)); return rootJ; } @@ -134,74 +133,13 @@ struct MIDI_Gate : Module { } } - 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); - } -}; - - -struct MidiTrigChoice : GridChoice { - MIDI_Gate *module; - int id; - - MidiTrigChoice() { - box.size.y = mm2px(6.666); - textOffset.y -= 4; - textOffset.x -= 4; - } - - void setId(int id) override { - this->id = id; - } - - void step() override { - if (!module) - return; - if (module->learningId == id) { - text = "LRN"; - color.a = 0.5; - } - else { - uint8_t note = module->learnedNotes[id]; - static const char *noteNames[] = { - "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" - }; - int oct = note / 12 - 1; - int semi = note % 12; - text = string::f("%s%d", noteNames[semi], oct); - color.a = 1.0; - - if (app()->event->selectedWidget == this) - app()->event->selectedWidget = NULL; - } - } - - void onSelect(const event::Select &e) override { - e.consume(this); - if (!module) - return; - module->learningId = id; - } + velocityMode = json_boolean_value(velocityJ); - void onDeselect(const event::Deselect &e) override { - if (!module) - return; - module->learningId = -1; - } -}; - - -struct MidiTrigWidget : Grid16MidiWidget { - MIDI_Gate *module; - GridChoice *createGridChoice() override { - MidiTrigChoice *gridChoice = new MidiTrigChoice; - gridChoice->module = module; - return gridChoice; + json_t *midiJ = json_object_get(rootJ, "midi"); + if (midiJ) + midiInput.fromJson(midiJ); } }; @@ -233,12 +171,12 @@ struct MIDI_GateWidget : ModuleWidget { addOutput(createOutput(mm2px(Vec(27.09498, 108.14429)), module, MIDI_Gate::TRIG_OUTPUT + 14)); addOutput(createOutput(mm2px(Vec(38.693932, 108.14429)), module, MIDI_Gate::TRIG_OUTPUT + 15)); - MidiTrigWidget *midiWidget = createWidget(mm2px(Vec(3.399621, 14.837339))); - midiWidget->module = module; + typedef Grid16MidiWidget> TMidiWidget; + TMidiWidget *midiWidget = createWidget(mm2px(Vec(3.399621, 14.837339))); midiWidget->box.size = mm2px(Vec(44, 54.667)); if (module) midiWidget->midiIO = &module->midiInput; - midiWidget->createGridChoices(); + midiWidget->setModule(module); addChild(midiWidget); } @@ -248,12 +186,12 @@ struct MIDI_GateWidget : ModuleWidget { struct VelocityItem : MenuItem { MIDI_Gate *module; void onAction(const event::Action &e) override { - module->velocity ^= true; + module->velocityMode ^= true; } }; menu->addChild(new MenuEntry); - VelocityItem *velocityItem = createMenuItem("Velocity", CHECKMARK(module->velocity)); + VelocityItem *velocityItem = createMenuItem("Velocity", CHECKMARK(module->velocityMode)); velocityItem->module = module; menu->addChild(velocityItem); }