Browse Source

Make Gate_MIDI notes unique (meaning only one cell can use a particular note). Use Schmitt trigger for Gate_MIDI inputs.

tags/v2.1.0
Andrew Belt 3 years ago
parent
commit
ebda3472fb
4 changed files with 53 additions and 34 deletions
  1. +5
    -5
      src/core/CV_MIDICC.cpp
  2. +38
    -23
      src/core/Gate_MIDI.cpp
  3. +7
    -3
      src/core/MIDI_Gate.cpp
  4. +3
    -3
      src/core/plugin.hpp

+ 5
- 5
src/core/CV_MIDICC.cpp View File

@@ -6,21 +6,21 @@ namespace core {




struct CCMidiOutput : midi::Output { struct CCMidiOutput : midi::Output {
int lastValues[128];
double frame = 0.0;
uint8_t lastValues[128];
int64_t frame = -1;


CCMidiOutput() { CCMidiOutput() {
reset(); reset();
} }


void reset() { void reset() {
for (int n = 0; n < 128; n++) {
for (uint8_t n = 0; n < 128; n++) {
lastValues[n] = -1; lastValues[n] = -1;
} }
Output::reset(); Output::reset();
} }


void setValue(int value, int cc) {
void setValue(uint8_t value, uint8_t cc) {
if (value == lastValues[cc]) if (value == lastValues[cc])
return; return;
lastValues[cc] = value; lastValues[cc] = value;
@@ -33,7 +33,7 @@ struct CCMidiOutput : midi::Output {
sendMessage(m); sendMessage(m);
} }


void setFrame(double frame) {
void setFrame(int64_t frame) {
this->frame = frame; this->frame = frame;
} }
}; };


+ 38
- 23
src/core/Gate_MIDI.cpp View File

@@ -6,16 +6,16 @@ namespace core {




struct GateMidiOutput : midi::Output { struct GateMidiOutput : midi::Output {
int vels[128];
uint8_t vels[128];
bool lastGates[128]; bool lastGates[128];
double frame = 0.0;
int64_t frame = -1;


GateMidiOutput() { GateMidiOutput() {
reset(); reset();
} }


void reset() { void reset() {
for (int note = 0; note < 128; note++) {
for (uint8_t note = 0; note < 128; note++) {
vels[note] = 100; vels[note] = 100;
lastGates[note] = false; lastGates[note] = false;
} }
@@ -24,7 +24,7 @@ struct GateMidiOutput : midi::Output {


void panic() { void panic() {
// Send all note off commands // Send all note off commands
for (int note = 0; note < 128; note++) {
for (uint8_t note = 0; note < 128; note++) {
// Note off // Note off
midi::Message m; midi::Message m;
m.setStatus(0x8); m.setStatus(0x8);
@@ -36,11 +36,11 @@ struct GateMidiOutput : midi::Output {
} }
} }


void setVelocity(int vel, int note) {
void setVelocity(uint8_t note, uint8_t vel) {
vels[note] = vel; vels[note] = vel;
} }


void setGate(bool gate, int note) {
void setGate(uint8_t note, bool gate) {
if (gate && !lastGates[note]) { if (gate && !lastGates[note]) {
// Note on // Note on
midi::Message m; midi::Message m;
@@ -62,7 +62,7 @@ struct GateMidiOutput : midi::Output {
lastGates[note] = gate; lastGates[note] = gate;
} }


void setFrame(double frame) {
void setFrame(int64_t frame) {
this->frame = frame; this->frame = frame;
} }
}; };
@@ -86,12 +86,13 @@ struct Gate_MIDI : Module {
GateMidiOutput midiOutput; GateMidiOutput midiOutput;
bool velocityMode = false; bool velocityMode = false;
int learningId = -1; int learningId = -1;
uint8_t learnedNotes[16] = {};
int8_t learnedNotes[16] = {};
dsp::SchmittTrigger cellTriggers[16];


Gate_MIDI() { Gate_MIDI() {
config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS); config(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS);
for (int i = 0; i < 16; i++)
configInput(GATE_INPUTS + i, string::f("Cell %d", i + 1));
for (int id = 0; id < 16; id++)
configInput(GATE_INPUTS + id, string::f("Cell %d", id + 1));
onReset(); onReset();
} }


@@ -109,28 +110,42 @@ struct Gate_MIDI : Module {
void process(const ProcessArgs& args) override { void process(const ProcessArgs& args) override {
midiOutput.setFrame(args.frame); midiOutput.setFrame(args.frame);


for (int i = 0; i < 16; i++) {
int note = learnedNotes[i];
for (int id = 0; id < 16; id++) {
int8_t note = learnedNotes[id];
if (note < 0)
continue;

if (velocityMode) { if (velocityMode) {
int vel = (int) std::round(inputs[GATE_INPUTS + i].getVoltage() / 10.f * 127);
int8_t vel = (int8_t) clamp(std::round(inputs[GATE_INPUTS + id].getVoltage() / 10.f * 127), 0.f, 127.f);
vel = clamp(vel, 0, 127); vel = clamp(vel, 0, 127);
midiOutput.setVelocity(vel, note);
midiOutput.setGate(vel > 0, note);
midiOutput.setVelocity(note, vel);
midiOutput.setGate(note, vel > 0);
} }
else { else {
bool gate = inputs[GATE_INPUTS + i].getVoltage() >= 1.f;
midiOutput.setVelocity(100, note);
midiOutput.setGate(gate, note);
cellTriggers[id].process(inputs[GATE_INPUTS + id].getVoltage(), 0.1f, 2.f);
midiOutput.setVelocity(note, 100);
midiOutput.setGate(note, cellTriggers[id].isHigh());
}
}
}

void setLearnedNote(int id, int8_t note) {
// Unset IDs of similar note
if (note >= 0) {
for (int id = 0; id < 16; id++) {
if (learnedNotes[id] == note)
learnedNotes[id] = -1;
} }
} }
learnedNotes[id] = note;
} }


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


json_t* notesJ = json_array(); json_t* notesJ = json_array();
for (int i = 0; i < 16; i++) {
json_t* noteJ = json_integer(learnedNotes[i]);
for (int id = 0; id < 16; id++) {
json_t* noteJ = json_integer(learnedNotes[id]);
json_array_append_new(notesJ, noteJ); json_array_append_new(notesJ, noteJ);
} }
json_object_set_new(rootJ, "notes", notesJ); json_object_set_new(rootJ, "notes", notesJ);
@@ -144,10 +159,10 @@ struct Gate_MIDI : Module {
void dataFromJson(json_t* rootJ) override { void dataFromJson(json_t* rootJ) override {
json_t* notesJ = json_object_get(rootJ, "notes"); json_t* notesJ = json_object_get(rootJ, "notes");
if (notesJ) { if (notesJ) {
for (int i = 0; i < 16; i++) {
json_t* noteJ = json_array_get(notesJ, i);
for (int id = 0; id < 16; id++) {
json_t* noteJ = json_array_get(notesJ, id);
if (noteJ) if (noteJ)
learnedNotes[i] = json_integer_value(noteJ);
setLearnedNote(id, json_integer_value(noteJ));
} }
} }




+ 7
- 3
src/core/MIDI_Gate.cpp View File

@@ -31,7 +31,7 @@ struct MIDI_Gate : Module {
/** Cell ID in learn mode, or -1 if none. */ /** Cell ID in learn mode, or -1 if none. */
int learningId; int learningId;
/** [cell] */ /** [cell] */
uint8_t learnedNotes[16];
int8_t learnedNotes[16];
bool velocityMode; bool velocityMode;
bool mpeMode; bool mpeMode;


@@ -113,7 +113,7 @@ struct MIDI_Gate : Module {
int c = mpeMode ? channel : 0; int c = mpeMode ? channel : 0;
// Learn // Learn
if (learningId >= 0) { if (learningId >= 0) {
learnedNotes[learningId] = note;
setLearnedNote(learningId, note);
learningId = -1; learningId = -1;
} }
// Find id // Find id
@@ -136,6 +136,10 @@ struct MIDI_Gate : Module {
} }
} }


void setLearnedNote(int id, int8_t note) {
learnedNotes[id] = note;
}

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


@@ -160,7 +164,7 @@ struct MIDI_Gate : Module {
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
json_t* noteJ = json_array_get(notesJ, i); json_t* noteJ = json_array_get(notesJ, i);
if (noteJ) if (noteJ)
learnedNotes[i] = json_integer_value(noteJ);
setLearnedNote(i, json_integer_value(noteJ));
} }
} }




+ 3
- 3
src/core/plugin.hpp View File

@@ -147,7 +147,7 @@ template <class TModule>
struct NoteChoice : LedDisplayChoice { struct NoteChoice : LedDisplayChoice {
TModule* module; TModule* module;
int id; int id;
int focusNote;
uint8_t focusNote;


NoteChoice() { NoteChoice() {
box.size.y = mm2px(6.666); box.size.y = mm2px(6.666);
@@ -164,7 +164,7 @@ struct NoteChoice : LedDisplayChoice {
} }


void step() override { void step() override {
int note;
int8_t note;
if (!module) { if (!module) {
note = id + 36; note = id + 36;
} }
@@ -206,7 +206,7 @@ struct NoteChoice : LedDisplayChoice {
return; return;
if (module->learningId == id) { if (module->learningId == id) {
if (0 <= focusNote && focusNote < 128) { if (0 <= focusNote && focusNote < 128) {
module->learnedNotes[id] = focusNote;
module->setLearnedNote(id, focusNote);
} }
module->learningId = -1; module->learningId = -1;
} }


Loading…
Cancel
Save