From 3dabea0eda621ac0a83312c16717791ce0f90619 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Mon, 24 Jan 2022 10:57:12 -0500 Subject: [PATCH] Refactor note and CC types in MIDI interface modules. --- src/core/CV_MIDICC.cpp | 38 ++++++++++++++++++++------------ src/core/Gate_MIDI.cpp | 3 +-- src/core/MIDICC_CV.cpp | 49 ++++++++++++++++++++++++++---------------- src/core/MIDI_Gate.cpp | 7 ++++++ src/core/plugin.hpp | 2 +- 5 files changed, 63 insertions(+), 36 deletions(-) diff --git a/src/core/CV_MIDICC.cpp b/src/core/CV_MIDICC.cpp index 1de3acf6..4f63e82b 100644 --- a/src/core/CV_MIDICC.cpp +++ b/src/core/CV_MIDICC.cpp @@ -57,18 +57,18 @@ struct CV_MIDICC : Module { CCMidiOutput midiOutput; dsp::Timer rateLimiterTimer; int learningId = -1; - int learnedCcs[16] = {}; + int8_t learnedCcs[16] = {}; CV_MIDICC() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - for (int i = 0; i < 16; i++) - configInput(CC_INPUTS + i, string::f("Cell %d", i + 1)); + for (int id = 0; id < 16; id++) + configInput(CC_INPUTS + id, string::f("Cell %d", id + 1)); onReset(); } void onReset() override { - for (int i = 0; i < 16; i++) { - learnedCcs[i] = i; + for (int id = 0; id < 16; id++) { + learnedCcs[id] = id; } learningId = -1; midiOutput.reset(); @@ -85,19 +85,29 @@ struct CV_MIDICC : Module { midiOutput.setFrame(args.frame); - 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, learnedCcs[i]); + for (int id = 0; id < 16; id++) { + uint8_t value = (uint8_t) clamp(std::round(inputs[CC_INPUTS + id].getVoltage() / 10.f * 127), 0.f, 127.f); + midiOutput.setValue(value, learnedCcs[id]); } } + void setLearnedCc(int id, int8_t cc) { + // Unset IDs of similar CCs + if (cc >= 0) { + for (int id = 0; id < 16; id++) { + if (learnedCcs[id] == cc) + learnedCcs[id] = -1; + } + } + learnedCcs[id] = cc; + } + 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])); + for (int id = 0; id < 16; id++) { + json_array_append_new(ccsJ, json_integer(learnedCcs[id])); } json_object_set_new(rootJ, "ccs", ccsJ); @@ -108,10 +118,10 @@ struct CV_MIDICC : Module { 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); + for (int id = 0; id < 16; id++) { + json_t* ccJ = json_array_get(ccsJ, id); if (ccJ) - learnedCcs[i] = json_integer_value(ccJ); + setLearnedCc(id, json_integer_value(ccJ)); } } diff --git a/src/core/Gate_MIDI.cpp b/src/core/Gate_MIDI.cpp index 0a142527..e940cbfd 100644 --- a/src/core/Gate_MIDI.cpp +++ b/src/core/Gate_MIDI.cpp @@ -116,8 +116,7 @@ struct Gate_MIDI : Module { continue; if (velocityMode) { - 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); + uint8_t vel = (uint8_t) clamp(std::round(inputs[GATE_INPUTS + id].getVoltage() / 10.f * 127), 0.f, 127.f); midiOutput.setVelocity(note, vel); midiOutput.setGate(note, vel > 0); } diff --git a/src/core/MIDICC_CV.cpp b/src/core/MIDICC_CV.cpp index 5d274c5a..2097af95 100644 --- a/src/core/MIDICC_CV.cpp +++ b/src/core/MIDICC_CV.cpp @@ -29,7 +29,7 @@ struct MIDICC_CV : Module { */ int8_t msbValues[32][16]; int learningId; - int learnedCcs[16]; + int8_t learnedCcs[16]; /** [cell][channel] */ dsp::ExponentialFilter valueFilters[16][16]; bool smooth; @@ -38,31 +38,31 @@ struct MIDICC_CV : Module { MIDICC_CV() { config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); - for (int i = 0; i < 16; i++) - configOutput(CC_OUTPUT + i, string::f("Cell %d", i + 1)); + for (int id = 0; id < 16; id++) + configOutput(CC_OUTPUT + id, string::f("Cell %d", id + 1)); - for (int i = 0; i < 16; i++) { + for (int id = 0; id < 16; id++) { for (int c = 0; c < 16; c++) { - valueFilters[i][c].setTau(1 / 30.f); + valueFilters[id][c].setTau(1 / 30.f); } } onReset(); } void onReset() override { - for (int cc = 0; cc < 128; cc++) { + for (int8_t cc = 0; cc < 128; cc++) { for (int c = 0; c < 16; c++) { ccValues[cc][c] = 0; } } - for (int cc = 0; cc < 32; cc++) { + for (int8_t cc = 0; cc < 32; cc++) { for (int c = 0; c < 16; c++) { msbValues[cc][c] = 0; } } learningId = -1; - for (int i = 0; i < 16; i++) { - learnedCcs[i] = i; + for (int id = 0; id < 16; id++) { + learnedCcs[id] = id; } midiInput.reset(); smooth = true; @@ -78,12 +78,12 @@ struct MIDICC_CV : Module { int channels = mpeMode ? 16 : 1; - for (int i = 0; i < 16; i++) { - if (!outputs[CC_OUTPUT + i].isConnected()) + for (int id = 0; id < 16; id++) { + if (!outputs[CC_OUTPUT + id].isConnected()) continue; - outputs[CC_OUTPUT + i].setChannels(channels); + outputs[CC_OUTPUT + id].setChannels(channels); - int cc = learnedCcs[i]; + int cc = learnedCcs[id]; for (int c = 0; c < channels; c++) { int16_t cellValue = int16_t(ccValues[cc][c]) * 128; @@ -95,15 +95,15 @@ struct MIDICC_CV : Module { value = clamp(value, -1.f, 1.f); // Detect behavior from MIDI buttons. - if (smooth && std::fabs(valueFilters[i][c].out - value) < 1.f) { + if (smooth && std::fabs(valueFilters[id][c].out - value) < 1.f) { // Smooth value with filter - valueFilters[i][c].process(args.sampleTime, value); + valueFilters[id][c].process(args.sampleTime, value); } else { // Jump value - valueFilters[i][c].out = value; + valueFilters[id][c].out = value; } - outputs[CC_OUTPUT + i].setVoltage(valueFilters[i][c].out * 10.f, c); + outputs[CC_OUTPUT + id].setVoltage(valueFilters[id][c].out * 10.f, c); } } } @@ -129,7 +129,7 @@ struct MIDICC_CV : Module { int8_t value = msg.bytes[2]; // Learn if (learningId >= 0 && ccValues[cc][c] != value) { - learnedCcs[learningId] = cc; + setLearnedCc(learningId, cc); learningId = -1; } @@ -147,6 +147,17 @@ struct MIDICC_CV : Module { } } + void setLearnedCc(int id, int8_t cc) { + // Unset IDs of similar CCs + if (cc >= 0) { + for (int id = 0; id < 16; id++) { + if (learnedCcs[id] == cc) + learnedCcs[id] = -1; + } + } + learnedCcs[id] = cc; + } + json_t* dataToJson() override { json_t* rootJ = json_object(); @@ -178,7 +189,7 @@ struct MIDICC_CV : Module { for (int i = 0; i < 16; i++) { json_t* ccJ = json_array_get(ccsJ, i); if (ccJ) - learnedCcs[i] = json_integer_value(ccJ); + setLearnedCc(i, json_integer_value(ccJ)); } } diff --git a/src/core/MIDI_Gate.cpp b/src/core/MIDI_Gate.cpp index 64e343cb..96eb8cb3 100644 --- a/src/core/MIDI_Gate.cpp +++ b/src/core/MIDI_Gate.cpp @@ -137,6 +137,13 @@ struct MIDI_Gate : Module { } 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; } diff --git a/src/core/plugin.hpp b/src/core/plugin.hpp index 7f624e4a..01eb47ee 100644 --- a/src/core/plugin.hpp +++ b/src/core/plugin.hpp @@ -114,7 +114,7 @@ struct CcChoice : LedDisplayChoice { return; if (module->learningId == id) { if (0 <= focusCc && focusCc < 128) { - module->learnedCcs[id] = focusCc; + module->setLearnedCc(id, focusCc); } module->learningId = -1; }