diff --git a/src/core/CV_MIDICC.cpp b/src/core/CV_MIDICC.cpp index 68065b15..1de3acf6 100644 --- a/src/core/CV_MIDICC.cpp +++ b/src/core/CV_MIDICC.cpp @@ -6,21 +6,21 @@ namespace core { struct CCMidiOutput : midi::Output { - int lastValues[128]; - double frame = 0.0; + uint8_t lastValues[128]; + int64_t frame = -1; CCMidiOutput() { reset(); } void reset() { - for (int n = 0; n < 128; n++) { + for (uint8_t n = 0; n < 128; n++) { lastValues[n] = -1; } Output::reset(); } - void setValue(int value, int cc) { + void setValue(uint8_t value, uint8_t cc) { if (value == lastValues[cc]) return; lastValues[cc] = value; @@ -33,7 +33,7 @@ struct CCMidiOutput : midi::Output { sendMessage(m); } - void setFrame(double frame) { + void setFrame(int64_t frame) { this->frame = frame; } }; diff --git a/src/core/Gate_MIDI.cpp b/src/core/Gate_MIDI.cpp index dd8f80b0..0a142527 100644 --- a/src/core/Gate_MIDI.cpp +++ b/src/core/Gate_MIDI.cpp @@ -6,16 +6,16 @@ namespace core { struct GateMidiOutput : midi::Output { - int vels[128]; + uint8_t vels[128]; bool lastGates[128]; - double frame = 0.0; + int64_t frame = -1; GateMidiOutput() { reset(); } void reset() { - for (int note = 0; note < 128; note++) { + for (uint8_t note = 0; note < 128; note++) { vels[note] = 100; lastGates[note] = false; } @@ -24,7 +24,7 @@ struct GateMidiOutput : midi::Output { void panic() { // Send all note off commands - for (int note = 0; note < 128; note++) { + for (uint8_t note = 0; note < 128; note++) { // Note off midi::Message m; m.setStatus(0x8); @@ -36,11 +36,11 @@ struct GateMidiOutput : midi::Output { } } - void setVelocity(int vel, int note) { + void setVelocity(uint8_t note, uint8_t vel) { vels[note] = vel; } - void setGate(bool gate, int note) { + void setGate(uint8_t note, bool gate) { if (gate && !lastGates[note]) { // Note on midi::Message m; @@ -62,7 +62,7 @@ struct GateMidiOutput : midi::Output { lastGates[note] = gate; } - void setFrame(double frame) { + void setFrame(int64_t frame) { this->frame = frame; } }; @@ -86,12 +86,13 @@ struct Gate_MIDI : Module { GateMidiOutput midiOutput; bool velocityMode = false; int learningId = -1; - uint8_t learnedNotes[16] = {}; + int8_t learnedNotes[16] = {}; + dsp::SchmittTrigger cellTriggers[16]; Gate_MIDI() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - for (int i = 0; i < 16; i++) - configInput(GATE_INPUTS + i, string::f("Cell %d", i + 1)); + for (int id = 0; id < 16; id++) + configInput(GATE_INPUTS + id, string::f("Cell %d", id + 1)); onReset(); } @@ -109,28 +110,42 @@ struct Gate_MIDI : Module { void process(const ProcessArgs& args) override { midiOutput.setFrame(args.frame); - for (int i = 0; i < 16; i++) { - int note = learnedNotes[i]; + for (int id = 0; id < 16; id++) { + int8_t note = learnedNotes[id]; + if (note < 0) + continue; + if (velocityMode) { - int vel = (int) std::round(inputs[GATE_INPUTS + i].getVoltage() / 10.f * 127); + int8_t vel = (int8_t) clamp(std::round(inputs[GATE_INPUTS + id].getVoltage() / 10.f * 127), 0.f, 127.f); vel = clamp(vel, 0, 127); - midiOutput.setVelocity(vel, note); - midiOutput.setGate(vel > 0, note); + midiOutput.setVelocity(note, vel); + midiOutput.setGate(note, vel > 0); } else { - bool gate = inputs[GATE_INPUTS + i].getVoltage() >= 1.f; - midiOutput.setVelocity(100, note); - midiOutput.setGate(gate, note); + cellTriggers[id].process(inputs[GATE_INPUTS + id].getVoltage(), 0.1f, 2.f); + midiOutput.setVelocity(note, 100); + midiOutput.setGate(note, cellTriggers[id].isHigh()); + } + } + } + + void setLearnedNote(int id, int8_t note) { + // Unset IDs of similar note + if (note >= 0) { + for (int id = 0; id < 16; id++) { + if (learnedNotes[id] == note) + learnedNotes[id] = -1; } } + learnedNotes[id] = 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]); + for (int id = 0; id < 16; id++) { + json_t* noteJ = json_integer(learnedNotes[id]); json_array_append_new(notesJ, noteJ); } json_object_set_new(rootJ, "notes", notesJ); @@ -144,10 +159,10 @@ struct Gate_MIDI : Module { 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); + for (int id = 0; id < 16; id++) { + json_t* noteJ = json_array_get(notesJ, id); if (noteJ) - learnedNotes[i] = json_integer_value(noteJ); + setLearnedNote(id, json_integer_value(noteJ)); } } diff --git a/src/core/MIDI_Gate.cpp b/src/core/MIDI_Gate.cpp index 29c6252f..64e343cb 100644 --- a/src/core/MIDI_Gate.cpp +++ b/src/core/MIDI_Gate.cpp @@ -31,7 +31,7 @@ struct MIDI_Gate : Module { /** Cell ID in learn mode, or -1 if none. */ int learningId; /** [cell] */ - uint8_t learnedNotes[16]; + int8_t learnedNotes[16]; bool velocityMode; bool mpeMode; @@ -113,7 +113,7 @@ struct MIDI_Gate : Module { int c = mpeMode ? channel : 0; // Learn if (learningId >= 0) { - learnedNotes[learningId] = note; + setLearnedNote(learningId, note); learningId = -1; } // Find id @@ -136,6 +136,10 @@ struct MIDI_Gate : Module { } } + void setLearnedNote(int id, int8_t note) { + learnedNotes[id] = note; + } + json_t* dataToJson() override { json_t* rootJ = json_object(); @@ -160,7 +164,7 @@ struct MIDI_Gate : Module { for (int i = 0; i < 16; i++) { json_t* noteJ = json_array_get(notesJ, i); if (noteJ) - learnedNotes[i] = json_integer_value(noteJ); + setLearnedNote(i, json_integer_value(noteJ)); } } diff --git a/src/core/plugin.hpp b/src/core/plugin.hpp index b6285fb0..7f624e4a 100644 --- a/src/core/plugin.hpp +++ b/src/core/plugin.hpp @@ -147,7 +147,7 @@ template struct NoteChoice : LedDisplayChoice { TModule* module; int id; - int focusNote; + uint8_t focusNote; NoteChoice() { box.size.y = mm2px(6.666); @@ -164,7 +164,7 @@ struct NoteChoice : LedDisplayChoice { } void step() override { - int note; + int8_t note; if (!module) { note = id + 36; } @@ -206,7 +206,7 @@ struct NoteChoice : LedDisplayChoice { return; if (module->learningId == id) { if (0 <= focusNote && focusNote < 128) { - module->learnedNotes[id] = focusNote; + module->setLearnedNote(id, focusNote); } module->learningId = -1; }