|
|
@@ -22,6 +22,7 @@ struct MIDICCToCVInterface : MidiIO, Module { |
|
|
|
int cc[NUM_OUTPUTS]; |
|
|
|
int ccNum[NUM_OUTPUTS]; |
|
|
|
bool ccSync[NUM_OUTPUTS]; |
|
|
|
bool ccSyncFirst[NUM_OUTPUTS]; |
|
|
|
bool ccNumInited[NUM_OUTPUTS]; |
|
|
|
bool onFocus[NUM_OUTPUTS]; |
|
|
|
float lights[NUM_OUTPUTS]; |
|
|
@@ -31,8 +32,9 @@ struct MIDICCToCVInterface : MidiIO, Module { |
|
|
|
for (int i = 0; i < NUM_OUTPUTS; i++) { |
|
|
|
cc[i] = 0; |
|
|
|
ccNum[i] = i; |
|
|
|
ccSync[i] = true; |
|
|
|
ccSyncFirst[i] = true; |
|
|
|
onFocus[i] = false; |
|
|
|
ccSync[i] = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -51,7 +53,7 @@ struct MIDICCToCVInterface : MidiIO, Module { |
|
|
|
addBaseJson(rootJ); |
|
|
|
for (int i = 0; i < NUM_OUTPUTS; i++) { |
|
|
|
json_object_set_new(rootJ, ("ccNum" + std::to_string(i)).c_str(), json_integer(ccNum[i])); |
|
|
|
if(outputs[i].active){ |
|
|
|
if (outputs[i].active) { |
|
|
|
json_object_set_new(rootJ, ("ccVal" + std::to_string(i)).c_str(), json_integer(cc[i])); |
|
|
|
} |
|
|
|
} |
|
|
@@ -70,7 +72,6 @@ struct MIDICCToCVInterface : MidiIO, Module { |
|
|
|
json_t *ccValJ = json_object_get(rootJ, ("ccVal" + std::to_string(i)).c_str()); |
|
|
|
if (ccValJ) { |
|
|
|
cc[i] = json_integer_value(ccValJ); |
|
|
|
ccSync[i] = false; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
@@ -82,7 +83,6 @@ struct MIDICCToCVInterface : MidiIO, Module { |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
void MIDICCToCVInterface::step() { |
|
|
|
if (isPortOpen()) { |
|
|
|
std::vector<unsigned char> message; |
|
|
@@ -124,21 +124,26 @@ void MIDICCToCVInterface::processMidi(std::vector<unsigned char> msg) { |
|
|
|
if (status == 0xb) { |
|
|
|
for (int i = 0; i < NUM_OUTPUTS; i++) { |
|
|
|
if (onFocus[i]) { |
|
|
|
if (ccNum[i] != data1) { |
|
|
|
ccSync[i] = false; |
|
|
|
} |
|
|
|
this->ccNum[i] = data1; |
|
|
|
ccSync[i] = true; |
|
|
|
ccSyncFirst[i] = true; |
|
|
|
ccNum[i] = data1; |
|
|
|
} |
|
|
|
} |
|
|
|
for (int i = 0; i < NUM_OUTPUTS; i++) { |
|
|
|
|
|
|
|
if (data1 == ccNum[i]) { |
|
|
|
if (!ccSync[i]) { |
|
|
|
ccSync[i] = (cc[i] <= data2+1 && cc[i] >= data2-1) ; |
|
|
|
break; |
|
|
|
if (ccSyncFirst[i]) { |
|
|
|
ccSyncFirst[i] = false; |
|
|
|
|
|
|
|
ccSync[i] = data2 < cc[i]+2 && data2 > cc[i] - 2; |
|
|
|
} |
|
|
|
|
|
|
|
this->cc[i] = data2; |
|
|
|
if (ccSync[i]) { |
|
|
|
cc[i] = data2; |
|
|
|
} else if (cc[i] == data2) { |
|
|
|
ccSync[i] = true; |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@@ -155,22 +160,21 @@ struct CCTextField : TextField { |
|
|
|
|
|
|
|
void onMouseLeave(); |
|
|
|
|
|
|
|
int *ccNum; |
|
|
|
bool *inited; |
|
|
|
bool *onFocus; |
|
|
|
bool *ccSync; |
|
|
|
int num; |
|
|
|
|
|
|
|
MIDICCToCVInterface *module; |
|
|
|
}; |
|
|
|
|
|
|
|
void CCTextField::draw(NVGcontext *vg) { |
|
|
|
/* This is necessary, since the save |
|
|
|
* file is loaded after constructing the widget*/ |
|
|
|
if (*inited) { |
|
|
|
*inited = false; |
|
|
|
text = std::to_string(*ccNum); |
|
|
|
if (module->ccNumInited[num]) { |
|
|
|
module->ccNumInited[num] = false; |
|
|
|
text = std::to_string(module->ccNum[num]); |
|
|
|
} |
|
|
|
|
|
|
|
if (*onFocus) { |
|
|
|
text = std::to_string(*ccNum); |
|
|
|
if (module->onFocus[num]) { |
|
|
|
text = std::to_string(module->ccNum[num]); |
|
|
|
} |
|
|
|
|
|
|
|
TextField::draw(vg); |
|
|
@@ -178,23 +182,24 @@ void CCTextField::draw(NVGcontext *vg) { |
|
|
|
|
|
|
|
void CCTextField::onMouseUpOpaque(int button) { |
|
|
|
if (button == 1) { |
|
|
|
*onFocus = false; |
|
|
|
module->onFocus[num] = false; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void CCTextField::onMouseDownOpaque(int button) { |
|
|
|
if (button == 1) { |
|
|
|
*onFocus = true; |
|
|
|
module->onFocus[num] = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void CCTextField::onMouseLeave() { |
|
|
|
*onFocus = false; |
|
|
|
module->onFocus[num] = false; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CCTextField::onTextChange() { |
|
|
|
int *ccNum = &module->ccNum[num]; |
|
|
|
if (text.size() > 0) { |
|
|
|
try { |
|
|
|
*ccNum = std::stoi(text); |
|
|
@@ -206,8 +211,8 @@ void CCTextField::onTextChange() { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (!*inited && *ccNum != std::stoi(text)) { |
|
|
|
*ccSync = false; |
|
|
|
if (!module->ccNumInited[num] && *ccNum != std::stoi(text)) { |
|
|
|
module->ccSync[num] = true; |
|
|
|
} |
|
|
|
|
|
|
|
} catch (...) { |
|
|
@@ -275,10 +280,8 @@ MIDICCToCVWidget::MIDICCToCVWidget() { |
|
|
|
|
|
|
|
for (int i = 0; i < MIDICCToCVInterface::NUM_OUTPUTS; i++) { |
|
|
|
CCTextField *ccNumChoice = new CCTextField(); |
|
|
|
ccNumChoice->ccNum = &module->ccNum[i]; |
|
|
|
ccNumChoice->inited = &module->ccNumInited[i]; |
|
|
|
ccNumChoice->onFocus = &module->onFocus[i]; |
|
|
|
ccNumChoice->ccSync = &module->ccSync[i]; |
|
|
|
ccNumChoice->module = module; |
|
|
|
ccNumChoice->num = i; |
|
|
|
ccNumChoice->text = std::to_string(module->ccNum[i]); |
|
|
|
ccNumChoice->box.pos = Vec(11 + (i % 4) * (63), yPos); |
|
|
|
ccNumChoice->box.size.x = 29; |
|
|
@@ -287,7 +290,8 @@ MIDICCToCVWidget::MIDICCToCVWidget() { |
|
|
|
|
|
|
|
yPos += labelHeight + margin; |
|
|
|
addOutput(createOutput<PJ3410Port>(Vec((i % 4) * (63) + 10, yPos + 5), module, i)); |
|
|
|
addChild(createValueLight<SmallLight<RedValueLight>>(Vec((i % 4) * (63) + 32, yPos + 5), &module->lights[i])); |
|
|
|
addChild(createValueLight<SmallLight<RedValueLight>>(Vec((i % 4) * (63) + 32, yPos + 5), |
|
|
|
&module->lights[i])); |
|
|
|
|
|
|
|
if ((i + 1) % 4 == 0) { |
|
|
|
yPos += 47 + margin; |
|
|
|