Browse Source

Finish MIDI-TRIG and MIDI-CC?

tags/v0.6.0
Andrew Belt 7 years ago
parent
commit
0e9a5b692f
4 changed files with 201 additions and 124 deletions
  1. +51
    -0
      src/Core/Core.hpp
  2. +74
    -57
      src/Core/MIDICCToCVInterface.cpp
  3. +76
    -66
      src/Core/MIDITriggerToCVInterface.cpp
  4. +0
    -1
      src/ui/TextField.cpp

+ 51
- 0
src/Core/Core.hpp View File

@@ -11,3 +11,54 @@ extern Model *modelMIDICCToCVInterface;
extern Model *modelMIDITriggerToCVInterface;
extern Model *modelBlank;
extern Model *modelNotes;



struct GridChoice : LedDisplayChoice {
virtual void setId(int id) {}
};


struct Grid16MidiWidget : MidiWidget {
LedDisplaySeparator *hSeparators[4];
LedDisplaySeparator *vSeparators[4];
GridChoice *gridChoices[4][4];

void createGridChoices() {
Vec pos = channelChoice->box.getBottomLeft();
for (int x = 1; x < 4; x++) {
vSeparators[x] = Widget::create<LedDisplaySeparator>(pos);
addChild(vSeparators[x]);
}
for (int y = 0; y < 4; y++) {
hSeparators[y] = Widget::create<LedDisplaySeparator>(pos);
addChild(hSeparators[y]);
for (int x = 0; x < 4; x++) {
GridChoice *gridChoice = createGridChoice();
assert(gridChoice);
gridChoice->box.pos = pos;
gridChoice->setId(4*y + x);
gridChoices[x][y] = gridChoice;
addChild(gridChoice);
}
pos = gridChoices[0][y]->box.getBottomLeft();
}
for (int x = 1; x < 4; x++) {
vSeparators[x]->box.size.y = pos.y - vSeparators[x]->box.pos.y;
}
}
void step() override {
MidiWidget::step();
for (int x = 1; x < 4; x++) {
vSeparators[x]->box.pos.x = box.size.x / 4 * x;
}
for (int y = 0; y < 4; y++) {
hSeparators[y]->box.size.x = box.size.x;
for (int x = 0; x < 4; x++) {
gridChoices[x][y]->box.size.x = box.size.x / 4;
gridChoices[x][y]->box.pos.x = box.size.x / 4 * x;
}
}
}
virtual GridChoice *createGridChoice() {return NULL;}
};

+ 74
- 57
src/Core/MIDICCToCVInterface.cpp View File

@@ -3,57 +3,6 @@
#include "dsp/filter.hpp"



struct CcChoice : LedDisplayChoice {
CcChoice() {
box.size.y = mm2px(6.666);
textOffset.y -= 4;
}
};


struct CcMidiWidget : MidiWidget {
LedDisplaySeparator *hSeparators[4];
LedDisplaySeparator *vSeparators[4];
LedDisplayChoice *ccChoices[4][4];

CcMidiWidget() {
Vec pos = channelChoice->box.getBottomLeft();
for (int x = 1; x < 4; x++) {
vSeparators[x] = Widget::create<LedDisplaySeparator>(pos);
addChild(vSeparators[x]);
}
for (int y = 0; y < 4; y++) {
hSeparators[y] = Widget::create<LedDisplaySeparator>(pos);
addChild(hSeparators[y]);
for (int x = 0; x < 4; x++) {
CcChoice *ccChoice = Widget::create<CcChoice>(pos);
ccChoice->text = stringf("%d", x*4+y);
ccChoices[x][y] = ccChoice;
addChild(ccChoice);
}
pos = ccChoices[0][y]->box.getBottomLeft();
}
for (int x = 1; x < 4; x++) {
vSeparators[x]->box.size.y = pos.y - vSeparators[x]->box.pos.y;
}
}
void step() override {
MidiWidget::step();
for (int x = 1; x < 4; x++) {
vSeparators[x]->box.pos.x = box.size.x / 4 * x;
}
for (int y = 0; y < 4; y++) {
hSeparators[y]->box.size.x = box.size.x;
for (int x = 0; x < 4; x++) {
ccChoices[x][y]->box.size.x = box.size.x / 4;
ccChoices[x][y]->box.pos.x = box.size.x / 4 * x;
}
}
}
};


struct MIDICCToCVInterface : Module {
enum ParamIds {
NUM_PARAMS
@@ -70,10 +19,23 @@ struct MIDICCToCVInterface : Module {
};

MidiInputQueue midiInput;
uint8_t cvs[128] = {};
uint8_t cvs[16];
ExponentialFilter ccFilters[16];

MIDICCToCVInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
int learningId = -1;
uint8_t learnedCcs[16] = {};

MIDICCToCVInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
onReset();
}

void onReset() override {
for (int i = 0; i < 16; i++) {
cvs[i] = 0;
learnedCcs[i] = i;
}
learningId = -1;
}

void step() override {
MidiMessage msg;
@@ -90,11 +52,20 @@ struct MIDICCToCVInterface : Module {
}

void processMessage(MidiMessage msg) {
debug("MIDI: %01x %01x %02x %02x", msg.status(), msg.channel(), msg.data1, msg.data2);
switch (msg.status()) {
// cc
case 0xb: {
cvs[msg.note()] = msg.value();
uint8_t cc = msg.note();
// Learn
if (learningId >= 0) {
learnedCcs[learningId] = cc;
}
// Set CV
for (int i = 0; i < 16; i++) {
if (learnedCcs[i] == cc) {
cvs[i] = msg.value();
}
}
} break;
default: break;
}
@@ -113,6 +84,51 @@ struct MIDICCToCVInterface : Module {
};


struct MidiCcChoice : GridChoice {
MIDICCToCVInterface *module;
int id;

MidiCcChoice() {
box.size.y = mm2px(6.666);
textOffset.y -= 4;
}

void setId(int id) override {
this->id = id;
}

void step() override {
if (module->learningId == id) {
text = "LRN";
color.a = 0.5;
}
else {
text = stringf("%d", id);
color.a = 1.0;
}
}

void onFocus(EventFocus &e) override {
e.consumed = true;
module->learningId = id;
}

void onDefocus(EventDefocus &e) override {
module->learningId = -1;
}
};


struct MidiCcWidget : Grid16MidiWidget {
MIDICCToCVInterface *module;
GridChoice *createGridChoice() override {
MidiCcChoice *gridChoice = new MidiCcChoice();
gridChoice->module = module;
return gridChoice;
}
};


struct MIDICCToCVInterfaceWidget : ModuleWidget {
MIDICCToCVInterfaceWidget(MIDICCToCVInterface *module) : ModuleWidget(module) {
setPanel(SVG::load(assetGlobal("res/Core/MIDICCToCVInterface.svg")));
@@ -139,11 +155,12 @@ struct MIDICCToCVInterfaceWidget : ModuleWidget {
addOutput(Port::create<PJ301MPort>(mm2px(Vec(27.09498, 108.14429)), Port::OUTPUT, module, MIDICCToCVInterface::CC_OUTPUT + 14));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(38.693932, 108.14429)), Port::OUTPUT, module, MIDICCToCVInterface::CC_OUTPUT + 15));

MidiWidget *midiWidget = Widget::create<CcMidiWidget>(mm2px(Vec(3.399621, 14.837339)));
MidiCcWidget *midiWidget = Widget::create<MidiCcWidget>(mm2px(Vec(3.399621, 14.837339)));
midiWidget->module = module;
midiWidget->box.size = mm2px(Vec(44, 54.667));
midiWidget->midiIO = &module->midiInput;
midiWidget->createGridChoices();
addChild(midiWidget);

}
};



+ 76
- 66
src/Core/MIDITriggerToCVInterface.cpp View File

@@ -1,57 +1,5 @@
#include "Core.hpp"
#include "midi.hpp"
#include "dsp/filter.hpp"



struct CcChoice : LedDisplayChoice {
CcChoice() {
box.size.y = mm2px(6.666);
textOffset.y -= 4;
}
};


struct CcMidiWidget : MidiWidget {
LedDisplaySeparator *hSeparators[4];
LedDisplaySeparator *vSeparators[4];
LedDisplayChoice *ccChoices[4][4];

CcMidiWidget() {
Vec pos = channelChoice->box.getBottomLeft();
for (int x = 1; x < 4; x++) {
vSeparators[x] = Widget::create<LedDisplaySeparator>(pos);
addChild(vSeparators[x]);
}
for (int y = 0; y < 4; y++) {
hSeparators[y] = Widget::create<LedDisplaySeparator>(pos);
addChild(hSeparators[y]);
for (int x = 0; x < 4; x++) {
CcChoice *ccChoice = Widget::create<CcChoice>(pos);
ccChoice->text = stringf("%d", x*4+y);
ccChoices[x][y] = ccChoice;
addChild(ccChoice);
}
pos = ccChoices[0][y]->box.getBottomLeft();
}
for (int x = 1; x < 4; x++) {
vSeparators[x]->box.size.y = pos.y - vSeparators[x]->box.pos.y;
}
}
void step() override {
MidiWidget::step();
for (int x = 1; x < 4; x++) {
vSeparators[x]->box.pos.x = box.size.x / 4 * x;
}
for (int y = 0; y < 4; y++) {
hSeparators[y]->box.size.x = box.size.x;
for (int x = 0; x < 4; x++) {
ccChoices[x][y]->box.size.x = box.size.x / 4;
ccChoices[x][y]->box.pos.x = box.size.x / 4 * x;
}
}
}
};


struct MIDITriggerToCVInterface : Module {
@@ -73,6 +21,8 @@ struct MIDITriggerToCVInterface : Module {

bool gates[16];
float gateTimes[16];
int learningId = -1;
uint8_t learnedNotes[16] = {};

MIDITriggerToCVInterface() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
onReset();
@@ -82,26 +32,32 @@ struct MIDITriggerToCVInterface : Module {
for (int i = 0; i < 16; i++) {
gates[i] = false;
gateTimes[i] = 0.f;
learnedNotes[i] = i + 36;
}
learningId = -1;
}

void pressNote(uint8_t note) {
// TEMP
if (note >= 16)
return;
int i = note;

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

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

void step() override {
@@ -158,6 +114,58 @@ struct MIDITriggerToCVInterface : Module {
};


struct MidiTrigChoice : GridChoice {
MIDITriggerToCVInterface *module;
int id;

MidiTrigChoice() {
box.size.y = mm2px(6.666);
textOffset.y -= 4;
textOffset.x -= 4;
}

void setId(int id) override {
this->id = id;
}

void step() override {
if (module->learningId == id) {
text = "LRN";
color.a = 0.5;
}
else {
uint8_t note = module->learnedNotes[id];
static const char *noteNames[] = {
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
};
int oct = note / 12 - 1;
int semi = note % 12;
text = stringf("%s%d", noteNames[semi], oct);
color.a = 1.0;
}
}

void onFocus(EventFocus &e) override {
e.consumed = true;
module->learningId = id;
}

void onDefocus(EventDefocus &e) override {
module->learningId = -1;
}
};


struct MidiTrigWidget : Grid16MidiWidget {
MIDITriggerToCVInterface *module;
GridChoice *createGridChoice() override {
MidiTrigChoice *gridChoice = new MidiTrigChoice();
gridChoice->module = module;
return gridChoice;
}
};


struct MIDITriggerToCVInterfaceWidget : ModuleWidget {
MIDITriggerToCVInterfaceWidget(MIDITriggerToCVInterface *module) : ModuleWidget(module) {
setPanel(SVG::load(assetGlobal("res/Core/MIDITriggerToCVInterface.svg")));
@@ -184,9 +192,11 @@ struct MIDITriggerToCVInterfaceWidget : ModuleWidget {
addOutput(Port::create<PJ301MPort>(mm2px(Vec(27.09498, 108.14429)), Port::OUTPUT, module, MIDITriggerToCVInterface::TRIG_OUTPUT + 14));
addOutput(Port::create<PJ301MPort>(mm2px(Vec(38.693932, 108.14429)), Port::OUTPUT, module, MIDITriggerToCVInterface::TRIG_OUTPUT + 15));

MidiWidget *midiWidget = Widget::create<CcMidiWidget>(mm2px(Vec(3.399621, 14.837339)));
MidiTrigWidget *midiWidget = Widget::create<MidiTrigWidget>(mm2px(Vec(3.399621, 14.837339)));
midiWidget->module = module;
midiWidget->box.size = mm2px(Vec(44, 54.667));
midiWidget->midiIO = &module->midiInput;
midiWidget->createGridChoices();
addChild(midiWidget);

}


+ 0
- 1
src/ui/TextField.cpp View File

@@ -31,7 +31,6 @@ void TextField::draw(NVGcontext *vg) {
}

void TextField::onMouseDown(EventMouseDown &e) {
debug("%d", this == gFocusedWidget);
if (e.button == 0) {
cursor = selection = getTextPosition(e.pos);
}


Loading…
Cancel
Save