From 79b116d19fa4de2f7b5450acfe77a54524505b7d Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Thu, 9 Feb 2023 13:42:46 +0100 Subject: Enable bypass and bugfixes --- src/app.c | 115 +++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 83 insertions(+), 32 deletions(-) (limited to 'src/app.c') diff --git a/src/app.c b/src/app.c index 27f88f1..7917a54 100644 --- a/src/app.c +++ b/src/app.c @@ -35,12 +35,16 @@ // Housekeeping and debugging. u16 frame = 0; u16 n_voices = 0; +u8 active = 1; +u8 ch_min = 4; +u8 ch_max = 8; typedef struct Voice { u8 active; u8 channel; u8 d1; u8 d2; + u8 port; } Voice; Voice voices[16] = {0}; @@ -134,76 +138,112 @@ u16 font_numbers[10] = { 0xF792, }; +enum Buttons { + POLY_PAD_ACTIVE = 11, +}; + 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]; - // } - - // // 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; - // } + switch (type) { + case TYPEPAD: { + if (value && index == POLY_PAD_ACTIVE) { + // Stop existing playing notes. + for (u8 i = 0; i < 16; i++) { + Voice *voice = &voices[i]; + if (voice->active) { + voice->active = 0; + hal_send_midi( + voice->port, + NOTEOFF | voice->channel, + voice->d1, + voice->d2); + } + } + n_voices = 0; + active = !active; + } + // // 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; + } } void app_midi_event(u8 port, u8 status, u8 d1, u8 d2) { + if (!active) { + hal_send_midi(port, status, d1, d2); + return; + } u8 channel = status & 0x0F; if ((status & 0xF0) == NOTEON) { + if (n_voices == (ch_max - ch_min)) { + return; + } + // Find if the note was already pressed. - for (u8 i = 0; i < 16; i++) { + for (u8 i = ch_min; i < ch_max; i++) { Voice *voice = &voices[i]; - // Register voice. + // Stop voice if needed. if (voice->active && voice->d1 == d1) { voice->active = 0; - hal_send_midi(port, NOTEOFF | i, d1, d2); + hal_send_midi(voice->port, + NOTEOFF | voice->channel, + voice->d1, + voice->d2); break; } } // Find next free voice slot. - for (u8 i = 0; i < 16; i++) { + for (u8 i = ch_min; i < ch_max; i++) { Voice *voice = &voices[i]; // Register voice. if (!voice->active) { voice->active = 1; + voice->port = port; voice->channel = i; voice->d1 = d1; voice->d2 = d2; - hal_send_midi(port, NOTEON | i, d1, d2); + hal_send_midi(voice->port, + NOTEON | voice->channel, + voice->d1, + voice->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. + // TODO: Round robin scheduling? n_voices++; } else if ((status & 0xF0) == NOTEOFF) { - for (u8 i = 0; i < 16; i++) { + for (u8 i = ch_min; i < ch_max; i++) { Voice *voice = &voices[i]; // Register voice. if (voice->active && voice->d1 == d1) { voice->active = 0; hal_send_midi(port, NOTEOFF | i, d1, d2); + n_voices--; break; } } - n_voices--; - // hal_send_midi(port, status, d1, d2); } } @@ -262,12 +302,23 @@ clear_pads(void) { } } +void +draw_poly_scene(void) { + print_number((n_voices / 10) % 10, MAXLED, MAXLED, MAXLED, 0, 0); + print_number( n_voices % 10, MAXLED, MAXLED, MAXLED, 4, 0); + + if (active) { + hal_plot_led(TYPEPAD, 11, 0, MAXLED, 0); + } else { + hal_plot_led(TYPEPAD, 11, MAXLED, 0, 0); + } +} + void render(void) { if (frame++ == 1000 / 10) { clear_pads(); - print_number((n_voices / 10) % 10, MAXLED, MAXLED, MAXLED, 0, 0); - print_number( n_voices % 10, MAXLED, MAXLED, MAXLED, 4, 0); + draw_poly_scene(); frame = 0; } } -- cgit v1.2.1