Hello!
I want to build a small tool to manage my Korg M1 with
a Teensy 4.0.
So far i got midi CC to SYSEX message translation working
for configuring the Presets.
Since i do have an audioshield with sdcard i am thinking
about how to add the feature of loading presets into the
synth via SYSEX.
I thought about simply loading the content of a SYSEX file
into an array and then simply pushing the data out via
usbMIDI.sendSysEx(32000, sysexfiledata);
Before i dive into this i thought it would be wise to ask here
if that would work or if there is another solution to this.
below is working code for controlling korg M1 preset parameters.
not really related to the question i guess.
Code:#include "korg-M1_sysex.h" // arrays with sysex data static uint8_t SYSEX_START = 0xF0; // start of system exclusive message static uint8_t SYSEX_END = 0xF7; // end of system exclusive message static uint8_t KORG_ID = 0x42; // Korg static uint8_t KORG_CHANNEL = 0x30; static uint8_t KORG_MODEL = 0x19; // Korg M1 static uint8_t KORG_PARAM_CHANGE = 0x41; static uint8_t NEGATIVE_VALUE = 0x7F; static uint8_t POSITIVE_VALUE = 0x00; uint8_t positive_or_negative = POSITIVE_VALUE; uint8_t parameter_page = 0; uint8_t parameter_position=0; char* parameter_name; byte last_cc_message[128]; bool CHAOS_MODE=0; void setup() { usbMIDI.setHandleControlChange(HandleControllMessage); // set handle control messages usbMIDI.setHandleProgramChange(HandleProgramChange); usbMIDI.setHandleNoteOn(HandleNoteOnMessage); usbMIDI.setHandleNoteOff(HandleNoteOffMessage); Serial.begin(115200); while (!Serial) {;} // wait for serial } void loop() { usbMIDI.read(); } // read the USB MIDI bus every loop void HandleControllMessage(byte channel, byte controller, byte value) { // check for CHAOS_MODE Setting if (channel == 6 && controller == 66){ switch (value) { case 127: CHAOS_MODE = 1; Serial.println("CHAOS MODE ACTIVATED !!!!"); break; default: CHAOS_MODE = 0; Serial.println("CHAOS MODE OFF"); } } // filter out cc 120 - 127 and forward it if (controller >= 120 || controller == 64){ usbMIDI.sendControlChange(0x01, controller, value); } else if (last_cc_message[controller] == value && !CHAOS_MODE){ Serial.print(channel); Serial.print(" "); Serial.print(controller); Serial.print(" "); Serial.print(value); Serial.print(" "); Serial.println("DUPLICATE MESSAGE"); } else { last_cc_message[controller] = value; Serial.print(channel); Serial.print(" "); Serial.print(controller); Serial.print(" "); Serial.print(value); Serial.print(" = "); controller = (controller - 1); // cc1 == array[0], cc128 == array[127] switch (channel) { case 2: // single osclillator parameter_name = sysex_single_name[controller]; parameter_page = sysex_single_parameter_page[controller]; parameter_position = sysex_single_parameter_position[controller]; // -/+ controller negativ value if (sysex_single_val_start[controller] == NEGATIVE_VALUE && value < 63) { value = map(value, 0, 62, sysex_single_val_end[controller], 0); value = 128 - value; positive_or_negative = NEGATIVE_VALUE; } // -/+ controller positiv value else if (sysex_single_val_start[controller] == NEGATIVE_VALUE) { value = map(value, 63, 127, 0, sysex_single_val_end[controller]); positive_or_negative = POSITIVE_VALUE; } // full range 0-x controller else if (sysex_single_val_start[controller] == POSITIVE_VALUE) { value = map(value, 0, 127, 0, sysex_single_val_end[controller]); positive_or_negative = POSITIVE_VALUE; } break; case 3: // double osclillator part 1 parameter_name = sysex_double1_name[controller]; parameter_page = sysex_double1_parameter_page[controller]; parameter_position = sysex_double1_parameter_position[controller]; // -/+ controller negativ value if (sysex_double1_val_start[controller] == NEGATIVE_VALUE && value < 63) { value = map(value, 0, 62, sysex_double1_val_end[controller], 0); value = 128 - value; positive_or_negative = NEGATIVE_VALUE; } // -/+ controller positiv value else if (sysex_double1_val_start[controller] == NEGATIVE_VALUE) { value = map(value, 63, 127, 0, sysex_double1_val_end[controller]); positive_or_negative = POSITIVE_VALUE; } // full range 0-x controller else if (sysex_double1_val_start[controller] == POSITIVE_VALUE) { value = map(value, 0, 127, 0, sysex_double1_val_end[controller]); positive_or_negative = POSITIVE_VALUE; } break; case 4: // double osclillator part 2 parameter_name = sysex_double2_name[controller]; parameter_page = sysex_double2_parameter_page[controller]; parameter_position = sysex_double2_parameter_position[controller]; // -/+ controller negativ value if (sysex_double2_val_start[controller] == NEGATIVE_VALUE && value < 63) { value = map(value, 0, 62, sysex_double2_val_end[controller], 0); value = 128 - value; positive_or_negative = NEGATIVE_VALUE; } // -/+ controller positiv value else if (sysex_double2_val_start[controller] == NEGATIVE_VALUE) { value = map(value, 63, 127, 0, sysex_double2_val_end[controller]); positive_or_negative = POSITIVE_VALUE; } // full range 0-x controller else if (sysex_double2_val_start[controller] == POSITIVE_VALUE) { value = map(value, 0, 127, 0, sysex_double2_val_end[controller]); positive_or_negative = POSITIVE_VALUE; } break; } uint8_t sysex[] = {SYSEX_START, \ KORG_ID, \ KORG_CHANNEL, \ KORG_MODEL, \ KORG_PARAM_CHANGE,\ parameter_page, \ parameter_position,\ value, \ positive_or_negative, \ SYSEX_END}; for (int element : sysex){Serial.print(element < 16 ? "0" : "");Serial.print(element, HEX);Serial.print(" ");} //Serial.println(); Serial.print(" ::: "); Serial.println(parameter_name); usbMIDI.sendSysEx(10, sysex); //delay(1); // 1ms pause to not stress out the receiver, just a random value, lower may work - untested delayMicroseconds(100) } } void HandleProgramChange(byte channel, byte program) { usbMIDI.sendProgramChange(program, 0x01); } void HandleNoteOnMessage(byte channel, byte pitch, byte velocity) { usbMIDI.sendNoteOn(pitch, velocity, 0x01); } void HandleNoteOffMessage(byte channel, byte pitch, byte velocity) { usbMIDI.sendNoteOff(pitch, velocity, 0x01);}