Browse Source

Partial QuadMidiToCvInterface

tags/v0.6.0
Andrew Belt 7 years ago
parent
commit
eb7f5e0fc4
2 changed files with 215 additions and 60 deletions
  1. +32
    -26
      src/Core/MIDIToCVInterface.cpp
  2. +183
    -34
      src/Core/QuadMIDIToCVInterface.cpp

+ 32
- 26
src/Core/MIDIToCVInterface.cpp View File

@@ -6,12 +6,6 @@
#include <algorithm>


struct MidiNoteData {
uint8_t velocity = 0;
uint8_t aftertouch = 0;
};


struct MIDIToCVInterface : Module {
enum ParamIds {
NUM_PARAMS
@@ -49,25 +43,45 @@ struct MIDIToCVInterface : Module {
PulseGenerator continuePulse;
PulseGenerator clockPulse;

MidiNoteData noteData[128];
std::list<uint8_t> heldNotes;
struct NoteData {
uint8_t velocity = 0;
uint8_t aftertouch = 0;
};

NoteData noteData[128];
std::vector<uint8_t> heldNotes;
uint8_t lastNote;
bool pedal;
bool gate;

MIDIToCVInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
MIDIToCVInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS), heldNotes(128) {
onReset();
}

json_t *toJson() override {
json_t *rootJ = json_object();
json_object_set_new(rootJ, "midi", midiInput.toJson());
return rootJ;
}

void fromJson(json_t *rootJ) override {
json_t *midiJ = json_object_get(rootJ, "midi");
if (midiJ)
midiInput.fromJson(midiJ);
}

void onReset() override {
heldNotes.clear();
pedal = false;
lastNote = 60;
pedal = false;
gate = false;
}

void pressNote(uint8_t note) {
// Remove existing similar note
heldNotes.remove(note);
auto it = std::find(heldNotes.begin(), heldNotes.end(), note);
if (it != heldNotes.end())
heldNotes.erase(it);
// Push note
heldNotes.push_back(note);
lastNote = note;
@@ -76,15 +90,15 @@ struct MIDIToCVInterface : Module {

void releaseNote(uint8_t note) {
// Remove the note
heldNotes.remove(note);
auto it = std::find(heldNotes.begin(), heldNotes.end(), note);
if (it != heldNotes.end())
heldNotes.erase(it);
// Hold note if pedal is pressed
if (pedal)
return;
// Set last note
if (!heldNotes.empty()) {
auto it2 = heldNotes.end();
it2--;
lastNote = *it2;
lastNote = heldNotes[heldNotes.size() - 1];
gate = true;
}
else {
@@ -124,6 +138,9 @@ struct MIDIToCVInterface : Module {
outputs[CONTINUE_OUTPUT].value = continuePulse.process(deltaTime) ? 10.f : 0.f;

outputs[CLOCK_OUTPUT].value = clockPulse.process(deltaTime) ? 10.f : 0.f;
// TODO
outputs[CLOCK_2_OUTPUT].value = 0.f;
outputs[CLOCK_HALF_OUTPUT].value = 0.f;
}

void processMessage(MidiMessage msg) {
@@ -204,17 +221,6 @@ struct MIDIToCVInterface : Module {
default: break;
}
}

json_t *toJson() override {
json_t *rootJ = json_object();
json_object_set_new(rootJ, "midi", midiInput.toJson());
return rootJ;
}

void fromJson(json_t *rootJ) override {
json_t *midiJ = json_object_get(rootJ, "midi");
midiInput.fromJson(midiJ);
}
};




+ 183
- 34
src/Core/QuadMIDIToCVInterface.cpp View File

@@ -1,6 +1,8 @@
#include "Core.hpp"
#include "midi.hpp"

#include <algorithm>


struct QuadMIDIToCVInterface : Module {
enum ParamIds {
@@ -10,22 +12,10 @@ struct QuadMIDIToCVInterface : Module {
NUM_INPUTS
};
enum OutputIds {
RECT17025_OUTPUT,
RECT17027_OUTPUT,
RECT17029_OUTPUT,
RECT17031_OUTPUT,
RECT17033_OUTPUT,
RECT17035_OUTPUT,
RECT17037_OUTPUT,
RECT17039_OUTPUT,
RECT17041_OUTPUT,
RECT17043_OUTPUT,
RECT17045_OUTPUT,
RECT17047_OUTPUT,
RECT17049_OUTPUT,
RECT17051_OUTPUT,
RECT17053_OUTPUT,
RECT17055_OUTPUT,
ENUMS(CV_OUTPUT, 4),
ENUMS(GATE_OUTPUT, 4),
ENUMS(VELOCITY_OUTPUT, 4),
ENUMS(AFTERTOUCH_OUTPUT, 4),
NUM_OUTPUTS
};
enum LightIds {
@@ -34,9 +24,168 @@ struct QuadMIDIToCVInterface : Module {

MidiInputQueue midiInput;

QuadMIDIToCVInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
enum PolyMode {
ROTATE_MODE,
RESET_MODE,
REASSIGN_MODE,
UNISON_MODE,
NUM_MODES
};
PolyMode polyMode = ROTATE_MODE;

struct NoteData {
uint8_t velocity = 0;
uint8_t aftertouch = 0;
};

NoteData noteData[128];
std::vector<uint8_t> heldNotes;
uint8_t notes[4];
bool gates[4];
bool pedal;

QuadMIDIToCVInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS), heldNotes(128) {
onReset();
}

json_t *toJson() override {
json_t *rootJ = json_object();
json_object_set_new(rootJ, "midi", midiInput.toJson());
json_object_set_new(rootJ, "polyMode", json_integer(polyMode));
return rootJ;
}

void fromJson(json_t *rootJ) override {
json_t *midiJ = json_object_get(rootJ, "midi");
if (midiJ)
midiInput.fromJson(midiJ);

json_t *polyModeJ = json_object_get(rootJ, "polyMode");
if (polyModeJ)
polyMode = (PolyMode) json_integer_value(polyModeJ);
}

void onReset() override {
for (int i = 0; i < 4; i++) {
notes[i] = 60;
gates[i] = false;
}
pedal = false;
}

void pressNote(uint8_t note) {
// Remove existing similar note
auto it = std::find(heldNotes.begin(), heldNotes.end(), note);
if (it != heldNotes.end())
heldNotes.erase(it);
// Push note
heldNotes.push_back(note);

// Set notes and gates
switch (polyMode) {
case ROTATE_MODE: {

} break;
case RESET_MODE: {

void step() override {}
} break;
case REASSIGN_MODE: {

} break;
case UNISON_MODE: {

} break;
default: break;
}
}

void releaseNote(uint8_t note) {
// Remove the note
auto it = std::find(heldNotes.begin(), heldNotes.end(), note);
if (it != heldNotes.end())
heldNotes.erase(it);
// Hold note if pedal is pressed
// if (pedal)
// return;
// // Set last note
// if (!heldNotes.empty()) {
// auto it2 = heldNotes.end();
// it2--;
// lastNote = *it2;
// gate = true;
// }
// else {
// gate = false;
// }
}

void pressPedal() {
pedal = true;
}

void releasePedal() {
pedal = false;
releaseNote(255);
}

void step() override {
MidiMessage msg;
while (midiInput.shift(&msg)) {
processMessage(msg);
}

for (int i = 0; i < 4; i++) {
uint8_t lastNote = notes[i];
outputs[CV_OUTPUT + i].value = (lastNote - 60) / 12.f;
outputs[GATE_OUTPUT + i].value = gates[i] ? 10.f : 0.f;
outputs[VELOCITY_OUTPUT + i].value = rescale(noteData[lastNote].velocity, 0, 127, 0.f, 10.f);
outputs[VELOCITY_OUTPUT + i].value = rescale(noteData[lastNote].aftertouch, 0, 127, 0.f, 10.f);
}
}

void processMessage(MidiMessage msg) {
switch (msg.status()) {
// note off
case 0x8: {
// releaseNote(msg.data1);
} break;
// note on
case 0x9: {
if (msg.data2 > 0) {
uint8_t note = msg.data1 & 0x7f;
noteData[note].velocity = msg.data2;
// pressNote(msg.data1);
}
else {
// For some reason, some keyboards send a "note on" event with a velocity of 0 to signal that the key has been released.
// releaseNote(msg.data1);
}
} break;
// channel aftertouch
case 0xa: {
uint8_t note = msg.data1 & 0x7f;
noteData[note].aftertouch = msg.data2;
} break;
// cc
case 0xb: {
processCC(msg);
} break;
default: break;
}
}

void processCC(MidiMessage msg) {
switch (msg.data1) {
// sustain
case 0x40: {
if (msg.data2 >= 64)
pressPedal();
else
releasePedal();
} break;
default: break;
}
}
};


@@ -49,22 +198,22 @@ struct QuadMIDIToCVInterfaceWidget : ModuleWidget {
addChild(Widget::create<ScrewSilver>(Vec(RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
addChild(Widget::create<ScrewSilver>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));

addOutput(Port::create<PJ301MPort>(mm2px(Vec(3.894335, 60.144478)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17025_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(15.494659, 60.144478)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17027_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(27.094986, 60.144478)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17029_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(38.693935, 60.144478)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17031_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(3.894335, 76.144882)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17033_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(15.494659, 76.144882)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17035_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(27.094986, 76.144882)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17037_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(38.693935, 76.144882)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17039_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(3.894335, 92.143906)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17041_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(15.494659, 92.143906)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17043_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(27.094986, 92.143906)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17045_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(38.693935, 92.143906)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17047_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(3.894335, 108.1443)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17049_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(15.494659, 108.1443)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17051_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(27.094986, 108.1443)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17053_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(38.693935, 108.1443)), Port::OUTPUT, module, QuadMIDIToCVInterface::RECT17055_OUTPUT));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(3.894335, 60.144478)), Port::OUTPUT, module, QuadMIDIToCVInterface::CV_OUTPUT + 0));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(15.494659, 60.144478)), Port::OUTPUT, module, QuadMIDIToCVInterface::GATE_OUTPUT + 0));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(27.094986, 60.144478)), Port::OUTPUT, module, QuadMIDIToCVInterface::VELOCITY_OUTPUT + 0));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(38.693935, 60.144478)), Port::OUTPUT, module, QuadMIDIToCVInterface::AFTERTOUCH_OUTPUT + 0));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(3.894335, 76.144882)), Port::OUTPUT, module, QuadMIDIToCVInterface::CV_OUTPUT + 1));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(15.494659, 76.144882)), Port::OUTPUT, module, QuadMIDIToCVInterface::GATE_OUTPUT + 1));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(27.094986, 76.144882)), Port::OUTPUT, module, QuadMIDIToCVInterface::VELOCITY_OUTPUT + 1));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(38.693935, 76.144882)), Port::OUTPUT, module, QuadMIDIToCVInterface::AFTERTOUCH_OUTPUT + 1));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(3.894335, 92.143906)), Port::OUTPUT, module, QuadMIDIToCVInterface::CV_OUTPUT + 2));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(15.494659, 92.143906)), Port::OUTPUT, module, QuadMIDIToCVInterface::GATE_OUTPUT + 2));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(27.094986, 92.143906)), Port::OUTPUT, module, QuadMIDIToCVInterface::VELOCITY_OUTPUT + 2));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(38.693935, 92.143906)), Port::OUTPUT, module, QuadMIDIToCVInterface::AFTERTOUCH_OUTPUT + 2));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(3.894335, 108.1443)), Port::OUTPUT, module, QuadMIDIToCVInterface::CV_OUTPUT + 3));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(15.494659, 108.1443)), Port::OUTPUT, module, QuadMIDIToCVInterface::GATE_OUTPUT + 3));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(27.094986, 108.1443)), Port::OUTPUT, module, QuadMIDIToCVInterface::VELOCITY_OUTPUT + 3));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(38.693935, 108.1443)), Port::OUTPUT, module, QuadMIDIToCVInterface::AFTERTOUCH_OUTPUT + 3));

MidiWidget *midiWidget = Widget::create<MidiWidget>(mm2px(Vec(3.4009969, 14.837336)));
midiWidget->box.size = mm2px(Vec(44, 28));


Loading…
Cancel
Save