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