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 2 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 {
int lastValues[128];
double frame = 0.0;
uint8_t lastValues[128];
int64_t frame = -1;

CCMidiOutput() {
reset();
}

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

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

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


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

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


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

GateMidiOutput() {
reset();
}

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

void panic() {
// Send all note off commands
for (int note = 0; note < 128; note++) {
for (uint8_t note = 0; note < 128; note++) {
// Note off
midi::Message m;
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;
}

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

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

Gate_MIDI() {
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();
}

@@ -109,28 +110,42 @@ struct Gate_MIDI : Module {
void process(const ProcessArgs& args) override {
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) {
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);
midiOutput.setVelocity(vel, note);
midiOutput.setGate(vel > 0, note);
midiOutput.setVelocity(note, vel);
midiOutput.setGate(note, vel > 0);
}
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* rootJ = json_object();

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_object_set_new(rootJ, "notes", notesJ);
@@ -144,10 +159,10 @@ struct Gate_MIDI : Module {
void dataFromJson(json_t* rootJ) override {
json_t* notesJ = json_object_get(rootJ, "notes");
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)
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. */
int learningId;
/** [cell] */
uint8_t learnedNotes[16];
int8_t learnedNotes[16];
bool velocityMode;
bool mpeMode;

@@ -113,7 +113,7 @@ struct MIDI_Gate : Module {
int c = mpeMode ? channel : 0;
// Learn
if (learningId >= 0) {
learnedNotes[learningId] = note;
setLearnedNote(learningId, note);
learningId = -1;
}
// 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* rootJ = json_object();

@@ -160,7 +164,7 @@ struct MIDI_Gate : Module {
for (int i = 0; i < 16; i++) {
json_t* noteJ = json_array_get(notesJ, i);
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 {
TModule* module;
int id;
int focusNote;
uint8_t focusNote;

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

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


Loading…
Cancel
Save