@@ -117,7 +117,7 @@ void MIDICCToCVInterface::resetMidi() { | |||||
for (int i = 0; i < NUM_OUTPUTS; i++) { | for (int i = 0; i < NUM_OUTPUTS; i++) { | ||||
cc[i].val = 0; | cc[i].val = 0; | ||||
cc[i].resetSync(); | cc[i].resetSync(); | ||||
cc[i].tSmooth.set(0,0); | |||||
cc[i].tSmooth.set(0, 0); | |||||
} | } | ||||
}; | }; | ||||
@@ -147,7 +147,8 @@ void MIDICCToCVInterface::processMidi(std::vector<unsigned char> msg) { | |||||
cc[i].syncFirst = false; | cc[i].syncFirst = false; | ||||
if (data2 < cc[i].val + 2 && data2 > cc[i].val - 2) { | if (data2 < cc[i].val + 2 && data2 > cc[i].val - 2) { | ||||
cc[i].sync = 0; | cc[i].sync = 0; | ||||
}else { | |||||
} | |||||
else { | |||||
cc[i].sync = absi(data2 - cc[i].val); | cc[i].sync = absi(data2 - cc[i].val); | ||||
} | } | ||||
return; | return; | ||||
@@ -156,7 +157,8 @@ void MIDICCToCVInterface::processMidi(std::vector<unsigned char> msg) { | |||||
if (cc[i].sync == 0) { | if (cc[i].sync == 0) { | ||||
cc[i].val = data2; | cc[i].val = data2; | ||||
cc[i].changed = true; | cc[i].changed = true; | ||||
} else { | |||||
} | |||||
else { | |||||
cc[i].sync = absi(data2 - cc[i].val); | cc[i].sync = absi(data2 - cc[i].val); | ||||
} | } | ||||
} | } | ||||
@@ -225,12 +227,14 @@ void CCTextField::onTextChange() { | |||||
text = ""; | text = ""; | ||||
begin = end = 0; | begin = end = 0; | ||||
module->cc[outNum].num = -1; | module->cc[outNum].num = -1; | ||||
} else { | |||||
} | |||||
else { | |||||
module->cc[outNum].num = num; | module->cc[outNum].num = num; | ||||
module->cc[outNum].resetSync(); | module->cc[outNum].resetSync(); | ||||
} | } | ||||
} catch (...) { | |||||
} | |||||
catch (...) { | |||||
text = ""; | text = ""; | ||||
begin = end = 0; | begin = end = 0; | ||||
module->cc[outNum].num = -1; | module->cc[outNum].num = -1; | ||||
@@ -309,7 +313,8 @@ MIDICCToCVWidget::MIDICCToCVWidget() { | |||||
if ((i + 1) % 4 == 0) { | if ((i + 1) % 4 == 0) { | ||||
yPos += 47 + margin; | yPos += 47 + margin; | ||||
} else { | |||||
} | |||||
else { | |||||
yPos -= labelHeight + margin; | yPos -= labelHeight + margin; | ||||
} | } | ||||
} | } | ||||
@@ -71,7 +71,7 @@ struct MIDIClockToCVInterface : MidiIO, Module { | |||||
void resetMidi() override; | void resetMidi() override; | ||||
json_t *toJson() override{ | |||||
json_t *toJson() override { | |||||
json_t *rootJ = json_object(); | json_t *rootJ = json_object(); | ||||
addBaseJson(rootJ); | addBaseJson(rootJ); | ||||
json_object_set_new(rootJ, "clock1ratio", json_integer(clock1ratio)); | json_object_set_new(rootJ, "clock1ratio", json_integer(clock1ratio)); | ||||
@@ -79,7 +79,7 @@ struct MIDIClockToCVInterface : MidiIO, Module { | |||||
return rootJ; | return rootJ; | ||||
} | } | ||||
void fromJson(json_t *rootJ) override{ | |||||
void fromJson(json_t *rootJ) override { | |||||
baseFromJson(rootJ); | baseFromJson(rootJ); | ||||
json_t *c1rJ = json_object_get(rootJ, "clock1ratio"); | json_t *c1rJ = json_object_get(rootJ, "clock1ratio"); | ||||
if (c1rJ) { | if (c1rJ) { | ||||
@@ -185,18 +185,18 @@ void MIDIClockToCVInterface::resetMidi() { | |||||
void MIDIClockToCVInterface::processMidi(std::vector<unsigned char> msg) { | void MIDIClockToCVInterface::processMidi(std::vector<unsigned char> msg) { | ||||
switch (msg[0]) { | switch (msg[0]) { | ||||
case 0xfa: | |||||
start = true; | |||||
break; | |||||
case 0xfb: | |||||
cont = true; | |||||
break; | |||||
case 0xfc: | |||||
stop = true; | |||||
break; | |||||
case 0xf8: | |||||
tick = true; | |||||
break; | |||||
case 0xfa: | |||||
start = true; | |||||
break; | |||||
case 0xfb: | |||||
cont = true; | |||||
break; | |||||
case 0xfc: | |||||
stop = true; | |||||
break; | |||||
case 0xf8: | |||||
tick = true; | |||||
break; | |||||
} | } | ||||
@@ -218,13 +218,15 @@ struct ClockRatioItem : MenuItem { | |||||
struct ClockRatioChoice : ChoiceButton { | struct ClockRatioChoice : ChoiceButton { | ||||
int *clockRatio; | int *clockRatio; | ||||
const std::vector<std::string> ratioNames = {"Sixteenth note (1:4 ratio)", "Eighth note triplet (1:3 ratio)", | const std::vector<std::string> ratioNames = {"Sixteenth note (1:4 ratio)", "Eighth note triplet (1:3 ratio)", | ||||
"Eighth note (1:2 ratio)", "Quarter note triplet (2:3 ratio)", | |||||
"Quarter note (tap speed)", "Half note triplet (4:3 ratio)", | |||||
"Half note (2:1 ratio)", "Whole note (4:1 ratio)", | |||||
"Two whole notes (8:1 ratio)"}; | |||||
"Eighth note (1:2 ratio)", "Quarter note triplet (2:3 ratio)", | |||||
"Quarter note (tap speed)", "Half note triplet (4:3 ratio)", | |||||
"Half note (2:1 ratio)", "Whole note (4:1 ratio)", | |||||
"Two whole notes (8:1 ratio)" | |||||
}; | |||||
const std::vector<std::string> ratioNames_short = {"1:4 ratio", "1:3 ratio", "1:2 ratio", "2:3 ratio", "1:1 ratio", | const std::vector<std::string> ratioNames_short = {"1:4 ratio", "1:3 ratio", "1:2 ratio", "2:3 ratio", "1:1 ratio", | ||||
"4:3", "2:1 ratio", "4:1 ratio", "8:1 ratio"}; | |||||
"4:3", "2:1 ratio", "4:1 ratio", "8:1 ratio" | |||||
}; | |||||
void onAction(EventAction &e) override { | void onAction(EventAction &e) override { | ||||
Menu *menu = gScene->createMenu(); | Menu *menu = gScene->createMenu(); | ||||
@@ -270,7 +272,7 @@ MIDIClockToCVWidget::MIDIClockToCVWidget() { | |||||
label->box.pos = Vec(box.size.x - margin - 7 * 15, margin); | label->box.pos = Vec(box.size.x - margin - 7 * 15, margin); | ||||
label->text = "MIDI Clk-CV"; | label->text = "MIDI Clk-CV"; | ||||
addChild(label); | addChild(label); | ||||
yPos = labelHeight*2; | |||||
yPos = labelHeight * 2; | |||||
} | } | ||||
{ | { | ||||
@@ -320,8 +322,8 @@ MIDIClockToCVWidget::MIDIClockToCVWidget() { | |||||
addInput(createInput<PJ3410Port>(Vec(margin, yPos - 5), module, MIDIClockToCVInterface::CLOCK1_RATIO)); | addInput(createInput<PJ3410Port>(Vec(margin, yPos - 5), module, MIDIClockToCVInterface::CLOCK1_RATIO)); | ||||
ClockRatioChoice *ratioChoice = new ClockRatioChoice(); | ClockRatioChoice *ratioChoice = new ClockRatioChoice(); | ||||
ratioChoice->clockRatio = &module->clock1ratio; | ratioChoice->clockRatio = &module->clock1ratio; | ||||
ratioChoice->box.pos = Vec(int(box.size.x/3), yPos); | |||||
ratioChoice->box.size.x = int(box.size.x/1.5 - margin); | |||||
ratioChoice->box.pos = Vec(int(box.size.x / 3), yPos); | |||||
ratioChoice->box.size.x = int(box.size.x / 1.5 - margin); | |||||
addChild(ratioChoice); | addChild(ratioChoice); | ||||
yPos += ratioChoice->box.size.y + margin * 3; | yPos += ratioChoice->box.size.y + margin * 3; | ||||
@@ -344,8 +346,8 @@ MIDIClockToCVWidget::MIDIClockToCVWidget() { | |||||
addInput(createInput<PJ3410Port>(Vec(margin, yPos - 5), module, MIDIClockToCVInterface::CLOCK2_RATIO)); | addInput(createInput<PJ3410Port>(Vec(margin, yPos - 5), module, MIDIClockToCVInterface::CLOCK2_RATIO)); | ||||
ClockRatioChoice *ratioChoice = new ClockRatioChoice(); | ClockRatioChoice *ratioChoice = new ClockRatioChoice(); | ||||
ratioChoice->clockRatio = &module->clock2ratio; | ratioChoice->clockRatio = &module->clock2ratio; | ||||
ratioChoice->box.pos = Vec(int(box.size.x/3), yPos); | |||||
ratioChoice->box.size.x = int(box.size.x/1.5 - margin); | |||||
ratioChoice->box.pos = Vec(int(box.size.x / 3), yPos); | |||||
ratioChoice->box.size.x = int(box.size.x / 1.5 - margin); | |||||
addChild(ratioChoice); | addChild(ratioChoice); | ||||
yPos += ratioChoice->box.size.y + margin * 3; | yPos += ratioChoice->box.size.y + margin * 3; | ||||
@@ -59,7 +59,8 @@ std::vector<std::string> MidiIO::getDevices() { | |||||
RtMidiIn *m; | RtMidiIn *m; | ||||
try { | try { | ||||
m = new RtMidiIn(); | m = new RtMidiIn(); | ||||
} catch (RtMidiError &error) { | |||||
} | |||||
catch (RtMidiError &error) { | |||||
warn("Failed to create RtMidiIn: %s", error.getMessage().c_str()); | warn("Failed to create RtMidiIn: %s", error.getMessage().c_str()); | ||||
return names; | return names; | ||||
} | } | ||||
@@ -9,6 +9,7 @@ | |||||
using namespace rack; | using namespace rack; | ||||
struct IgnoreFlags { | struct IgnoreFlags { | ||||
bool midiSysex = true; | bool midiSysex = true; | ||||
bool midiTime = true; | bool midiTime = true; | ||||
@@ -20,7 +21,6 @@ struct MidiMessage { | |||||
double timeStamp; | double timeStamp; | ||||
MidiMessage() : bytes(0), timeStamp(0.0) {}; | MidiMessage() : bytes(0), timeStamp(0.0) {}; | ||||
}; | }; | ||||
/** | /** | ||||
@@ -135,10 +135,10 @@ struct TransitionSmoother { | |||||
switch (m) { | switch (m) { | ||||
case DELTA: | case DELTA: | ||||
/* If the change is smaller, the transition phase is longer */ | /* If the change is smaller, the transition phase is longer */ | ||||
this->step = delta > 0 ? delta/l : -delta/l; | |||||
this->step = delta > 0 ? delta / l : -delta / l; | |||||
break; | break; | ||||
case CONST: | case CONST: | ||||
this->step = 1.0/l; | |||||
this->step = 1.0 / l; | |||||
break; | break; | ||||
} | } | ||||
@@ -153,13 +153,13 @@ struct TransitionSmoother { | |||||
switch (t) { | switch (t) { | ||||
case SMOOTHSTEP: | case SMOOTHSTEP: | ||||
next += delta*x*x*(3-2*x); | |||||
next += delta * x * x * (3 - 2 * x); | |||||
break; | break; | ||||
case EXP: | case EXP: | ||||
next += delta*x*x; | |||||
next += delta * x * x; | |||||
break; | break; | ||||
case LIN: | case LIN: | ||||
next += delta*x; | |||||
next += delta * x; | |||||
break; | break; | ||||
} | } | ||||
@@ -169,10 +169,12 @@ void TriggerTextField::onTextChange() { | |||||
text = ""; | text = ""; | ||||
begin = end = 0; | begin = end = 0; | ||||
module->trigger[outNum].num = -1; | module->trigger[outNum].num = -1; | ||||
}else { | |||||
} | |||||
else { | |||||
module->trigger[outNum].num = num; | module->trigger[outNum].num = num; | ||||
} | } | ||||
} catch (...) { | |||||
} | |||||
catch (...) { | |||||
text = ""; | text = ""; | ||||
begin = end = 0; | begin = end = 0; | ||||
module->trigger[outNum].num = -1; | module->trigger[outNum].num = -1; | ||||
@@ -271,7 +273,8 @@ MIDITriggerToCVWidget::MIDITriggerToCVWidget() { | |||||
if ((i + 1) % 4 == 0) { | if ((i + 1) % 4 == 0) { | ||||
yPos += 47 + margin; | yPos += 47 + margin; | ||||
} else { | |||||
} | |||||
else { | |||||
yPos -= labelHeight + margin; | yPos -= labelHeight + margin; | ||||
} | } | ||||
} | } | ||||
@@ -140,40 +140,41 @@ void QuadMIDIToCVInterface::processMidi(std::vector<unsigned char> msg) { | |||||
return; | return; | ||||
switch (status) { | switch (status) { | ||||
// note off | |||||
case 0x8: { | |||||
// 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; | 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; | |||||
} | |||||
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) { | |||||
open.clear(); | |||||
for (int i = 0; i < 4; i++) { | |||||
activeKeys[i].gate = false; | |||||
open.push_back(i); | |||||
} | |||||
} | |||||
return; | |||||
case 0xb: // cc | |||||
if (data1 == 0x40) { // pedal | |||||
pedal = (data2 >= 64); | |||||
if (!pedal) { | |||||
open.clear(); | |||||
for (int i = 0; i < 4; i++) { | |||||
activeKeys[i].gate = false; | |||||
open.push_back(i); | |||||
} | } | ||||
} | } | ||||
return; | |||||
default: | |||||
return; | |||||
} | |||||
return; | |||||
default: | |||||
return; | |||||
} | } | ||||
if (pedal && !gate) { | if (pedal && !gate) { | ||||
@@ -201,25 +202,25 @@ void QuadMIDIToCVInterface::processMidi(std::vector<unsigned char> msg) { | |||||
} | } | ||||
if (!activeKeys[0].gate && !activeKeys[1].gate && | if (!activeKeys[0].gate && !activeKeys[1].gate && | ||||
!activeKeys[2].gate && !activeKeys[3].gate) { | |||||
!activeKeys[2].gate && !activeKeys[3].gate) { | |||||
open.sort(); | open.sort(); | ||||
} | } | ||||
switch (mode) { | switch (mode) { | ||||
case RESET: | |||||
if (open.size() >= 4) { | |||||
for (int i = 0; i < 4; i++) { | |||||
activeKeys[i].gate = false; | |||||
open.push_back(i); | |||||
} | |||||
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; | |||||
} | |||||
break; | |||||
case REASSIGN: | |||||
open.push_back(open.front()); | |||||
break; | |||||
case ROTATE: | |||||
break; | |||||
} | } | ||||
int next = open.front(); | int next = open.front(); | ||||
@@ -313,7 +314,7 @@ QuadMidiToCVWidget::QuadMidiToCVWidget() { | |||||
} | } | ||||
addParam(createParam<LEDButton>(Vec(12 * 15, labelHeight), module, QuadMIDIToCVInterface::RESET_PARAM, 0.0, 1.0, | addParam(createParam<LEDButton>(Vec(12 * 15, labelHeight), module, QuadMIDIToCVInterface::RESET_PARAM, 0.0, 1.0, | ||||
0.0)); | |||||
0.0)); | |||||
addChild(createLight<SmallLight<RedLight>>(Vec(12 * 15 + 5, labelHeight + 5), module, QuadMIDIToCVInterface::RESET_LIGHT)); | addChild(createLight<SmallLight<RedLight>>(Vec(12 * 15 + 5, labelHeight + 5), module, QuadMIDIToCVInterface::RESET_LIGHT)); | ||||
{ | { | ||||
Label *label = new Label(); | Label *label = new Label(); | ||||