|  | @@ -0,0 +1,401 @@ | 
														
													
														
															
																|  |  |  |  |  | #include <list> | 
														
													
														
															
																|  |  |  |  |  | #include <algorithm> | 
														
													
														
															
																|  |  |  |  |  | #include "rtmidi/RtMidi.h" | 
														
													
														
															
																|  |  |  |  |  | #include "core.hpp" | 
														
													
														
															
																|  |  |  |  |  | #include "MidiIO.hpp" | 
														
													
														
															
																|  |  |  |  |  | #include "dsp/digital.hpp" | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | struct MidiKey { | 
														
													
														
															
																|  |  |  |  |  | int pitch = 60; | 
														
													
														
															
																|  |  |  |  |  | int at = 0; // aftertouch | 
														
													
														
															
																|  |  |  |  |  | int vel = 0; // velocity | 
														
													
														
															
																|  |  |  |  |  | int retriggerC = 0; | 
														
													
														
															
																|  |  |  |  |  | bool gate = false; | 
														
													
														
															
																|  |  |  |  |  | }; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | struct QuadMIDIToCVInterface : MidiIO, Module { | 
														
													
														
															
																|  |  |  |  |  | enum ParamIds { | 
														
													
														
															
																|  |  |  |  |  | RESET_PARAM, | 
														
													
														
															
																|  |  |  |  |  | NUM_PARAMS | 
														
													
														
															
																|  |  |  |  |  | }; | 
														
													
														
															
																|  |  |  |  |  | enum InputIds { | 
														
													
														
															
																|  |  |  |  |  | NUM_INPUTS | 
														
													
														
															
																|  |  |  |  |  | }; | 
														
													
														
															
																|  |  |  |  |  | enum OutputIds { | 
														
													
														
															
																|  |  |  |  |  | PITCH_OUTPUT = 0, | 
														
													
														
															
																|  |  |  |  |  | GATE_OUTPUT = 4, | 
														
													
														
															
																|  |  |  |  |  | VELOCITY_OUTPUT = 8, | 
														
													
														
															
																|  |  |  |  |  | AT_OUTPUT = 12, | 
														
													
														
															
																|  |  |  |  |  | NUM_OUTPUTS = 16 | 
														
													
														
															
																|  |  |  |  |  | }; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | enum Modes { | 
														
													
														
															
																|  |  |  |  |  | ROTATE, | 
														
													
														
															
																|  |  |  |  |  | RESET, | 
														
													
														
															
																|  |  |  |  |  | REASSIGN | 
														
													
														
															
																|  |  |  |  |  | }; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | bool pedal = false; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | int mode = REASSIGN; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | int getMode() const; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void setMode(int mode); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | MidiKey activeKeys[4]; | 
														
													
														
															
																|  |  |  |  |  | std::list<int> open; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | SchmittTrigger resetTrigger; | 
														
													
														
															
																|  |  |  |  |  | float resetLight = 0.0; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | QuadMIDIToCVInterface() : MidiIO(), Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) { | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | ~QuadMIDIToCVInterface() { | 
														
													
														
															
																|  |  |  |  |  | }; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void step(); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void processMidi(std::vector<unsigned char> msg); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | json_t *toJson() { | 
														
													
														
															
																|  |  |  |  |  | json_t *rootJ = json_object(); | 
														
													
														
															
																|  |  |  |  |  | addBaseJson(rootJ); | 
														
													
														
															
																|  |  |  |  |  | return rootJ; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void fromJson(json_t *rootJ) { | 
														
													
														
															
																|  |  |  |  |  | baseFromJson(rootJ); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void reset() { | 
														
													
														
															
																|  |  |  |  |  | resetMidi(); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void resetMidi(); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | }; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void QuadMIDIToCVInterface::resetMidi() { | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | for (int i = 0; i < 4; i++) { | 
														
													
														
															
																|  |  |  |  |  | outputs[GATE_OUTPUT + i].value = 0.0; | 
														
													
														
															
																|  |  |  |  |  | activeKeys[i].gate = false; | 
														
													
														
															
																|  |  |  |  |  | activeKeys[i].vel = 0; | 
														
													
														
															
																|  |  |  |  |  | activeKeys[i].at = 0; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | open.clear(); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | pedal = false; | 
														
													
														
															
																|  |  |  |  |  | resetLight = 1.0; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void QuadMIDIToCVInterface::step() { | 
														
													
														
															
																|  |  |  |  |  | static float sampleRate = engineGetSampleRate(); | 
														
													
														
															
																|  |  |  |  |  | static int msgsProcessed = 0; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | if (isPortOpen()) { | 
														
													
														
															
																|  |  |  |  |  | std::vector<unsigned char> message; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | // midiIn->getMessage returns empty vector if there are no messages in the queue | 
														
													
														
															
																|  |  |  |  |  | // NOTE: For the quadmidi we will process max 4 midi messages per step to avoid | 
														
													
														
															
																|  |  |  |  |  | // problems with parallel input. | 
														
													
														
															
																|  |  |  |  |  | getMessage(&message); | 
														
													
														
															
																|  |  |  |  |  | while (msgsProcessed < 4 && message.size() > 0) { | 
														
													
														
															
																|  |  |  |  |  | processMidi(message); | 
														
													
														
															
																|  |  |  |  |  | getMessage(&message); | 
														
													
														
															
																|  |  |  |  |  | msgsProcessed++; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | msgsProcessed = 0; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | for (int i = 0; i < 4; i++) { | 
														
													
														
															
																|  |  |  |  |  | outputs[GATE_OUTPUT + i].value = activeKeys[i].gate ? 10.0 : 0; | 
														
													
														
															
																|  |  |  |  |  | outputs[PITCH_OUTPUT + i].value = (activeKeys[i].pitch - 60) / 12.0; | 
														
													
														
															
																|  |  |  |  |  | outputs[VELOCITY_OUTPUT + i].value = activeKeys[i].vel / 127.0 * 10.0; | 
														
													
														
															
																|  |  |  |  |  | outputs[AT_OUTPUT + i].value = activeKeys[i].at / 127.0 * 10.0; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | if (resetTrigger.process(params[RESET_PARAM].value)) { | 
														
													
														
															
																|  |  |  |  |  | resetMidi(); | 
														
													
														
															
																|  |  |  |  |  | return; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | if (resetLight > 0) { | 
														
													
														
															
																|  |  |  |  |  | resetLight -= resetLight / 0.55 / sampleRate; // fade out light | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void QuadMIDIToCVInterface::processMidi(std::vector<unsigned char> msg) { | 
														
													
														
															
																|  |  |  |  |  | int channel = msg[0] & 0xf; | 
														
													
														
															
																|  |  |  |  |  | int status = (msg[0] >> 4) & 0xf; | 
														
													
														
															
																|  |  |  |  |  | int data1 = msg[1]; | 
														
													
														
															
																|  |  |  |  |  | int data2 = msg[2]; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | static int gate; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | // Filter channels | 
														
													
														
															
																|  |  |  |  |  | if (this->channel >= 0 && this->channel != channel) | 
														
													
														
															
																|  |  |  |  |  | return; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | switch (status) { | 
														
													
														
															
																|  |  |  |  |  | // note off | 
														
													
														
															
																|  |  |  |  |  | case 0x8: { | 
														
													
														
															
																|  |  |  |  |  | gate = false; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | break; | 
														
													
														
															
																|  |  |  |  |  | case 0x9: // note on | 
														
													
														
															
																|  |  |  |  |  | if (data2 > 0) { | 
														
													
														
															
																|  |  |  |  |  | gate = true; | 
														
													
														
															
																|  |  |  |  |  | } else { | 
														
													
														
															
																|  |  |  |  |  | // For some reason, some keyboards send a "note on" event with a velocity of 0 to signal that the key has been released. | 
														
													
														
															
																|  |  |  |  |  | gate = false; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | break; | 
														
													
														
															
																|  |  |  |  |  | case 0xa: // channel aftertouch | 
														
													
														
															
																|  |  |  |  |  | for (int i = 0; i < 4; i++) { | 
														
													
														
															
																|  |  |  |  |  | if (activeKeys[i].pitch == data1) { | 
														
													
														
															
																|  |  |  |  |  | activeKeys[i].at = data2; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | return; | 
														
													
														
															
																|  |  |  |  |  | case 0xb: // cc | 
														
													
														
															
																|  |  |  |  |  | if (data1 == 0x40) { // pedal | 
														
													
														
															
																|  |  |  |  |  | pedal = (data2 >= 64); | 
														
													
														
															
																|  |  |  |  |  | if (!pedal) { | 
														
													
														
															
																|  |  |  |  |  | for (int i = 0; i < 4; i++) { | 
														
													
														
															
																|  |  |  |  |  | activeKeys[i].gate = false; | 
														
													
														
															
																|  |  |  |  |  | open.push_back(i); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | return; | 
														
													
														
															
																|  |  |  |  |  | default: | 
														
													
														
															
																|  |  |  |  |  | return; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | if (!pedal && !gate) { | 
														
													
														
															
																|  |  |  |  |  | for (int i = 0; i < 4; i++) { | 
														
													
														
															
																|  |  |  |  |  | if (activeKeys[i].pitch == data1) { | 
														
													
														
															
																|  |  |  |  |  | activeKeys[i].gate = false; | 
														
													
														
															
																|  |  |  |  |  | activeKeys[i].vel = data2; | 
														
													
														
															
																|  |  |  |  |  | if (std::find(open.begin(), open.end(), i) != open.end()) { | 
														
													
														
															
																|  |  |  |  |  | open.remove(i); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | open.push_front(i); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | return; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | if (open.empty()) { | 
														
													
														
															
																|  |  |  |  |  | open.clear(); | 
														
													
														
															
																|  |  |  |  |  | for (int i = 0; i < 4; i++) { | 
														
													
														
															
																|  |  |  |  |  | open.push_back(i); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | if (!activeKeys[0].gate && !activeKeys[1].gate && | 
														
													
														
															
																|  |  |  |  |  | !activeKeys[2].gate && !activeKeys[3].gate) { | 
														
													
														
															
																|  |  |  |  |  | open.sort(); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | switch (mode) { | 
														
													
														
															
																|  |  |  |  |  | case RESET: | 
														
													
														
															
																|  |  |  |  |  | if (open.size() == 4 ) { | 
														
													
														
															
																|  |  |  |  |  | for (int i = 0; i < 4; i++) { | 
														
													
														
															
																|  |  |  |  |  | activeKeys[i].gate = false; | 
														
													
														
															
																|  |  |  |  |  | open.push_back(i); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | break; | 
														
													
														
															
																|  |  |  |  |  | case REASSIGN: | 
														
													
														
															
																|  |  |  |  |  | open.push_back(open.front()); | 
														
													
														
															
																|  |  |  |  |  | break; | 
														
													
														
															
																|  |  |  |  |  | case ROTATE: | 
														
													
														
															
																|  |  |  |  |  | break; | 
														
													
														
															
																|  |  |  |  |  | default: | 
														
													
														
															
																|  |  |  |  |  | fprintf(stderr, "No mode selected?!\n"); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | activeKeys[open.front()].gate = true; | 
														
													
														
															
																|  |  |  |  |  | activeKeys[open.front()].pitch = data1; | 
														
													
														
															
																|  |  |  |  |  | activeKeys[open.front()].vel = data2; | 
														
													
														
															
																|  |  |  |  |  | open.pop_front(); | 
														
													
														
															
																|  |  |  |  |  | return; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | int QuadMIDIToCVInterface::getMode() const { | 
														
													
														
															
																|  |  |  |  |  | return mode; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void QuadMIDIToCVInterface::setMode(int mode) { | 
														
													
														
															
																|  |  |  |  |  | resetMidi(); | 
														
													
														
															
																|  |  |  |  |  | QuadMIDIToCVInterface::mode = mode; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | struct ModeItem : MenuItem { | 
														
													
														
															
																|  |  |  |  |  | int mode; | 
														
													
														
															
																|  |  |  |  |  | QuadMIDIToCVInterface *module; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void onAction() { | 
														
													
														
															
																|  |  |  |  |  | module->setMode(mode); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | }; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | struct ModeChoice : ChoiceButton { | 
														
													
														
															
																|  |  |  |  |  | QuadMIDIToCVInterface *module; | 
														
													
														
															
																|  |  |  |  |  | const std::vector<std::string> modeNames = {"ROTATE", "RESET", "REASSIGN"}; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void onAction() { | 
														
													
														
															
																|  |  |  |  |  | Menu *menu = gScene->createMenu(); | 
														
													
														
															
																|  |  |  |  |  | menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y)); | 
														
													
														
															
																|  |  |  |  |  | menu->box.size.x = box.size.x; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | for (unsigned long i = 0; i < modeNames.size(); i++) { | 
														
													
														
															
																|  |  |  |  |  | ModeItem *modeItem = new ModeItem(); | 
														
													
														
															
																|  |  |  |  |  | modeItem->mode = i; | 
														
													
														
															
																|  |  |  |  |  | modeItem->module = module; | 
														
													
														
															
																|  |  |  |  |  | modeItem->text = modeNames[i]; | 
														
													
														
															
																|  |  |  |  |  | menu->pushChild(modeItem); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void step() { | 
														
													
														
															
																|  |  |  |  |  | text = modeNames[module->getMode()]; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | }; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | QuadMidiToCVWidget::QuadMidiToCVWidget() { | 
														
													
														
															
																|  |  |  |  |  | QuadMIDIToCVInterface *module = new QuadMIDIToCVInterface(); | 
														
													
														
															
																|  |  |  |  |  | setModule(module); | 
														
													
														
															
																|  |  |  |  |  | box.size = Vec(15 * 16, 380); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | { | 
														
													
														
															
																|  |  |  |  |  | Panel *panel = new LightPanel(); | 
														
													
														
															
																|  |  |  |  |  | panel->box.size = box.size; | 
														
													
														
															
																|  |  |  |  |  | addChild(panel); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | float margin = 5; | 
														
													
														
															
																|  |  |  |  |  | float labelHeight = 15; | 
														
													
														
															
																|  |  |  |  |  | float yPos = margin; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | addChild(createScrew<ScrewSilver>(Vec(15, 0))); | 
														
													
														
															
																|  |  |  |  |  | addChild(createScrew<ScrewSilver>(Vec(box.size.x - 30, 0))); | 
														
													
														
															
																|  |  |  |  |  | addChild(createScrew<ScrewSilver>(Vec(15, 365))); | 
														
													
														
															
																|  |  |  |  |  | addChild(createScrew<ScrewSilver>(Vec(box.size.x - 30, 365))); | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | { | 
														
													
														
															
																|  |  |  |  |  | Label *label = new Label(); | 
														
													
														
															
																|  |  |  |  |  | label->box.pos = Vec(box.size.x - margin - 12 * 15, margin); | 
														
													
														
															
																|  |  |  |  |  | label->text = "Quad MIDI to CV"; | 
														
													
														
															
																|  |  |  |  |  | addChild(label); | 
														
													
														
															
																|  |  |  |  |  | yPos = labelHeight * 2; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | addParam(createParam<LEDButton>(Vec(12 * 15, labelHeight), module, QuadMIDIToCVInterface::RESET_PARAM, 0.0, 1.0, | 
														
													
														
															
																|  |  |  |  |  | 0.0)); | 
														
													
														
															
																|  |  |  |  |  | addChild(createValueLight<SmallLight<RedValueLight>>(Vec(12 * 15 + 5, labelHeight + 5), &module->resetLight)); | 
														
													
														
															
																|  |  |  |  |  | { | 
														
													
														
															
																|  |  |  |  |  | Label *label = new Label(); | 
														
													
														
															
																|  |  |  |  |  | label->box.pos = Vec(margin, yPos); | 
														
													
														
															
																|  |  |  |  |  | label->text = "MIDI Interface"; | 
														
													
														
															
																|  |  |  |  |  | addChild(label); | 
														
													
														
															
																|  |  |  |  |  | yPos += labelHeight + margin; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | MidiChoice *midiChoice = new MidiChoice(); | 
														
													
														
															
																|  |  |  |  |  | midiChoice->midiModule = dynamic_cast<MidiIO *>(module); | 
														
													
														
															
																|  |  |  |  |  | midiChoice->box.pos = Vec(margin, yPos); | 
														
													
														
															
																|  |  |  |  |  | midiChoice->box.size.x = box.size.x - 10; | 
														
													
														
															
																|  |  |  |  |  | addChild(midiChoice); | 
														
													
														
															
																|  |  |  |  |  | yPos += midiChoice->box.size.y + margin; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | { | 
														
													
														
															
																|  |  |  |  |  | Label *label = new Label(); | 
														
													
														
															
																|  |  |  |  |  | label->box.pos = Vec(margin, yPos); | 
														
													
														
															
																|  |  |  |  |  | label->text = "Channel"; | 
														
													
														
															
																|  |  |  |  |  | addChild(label); | 
														
													
														
															
																|  |  |  |  |  | yPos += labelHeight + margin; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | ChannelChoice *channelChoice = new ChannelChoice(); | 
														
													
														
															
																|  |  |  |  |  | channelChoice->midiModule = dynamic_cast<MidiIO *>(module); | 
														
													
														
															
																|  |  |  |  |  | channelChoice->box.pos = Vec(margin, yPos); | 
														
													
														
															
																|  |  |  |  |  | channelChoice->box.size.x = box.size.x - 10; | 
														
													
														
															
																|  |  |  |  |  | addChild(channelChoice); | 
														
													
														
															
																|  |  |  |  |  | yPos += channelChoice->box.size.y + margin; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | { | 
														
													
														
															
																|  |  |  |  |  | Label *label = new Label(); | 
														
													
														
															
																|  |  |  |  |  | label->box.pos = Vec(margin, yPos); | 
														
													
														
															
																|  |  |  |  |  | label->text = "Mode"; | 
														
													
														
															
																|  |  |  |  |  | addChild(label); | 
														
													
														
															
																|  |  |  |  |  | yPos += labelHeight + margin; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | ModeChoice *modeChoice = new ModeChoice(); | 
														
													
														
															
																|  |  |  |  |  | modeChoice->module = module; | 
														
													
														
															
																|  |  |  |  |  | modeChoice->box.pos = Vec(margin, yPos); | 
														
													
														
															
																|  |  |  |  |  | modeChoice->box.size.x = box.size.x - 10; | 
														
													
														
															
																|  |  |  |  |  | addChild(modeChoice); | 
														
													
														
															
																|  |  |  |  |  | yPos += modeChoice->box.size.y + margin + 15; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | { | 
														
													
														
															
																|  |  |  |  |  | Label *label = new Label(); | 
														
													
														
															
																|  |  |  |  |  | label->box.pos = Vec(84, yPos); | 
														
													
														
															
																|  |  |  |  |  | label->text = "1"; | 
														
													
														
															
																|  |  |  |  |  | addChild(label); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | { | 
														
													
														
															
																|  |  |  |  |  | Label *label = new Label(); | 
														
													
														
															
																|  |  |  |  |  | label->box.pos = Vec(125, yPos); | 
														
													
														
															
																|  |  |  |  |  | label->text = "2"; | 
														
													
														
															
																|  |  |  |  |  | addChild(label); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | { | 
														
													
														
															
																|  |  |  |  |  | Label *label = new Label(); | 
														
													
														
															
																|  |  |  |  |  | label->box.pos = Vec(164, yPos); | 
														
													
														
															
																|  |  |  |  |  | label->text = "3"; | 
														
													
														
															
																|  |  |  |  |  | addChild(label); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | { | 
														
													
														
															
																|  |  |  |  |  | Label *label = new Label(); | 
														
													
														
															
																|  |  |  |  |  | label->box.pos = Vec(203, yPos); | 
														
													
														
															
																|  |  |  |  |  | label->text = "4"; | 
														
													
														
															
																|  |  |  |  |  | addChild(label); | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | std::string labels[4] = {"1V/oct", "Gate", "Velocity", "Aftertouch"}; | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | yPos += labelHeight + margin * 2; | 
														
													
														
															
																|  |  |  |  |  | for (int i = 0; i < 4; i++) { | 
														
													
														
															
																|  |  |  |  |  | Label *label = new Label(); | 
														
													
														
															
																|  |  |  |  |  | label->box.pos = Vec(margin, yPos); | 
														
													
														
															
																|  |  |  |  |  | label->text = labels[i]; | 
														
													
														
															
																|  |  |  |  |  | addChild(label); | 
														
													
														
															
																|  |  |  |  |  | addOutput(createOutput<PJ3410Port>(Vec(2 * (40), yPos - 5), module, i * 4)); | 
														
													
														
															
																|  |  |  |  |  | addOutput(createOutput<PJ3410Port>(Vec(3 * (40), yPos - 5), module, i * 4 + 1)); | 
														
													
														
															
																|  |  |  |  |  | addOutput(createOutput<PJ3410Port>(Vec(4 * (40), yPos - 5), module, i * 4 + 2)); | 
														
													
														
															
																|  |  |  |  |  | addOutput(createOutput<PJ3410Port>(Vec(5 * (40), yPos - 5), module, i * 4 + 3)); | 
														
													
														
															
																|  |  |  |  |  | yPos += 40; | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | } | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | void QuadMidiToCVWidget::step() { | 
														
													
														
															
																|  |  |  |  |  | 
 | 
														
													
														
															
																|  |  |  |  |  | ModuleWidget::step(); | 
														
													
														
															
																|  |  |  |  |  | } |