diff --git a/src/Core/MIDICCToCVInterface.cpp b/src/Core/MIDICCToCVInterface.cpp index 2c85bbdb..e16a5cdd 100644 --- a/src/Core/MIDICCToCVInterface.cpp +++ b/src/Core/MIDICCToCVInterface.cpp @@ -19,10 +19,10 @@ struct MIDICCToCVInterface : Module { midi::InputQueue midiInput; int8_t values[128]; - dsp::ExponentialFilter ccFilters[16]; + dsp::ExponentialFilter valueFilters[16]; int learningId = -1; - int learnedCcs[16] = {}; + int ccs[16] = {}; bool jump[16] = {}; MIDICCToCVInterface() { @@ -35,7 +35,7 @@ struct MIDICCToCVInterface : Module { values[i] = 0; } for (int i = 0; i < 16; i++) { - learnedCcs[i] = i; + ccs[i] = i; } learningId = -1; } @@ -48,18 +48,18 @@ struct MIDICCToCVInterface : Module { float lambda = app()->engine->getSampleTime() * 100.f; for (int i = 0; i < 16; i++) { - int learnedCc = learnedCcs[i]; + int learnedCc = ccs[i]; float value = rescale(values[learnedCc], 0, 127, 0.f, 10.f); - ccFilters[i].lambda = lambda; + valueFilters[i].lambda = lambda; // Smooth value unless we're jumping there if (jump[i]) { - ccFilters[i].out = value; + valueFilters[i].out = value; jump[i] = false; } else { - ccFilters[i].process(value); + valueFilters[i].process(value); } - outputs[CC_OUTPUT + i].setVoltage(ccFilters[i].out); + outputs[CC_OUTPUT + i].setVoltage(valueFilters[i].out); } } @@ -70,7 +70,7 @@ struct MIDICCToCVInterface : Module { uint8_t cc = msg.note(); // Learn if (learningId >= 0 && values[cc] != msg.data2) { - learnedCcs[learningId] = cc; + ccs[learningId] = cc; learningId = -1; } int8_t oldValue = values[cc]; @@ -92,11 +92,17 @@ struct MIDICCToCVInterface : Module { json_t *ccsJ = json_array(); for (int i = 0; i < 16; i++) { - json_t *ccJ = json_integer(learnedCcs[i]); - json_array_append_new(ccsJ, ccJ); + json_array_append_new(ccsJ, json_integer(ccs[i])); } json_object_set_new(rootJ, "ccs", ccsJ); + // Remember values so users don't have to touch MIDI controller knobs when restarting Rack + json_t *valuesJ = json_array(); + for (int i = 0; i < 128; i++) { + json_array_append_new(valuesJ, json_integer(values[i])); + } + json_object_set_new(rootJ, "values", valuesJ); + json_object_set_new(rootJ, "midi", midiInput.toJson()); return rootJ; } @@ -107,7 +113,21 @@ struct MIDICCToCVInterface : Module { for (int i = 0; i < 16; i++) { json_t *ccJ = json_array_get(ccsJ, i); if (ccJ) - learnedCcs[i] = json_integer_value(ccJ); + ccs[i] = json_integer_value(ccJ); + } + } + + json_t *valuesJ = json_object_get(rootJ, "values"); + if (valuesJ) { + for (int i = 0; i < 128; i++) { + json_t *valueJ = json_array_get(valuesJ, i); + if (valueJ) { + values[i] = json_integer_value(valueJ); + } + } + // Jump all CCs + for (int i = 0; i < 16; i++) { + jump[i] = true; } } @@ -145,7 +165,7 @@ struct MidiCcChoice : GridChoice { color.a = 0.5; } else { - text = string::f("%d", module->learnedCcs[id]); + text = string::f("%d", module->ccs[id]); color.a = 1.0; if (app()->event->selectedWidget == this) app()->event->selectedWidget = NULL; @@ -164,7 +184,7 @@ struct MidiCcChoice : GridChoice { if (!module) return; if (0 <= focusCc && focusCc < 128) { - module->learnedCcs[id] = focusCc; + module->ccs[id] = focusCc; } module->learningId = -1; }