|
|
@@ -19,19 +19,21 @@ struct MIDICCToCVInterface : Module { |
|
|
|
}; |
|
|
|
|
|
|
|
MidiInputQueue midiInput; |
|
|
|
int8_t cvs[16]; |
|
|
|
int8_t ccs[128]; |
|
|
|
ExponentialFilter ccFilters[16]; |
|
|
|
|
|
|
|
int learningId = -1; |
|
|
|
uint8_t learnedCcs[16] = {}; |
|
|
|
int learnedCcs[16] = {}; |
|
|
|
|
|
|
|
MIDICCToCVInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) { |
|
|
|
onReset(); |
|
|
|
} |
|
|
|
|
|
|
|
void onReset() override { |
|
|
|
for (int i = 0; i < 128; i++) { |
|
|
|
ccs[i] = 0; |
|
|
|
} |
|
|
|
for (int i = 0; i < 16; i++) { |
|
|
|
cvs[i] = 0; |
|
|
|
learnedCcs[i] = i; |
|
|
|
} |
|
|
|
learningId = -1; |
|
|
@@ -45,7 +47,8 @@ struct MIDICCToCVInterface : Module { |
|
|
|
|
|
|
|
float lambda = 100.f * engineGetSampleTime(); |
|
|
|
for (int i = 0; i < 16; i++) { |
|
|
|
float value = rescale(cvs[i], 0, 127, 0.f, 10.f); |
|
|
|
int learnedCc = learnedCcs[i]; |
|
|
|
float value = rescale(clamp(ccs[learnedCc], -127, 127), 0, 127, 0.f, 10.f); |
|
|
|
ccFilters[i].lambda = lambda; |
|
|
|
outputs[CC_OUTPUT + i].value = ccFilters[i].process(value); |
|
|
|
} |
|
|
@@ -57,17 +60,13 @@ struct MIDICCToCVInterface : Module { |
|
|
|
case 0xb: { |
|
|
|
uint8_t cc = msg.note(); |
|
|
|
// Learn |
|
|
|
if (learningId >= 0) { |
|
|
|
if (learningId >= 0 && ccs[cc] != msg.data2) { |
|
|
|
learnedCcs[learningId] = cc; |
|
|
|
learningId = -1; |
|
|
|
} |
|
|
|
// Set CV |
|
|
|
for (int i = 0; i < 16; i++) { |
|
|
|
if (learnedCcs[i] == cc) { |
|
|
|
// Allow CC to be negative if the 8th bit is set |
|
|
|
cvs[i] = msg.data2; |
|
|
|
} |
|
|
|
} |
|
|
|
// Allow CC to be negative if the 8th bit is set |
|
|
|
ccs[cc] = msg.data2; |
|
|
|
} break; |
|
|
|
default: break; |
|
|
|
} |
|
|
|