Browse Source

Add CC learning to MIDI-Map.

tags/v1.0.0
Andrew Belt 6 years ago
parent
commit
8bfa81c850
4 changed files with 120 additions and 38 deletions
  1. +15
    -11
      src/Core/MIDI_CC.cpp
  2. +25
    -25
      src/Core/MIDI_Gate.cpp
  3. +77
    -2
      src/Core/MIDI_Map.cpp
  4. +3
    -0
      src/Core/plugin.hpp

+ 15
- 11
src/Core/MIDI_CC.cpp View File

@@ -18,8 +18,8 @@ struct MIDI_CC : Module {

midi::InputQueue midiInput;
int8_t values[128];
int learningId = -1;
int learnedCcs[16] = {};
int learningId;
int learnedCcs[16];
dsp::ExponentialFilter valueFilters[16];
int8_t lastValues[16] = {};

@@ -76,20 +76,24 @@ struct MIDI_CC : Module {
switch (msg.getStatus()) {
// cc
case 0xb: {
uint8_t cc = msg.getNote();
// Learn
if (learningId >= 0 && values[cc] != msg.data2) {
learnedCcs[learningId] = cc;
learningId = -1;
}
// Allow CC to be negative if the 8th bit is set.
// The gamepad driver abuses this, for example.
values[cc] = msg.data2;
processCC(msg);
} break;
default: break;
}
}

void processCC(midi::Message msg) {
uint8_t cc = msg.getNote();
// Learn
if (learningId >= 0 && values[cc] != msg.data2) {
learnedCcs[learningId] = cc;
learningId = -1;
}
// Allow CC to be negative if the 8th bit is set.
// The gamepad driver abuses this, for example.
values[cc] = msg.data2;
}

json_t *dataToJson() override {
json_t *rootJ = json_object();



+ 25
- 25
src/Core/MIDI_Gate.cpp View File

@@ -46,31 +46,6 @@ struct MIDI_Gate : Module {
}
}

void pressNote(uint8_t note, uint8_t vel) {
// Learn
if (learningId >= 0) {
learnedNotes[learningId] = note;
learningId = -1;
}
// Find id
for (int i = 0; i < 16; i++) {
if (learnedNotes[i] == note) {
gates[i] = true;
gateTimes[i] = 1e-3f;
velocities[i] = vel;
}
}
}

void releaseNote(uint8_t note) {
// Find id
for (int i = 0; i < 16; i++) {
if (learnedNotes[i] == note) {
gates[i] = false;
}
}
}

void step() override {
midi::Message msg;
while (midiInput.shift(&msg)) {
@@ -113,6 +88,31 @@ struct MIDI_Gate : Module {
}
}

void pressNote(uint8_t note, uint8_t vel) {
// Learn
if (learningId >= 0) {
learnedNotes[learningId] = note;
learningId = -1;
}
// Find id
for (int i = 0; i < 16; i++) {
if (learnedNotes[i] == note) {
gates[i] = true;
gateTimes[i] = 1e-3f;
velocities[i] = vel;
}
}
}

void releaseNote(uint8_t note) {
// Find id
for (int i = 0; i < 16; i++) {
if (learnedNotes[i] == note) {
gates[i] = false;
}
}
}

json_t *dataToJson() override {
json_t *rootJ = json_object();



+ 77
- 2
src/Core/MIDI_Map.cpp View File

@@ -17,8 +17,9 @@ struct MIDI_Map : Module {

midi::InputQueue midiInput;
int8_t values[128];
int learningId = -1;
int learnedCcs[16] = {};
int learningId;
int lastLearnedCc;
int learnedCcs[8];
dsp::ExponentialFilter valueFilters[8];

MIDI_Map() {
@@ -27,10 +28,71 @@ struct MIDI_Map : Module {
}

void onReset() override {
learningId = -1;
lastLearnedCc = -1;
for (int i = 0; i < 8; i++) {
learnedCcs[i] = -1;
}
midiInput.reset();
}

void step() override {
midi::Message msg;
while (midiInput.shift(&msg)) {
processMessage(msg);
}
}

void processMessage(midi::Message msg) {
switch (msg.getStatus()) {
// cc
case 0xb: {
processCC(msg);
} break;
default: break;
}
}

void processCC(midi::Message msg) {
uint8_t cc = msg.getNote();
// Learn
if (learningId >= 0 && values[cc] != msg.data2) {
if (lastLearnedCc != cc) {
learnedCcs[learningId] = cc;
lastLearnedCc = cc;
if (++learningId >= 8)
learningId = -1;
}
}
values[cc] = msg.getValue();
}

json_t *dataToJson() override {
json_t *rootJ = json_object();

json_t *ccsJ = json_array();
for (int i = 0; i < 8; i++) {
json_array_append_new(ccsJ, json_integer(learnedCcs[i]));
}
json_object_set_new(rootJ, "ccs", ccsJ);

json_object_set_new(rootJ, "midi", midiInput.toJson());
return rootJ;
}

void dataFromJson(json_t *rootJ) override {
json_t *ccsJ = json_object_get(rootJ, "ccs");
if (ccsJ) {
for (int i = 0; i < 8; i++) {
json_t *ccJ = json_array_get(ccsJ, i);
if (ccJ)
learnedCcs[i] = json_integer_value(ccJ);
}
}

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

@@ -66,11 +128,24 @@ struct MIDI_MapChoice : LedDisplayChoice {
color.a = 1.0;
bgColor = color;
bgColor.a = 0.15;

// HACK
if (APP->event->selectedWidget != this)
APP->event->setSelected(this);
}
else if (module->learnedCcs[id] >= 0) {
text = string::f("CC%d", module->learnedCcs[id]);
color.a = 1.0;
bgColor = nvgRGBA(0, 0, 0, 0);
}
else {
text = "Unmapped";
color.a = 0.5;
bgColor = nvgRGBA(0, 0, 0, 0);

// HACK
if (APP->event->selectedWidget == this)
APP->event->setSelected(NULL);
}
}
};


+ 3
- 0
src/Core/plugin.hpp View File

@@ -87,6 +87,8 @@ struct CcChoice : LedDisplayChoice {
else {
text = string::f("%d", module->learnedCcs[id]);
color.a = 1.0;

// HACK
if (APP->event->selectedWidget == this)
APP->event->setSelected(NULL);
}
@@ -170,6 +172,7 @@ struct NoteChoice : LedDisplayChoice {
text = string::f("%s%d", noteNames[semi], oct);
color.a = 1.0;

// HACK
if (APP->event->selectedWidget == this)
APP->event->setSelected(NULL);
}


Loading…
Cancel
Save