From 8fc15953b2c10a8f06169b4ccbc6b16c86b205b2 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Wed, 8 Feb 2023 17:49:45 +0100 Subject: Add initial poly midi splitter --- src/app.c | 121 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/app.c b/src/app.c index 9258965..27f88f1 100644 --- a/src/app.c +++ b/src/app.c @@ -34,7 +34,16 @@ // Housekeeping and debugging. u16 frame = 0; -u16 value = 0; +u16 n_voices = 0; + +typedef struct Voice { + u8 active; + u8 channel; + u8 d1; + u8 d2; +} Voice; + +Voice voices[16] = {0}; // store ADC frame pointer static const u16 *g_ADC = 0; @@ -127,42 +136,74 @@ u16 font_numbers[10] = { void app_surface_event(u8 type, u8 index, u8 value) { - switch (type) { - case TYPEPAD: { - // toggle it and store it off, so we can save to flash if we want to - if (value) { - buttons[index] = MAXLED * !buttons[index]; - } + // switch (type) { + // case TYPEPAD: { + // // toggle it and store it off, so we can save to flash if we want to + // if (value) { + // buttons[index] = MAXLED * !buttons[index]; + // } - // example - light / extinguish pad LEDs - // hal_plot_led(TYPEPAD, index, 0, 0, buttons[index]); - - // example - send MIDI - // hal_send_midi(DINMIDI, NOTEON | 0, index, value); - } break; - case TYPESETUP: { - if (value) { - // Pressing the setup button will save the current buttons/pad - // state to the flash. The flash memory is USER_AREA_SIZE bytes - // long and can be organized however we need. - hal_write_flash(0, buttons, BUTTON_COUNT); - } - } break; - } + // // example - light / extinguish pad LEDs + // hal_plot_led(TYPEPAD, index, 0, 0, buttons[index]); + + // // example - send MIDI + // hal_send_midi(DINMIDI, NOTEON | 0, index, value); + // } break; + // case TYPESETUP: { + // if (value) { + // // Pressing the setup button will save the current buttons/pad + // // state to the flash. The flash memory is USER_AREA_SIZE bytes + // // long and can be organized however we need. + // hal_write_flash(0, buttons, BUTTON_COUNT); + // } + // } break; + // } } void app_midi_event(u8 port, u8 status, u8 d1, u8 d2) { - if (port == USBMIDI) { - hal_send_midi(DINMIDI, status, d1, d2); - } - if (port == DINMIDI) { - hal_send_midi(USBMIDI, status, d1, d2); - } + u8 channel = status & 0x0F; if ((status & 0xF0) == NOTEON) { - value++; + // Find if the note was already pressed. + for (u8 i = 0; i < 16; i++) { + Voice *voice = &voices[i]; + // Register voice. + if (voice->active && voice->d1 == d1) { + voice->active = 0; + hal_send_midi(port, NOTEOFF | i, d1, d2); + break; + } + } + + // Find next free voice slot. + for (u8 i = 0; i < 16; i++) { + Voice *voice = &voices[i]; + // Register voice. + if (!voice->active) { + voice->active = 1; + voice->channel = i; + voice->d1 = d1; + voice->d2 = d2; + hal_send_midi(port, NOTEON | i, d1, d2); + break; + } + } + // TODO: if there are no free slots choose the oldest active one. + // TODO: - Send noteoff message for the previous active channel. + // TODO: send noteon message. + n_voices++; } else if ((status & 0xF0) == NOTEOFF) { - value--; + for (u8 i = 0; i < 16; i++) { + Voice *voice = &voices[i]; + // Register voice. + if (voice->active && voice->d1 == d1) { + voice->active = 0; + hal_send_midi(port, NOTEOFF | i, d1, d2); + break; + } + } + n_voices--; + // hal_send_midi(port, status, d1, d2); } } @@ -180,11 +221,11 @@ app_aftertouch_event(u8 index, u8 value) { void app_cable_event(u8 type, u8 value) { // example - light the Setup LED to indicate cable connections - // if (type == MIDI_IN_CABLE) { - // hal_plot_led(TYPESETUP, 0, 0, value, 0); // green - // } else if (type == MIDI_OUT_CABLE) { - // hal_plot_led(TYPESETUP, 0, value, 0, 0); // red - // } + if (type == MIDI_IN_CABLE) { + hal_plot_led(TYPESETUP, 0, 0, value, 0); // green + } else if (type == MIDI_OUT_CABLE) { + hal_plot_led(TYPESETUP, 0, value, 0, 0); // red + } } void @@ -204,14 +245,14 @@ print_number(u8 n, u16 r, u16 g, u16 b, u8 x, u8 y) { void update(void) { // for (int i = 0; i < PAD_COUNT; ++i) { - // // Get the first detected button value. + // // Get the first detected button n_voices. // u16 x = (99 * g_ADC[i]) >> 12; // if (x > 3) { - // value = x; + // n_voices = x; // return; // } // } - // value = 0; + // n_voices = 0; } void @@ -225,8 +266,8 @@ void render(void) { if (frame++ == 1000 / 10) { clear_pads(); - print_number((value / 10) % 10, MAXLED, MAXLED, MAXLED, 0, 0); - print_number( value % 10, MAXLED, MAXLED, MAXLED, 4, 0); + print_number((n_voices / 10) % 10, MAXLED, MAXLED, MAXLED, 0, 0); + print_number( n_voices % 10, MAXLED, MAXLED, MAXLED, 4, 0); frame = 0; } } -- cgit v1.2.1