Browse Source

Finish CV-MIDI, CV-CC, and CV-Gate. Clean up MIDI-CV, MIDI-CC, and MIDI-Gate. Make Grid16MidiWidget generic and reusable.

tags/v1.0.0
Andrew Belt 5 years ago
parent
commit
c13c967b26
7 changed files with 318 additions and 257 deletions
  1. +53
    -19
      src/Core/CV_CC.cpp
  2. +75
    -49
      src/Core/CV_Gate.cpp
  3. +18
    -0
      src/Core/CV_MIDI.cpp
  4. +150
    -19
      src/Core/Core.hpp
  5. +9
    -94
      src/Core/MIDI_CC.cpp
  6. +0
    -1
      src/Core/MIDI_CV.cpp
  7. +13
    -75
      src/Core/MIDI_Gate.cpp

+ 53
- 19
src/Core/CV_CC.cpp View File

@@ -1,34 +1,27 @@
#include "Core.hpp"


template <int N>
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<PJ301MPort>(mm2px(Vec(31, 112)), module, CV_CC::CC_INPUTS + 14));
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(43, 112)), module, CV_CC::CC_INPUTS + 15));

MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.4, 14.839)));
typedef Grid16MidiWidget<CcChoice<CV_CC>> TMidiWidget;
TMidiWidget *midiWidget = createWidget<TMidiWidget>(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);
}
};


+ 75
- 49
src/Core/CV_Gate.cpp View File

@@ -1,28 +1,25 @@
#include "Core.hpp"


template <int N>
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<PJ301MPort>(mm2px(Vec(31, 112)), module, CV_Gate::GATE_INPUTS + 14));
addInput(createInputCentered<PJ301MPort>(mm2px(Vec(43, 112)), module, CV_Gate::GATE_INPUTS + 15));

MidiWidget *midiWidget = createWidget<MidiWidget>(mm2px(Vec(3.4, 14.839)));
typedef Grid16MidiWidget<NoteChoice<CV_Gate>> TMidiWidget;
TMidiWidget *midiWidget = createWidget<TMidiWidget>(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);
}
};


+ 18
- 0
src/Core/CV_MIDI.cpp View File

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




+ 150
- 19
src/Core/Core.hpp View File

@@ -16,40 +16,36 @@ extern Model *modelBlank;
extern Model *modelNotes;



struct GridChoice : LedDisplayChoice {
virtual void setId(int id) {}
};


template <class TChoice>
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<LedDisplaySeparator>(pos);
addChild(vSeparators[x]);
}
// Add hSeparators and choice widgets
for (int y = 0; y < 4; y++) {
hSeparators[y] = createWidget<LedDisplaySeparator>(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 <class TModule>
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;}
};
};


template <class TModule>
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 <class TModule>
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;
}
};

+ 9
- 94
src/Core/MIDI_CC.cpp View File

@@ -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<PJ301MPort>(mm2px(Vec(27.09498, 108.14429)), module, MIDI_CC::CC_OUTPUT + 14));
addOutput(createOutput<PJ301MPort>(mm2px(Vec(38.693932, 108.14429)), module, MIDI_CC::CC_OUTPUT + 15));

MidiCcWidget *midiWidget = createWidget<MidiCcWidget>(mm2px(Vec(3.399621, 14.837339)));
midiWidget->module = module;
typedef Grid16MidiWidget<CcChoice<MIDI_CC>> TMidiWidget;
TMidiWidget *midiWidget = createWidget<TMidiWidget>(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);
}
};


+ 0
- 1
src/Core/MIDI_CV.cpp View File

@@ -1,5 +1,4 @@
#include "Core.hpp"
#include "midi.hpp"

#include <algorithm>



+ 13
- 75
src/Core/MIDI_Gate.cpp View File

@@ -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<PJ301MPort>(mm2px(Vec(27.09498, 108.14429)), module, MIDI_Gate::TRIG_OUTPUT + 14));
addOutput(createOutput<PJ301MPort>(mm2px(Vec(38.693932, 108.14429)), module, MIDI_Gate::TRIG_OUTPUT + 15));

MidiTrigWidget *midiWidget = createWidget<MidiTrigWidget>(mm2px(Vec(3.399621, 14.837339)));
midiWidget->module = module;
typedef Grid16MidiWidget<NoteChoice<MIDI_Gate>> TMidiWidget;
TMidiWidget *midiWidget = createWidget<TMidiWidget>(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<VelocityItem>("Velocity", CHECKMARK(module->velocity));
VelocityItem *velocityItem = createMenuItem<VelocityItem>("Velocity", CHECKMARK(module->velocityMode));
velocityItem->module = module;
menu->addChild(velocityItem);
}


Loading…
Cancel
Save