From 3f3968e15776104c5420a0442364cda5a76d3f77 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 4 Apr 2023 09:38:55 +0200 Subject: Add bpm and play/pause buttons control --- src/sequencer.c | 241 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 187 insertions(+), 54 deletions(-) (limited to 'src/sequencer.c') diff --git a/src/sequencer.c b/src/sequencer.c index d0705a7..855bbe5 100644 --- a/src/sequencer.c +++ b/src/sequencer.c @@ -2,12 +2,11 @@ #include "text.h" // TODO -// - Preview sound keys +// - Preview sound keys? // - Copy paste trigs/notes/params // - Different banks for storing patterns -// - Buttons on the left side for selecting different patterns -// - Allow control BPM -// - Finish noise channel +// - Finish noise channel (parameter editing) + // // Color indexes. @@ -59,6 +58,17 @@ #define PAT_H 12 #define PAT_OFFSET_Y 17 +#define R_COL_W 24 +#define BPM_START_X (R_SIDEBAR_X) +#define BPM_START_Y (TRIG_START_Y + TRIG_H + 9) +#define BPM_H 22 + +#define PLAY_START_X (R_SIDEBAR_X) +#define PLAY_START_Y (TRIG_START_Y) +#define STOP_START_X (R_SIDEBAR_X) +#define STOP_START_Y (TRIG_START_Y + 14) +#define PLAY_STOP_H (10) + #define SEQ_N_CHANNELS 4 // @@ -193,10 +203,17 @@ int trig_selection_loc = 0; int param_selection_loc = 0; int channel_selection_loc = 0; int pattern_selection_loc = 0; +int right_col_selection_loc = 0; int play_status = 0; static int current_pattern = 0; static int next_pattern = 0; +enum RIGHT_COL_LOC { + R_COL_BPM = 0, + R_COL_STOP = 1, + R_COL_PLAY = 2, +}; + typedef struct TriggerNote { bool active; Note note; @@ -523,6 +540,31 @@ draw_trig_cursor(size_t i, u8 clr) { draw_line(x0, y, x1, y, clr); } +void +draw_right_col_cursor(u8 clr) { + size_t x0 = 0; + size_t x1 = 0; + size_t y = 0; + switch (right_col_selection_loc) { + case R_COL_BPM: { + x0 = BPM_START_X; + x1 = x0 + R_COL_W; + y = BPM_START_Y + BPM_H + 2; + } break; + case R_COL_STOP: { + x0 = STOP_START_X; + x1 = x0 + R_COL_W; + y = STOP_START_Y + PLAY_STOP_H + 2; + } break; + case R_COL_PLAY: { + x0 = PLAY_START_X; + x1 = x0 + R_COL_W; + y = PLAY_START_Y + PLAY_STOP_H + 2; + } break; + } + draw_line(x0, y, x1, y, clr); +} + void draw_current_step(u8 col) { size_t offset_x = TRIG_OFFSET_X * (step_counter % 8); @@ -533,26 +575,6 @@ draw_current_step(u8 col) { draw_line(x0, y, x1, y, col); } -void -draw_play() { - size_t x = R_SIDEBAR_X; - size_t y = TRIG_START_Y; - draw_filled_rect(x, y, x + 24, y + 10, COL_BG); - draw_rect(x, y, x + 24, y + 10, COL_CYAN); - if (play_status == 1) { - // Pause button - draw_filled_rect(x + 10, y + 3, x + 11, y + 7, COL_CYAN); - draw_filled_rect(x + 13, y + 3, x + 14, y + 7, COL_CYAN); - } else { - // Play button - x += 1; - draw_line(x + 10, y + 2, x + 10, y + 8, COL_CYAN); - draw_line(x + 11, y + 3, x + 11, y + 7, COL_CYAN); - draw_line(x + 12, y + 4, x + 12, y + 6, COL_CYAN); - draw_line(x + 13, y + 5, x + 13, y + 5, COL_CYAN); - } -} - void draw_pattern_buttons() { size_t x = PAT_START_X; @@ -587,21 +609,42 @@ draw_pattern_cursor(size_t i, u8 clr) { draw_line(x0, y, x1, y, clr); } +void +draw_play() { + size_t x = PLAY_START_X; + size_t y = PLAY_START_Y; + draw_filled_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_BG); + draw_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_CYAN); + if (play_status == 1) { + // Pause button + draw_filled_rect(x + 10, y + 3, x + 11, y + 7, COL_CYAN); + draw_filled_rect(x + 13, y + 3, x + 14, y + 7, COL_CYAN); + } else { + // Play button + x += 1; + draw_line(x + 10, y + 2, x + 10, y + 8, COL_CYAN); + draw_line(x + 11, y + 3, x + 11, y + 7, COL_CYAN); + draw_line(x + 12, y + 4, x + 12, y + 6, COL_CYAN); + draw_line(x + 13, y + 5, x + 13, y + 5, COL_CYAN); + } +} + void draw_stop() { - size_t x = R_SIDEBAR_X; - size_t y = TRIG_START_Y + 14; - draw_rect(x, y, x + 24, y + 10, COL_RED); + size_t x = STOP_START_X; + size_t y = STOP_START_Y; + draw_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_RED); draw_filled_rect(x + 10, y + 3, x + 14, y + 7, COL_RED); } void draw_bpm() { - size_t x = R_SIDEBAR_X; - size_t y = TRIG_START_Y + TRIG_H + 9; + size_t x = BPM_START_X; + size_t y = BPM_START_Y; // Draw bounding box. - draw_rect(x, y, x + 24, y + 22, COL_FG); + draw_filled_rect(x, y, x + R_COL_W, y + BPM_H, COL_BG); + draw_rect(x, y, x + R_COL_W, y + BPM_H, COL_FG); draw_line(x + 5, y, x + 19, y, COL_BG); txt_drawf_small("BPM", x + 5, y - 4, 4, COL_FG); @@ -820,6 +863,9 @@ draw_params_cursor_wave(size_t i, u8 clr) { void draw_params_cursor_noise(size_t i, u8 clr) { + // TODO: Handle this. + (void)i; + (void)clr; // u8 x_positions[] = { // // 32 half bytes (Wave A). // 0, 4, 8, 12, 16, 20, 24, 28, @@ -1611,6 +1657,7 @@ void handle_param_selection_sq1(void); void handle_param_selection_sq2(void); void handle_param_selection_wave(void); void handle_param_selection_noise(void); +void handle_right_col_selection(void); void handle_channel_selection(void) { @@ -1665,6 +1712,101 @@ handle_channel_selection(void) { } } +void +stop_playing(void) { + play_status ^= 1; + if (step_counter != 0) { + draw_current_step(COL_BG); + } + step_counter = 0; + if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) { + set_time(patterns[current_pattern].bpm); + } else { + TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; + SOUND_SQUARE1_CTRL = 0; + SOUND_SQUARE2_CTRL = 0; + SOUND_WAVE_CTRL = 0; + SOUND_NOISE_CTRL = 0; + } + draw_current_step(COL_RED); + draw_play(); +} + +void +pause_playing(void) { + play_status ^= 1; + if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) { + set_time(patterns[current_pattern].bpm); + } else { + TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; + SOUND_SQUARE1_CTRL = 0; + SOUND_SQUARE2_CTRL = 0; + SOUND_WAVE_CTRL = 0; + SOUND_NOISE_CTRL = 0; + } + draw_play(); +} + +void +handle_right_col_selection(void) { + if (key_tap(KEY_LEFT)) { + input_handler = handle_trigger_selection; + switch (right_col_selection_loc) { + case R_COL_BPM: { + trig_selection_loc = 15; + } break; + case R_COL_PLAY : + case R_COL_STOP: { + trig_selection_loc = 7; + } break; + } + draw_right_col_cursor(COL_BG); + draw_trig_cursor(trig_selection_loc, COL_CURSOR); + TriggerNote *trig = get_current_trig(); + draw_note(trig->note, COL_NOTE_PRESSED); + draw_parameters(); + } else if (key_tap(KEY_UP)) { + if (right_col_selection_loc < 2) { + draw_right_col_cursor(COL_BG); + right_col_selection_loc++; + draw_right_col_cursor(COL_CURSOR); + } + } else if (key_tap(KEY_DOWN)) { + if (right_col_selection_loc > 0) { + draw_right_col_cursor(COL_BG); + right_col_selection_loc--; + draw_right_col_cursor(COL_CURSOR); + } + } else if (key_tap(KEY_L)) { + switch (right_col_selection_loc) { + case R_COL_BPM: { + if (patterns[pattern_selection_loc].bpm > 10) { + set_time(--patterns[pattern_selection_loc].bpm); + draw_bpm(); + } + } break; + } + } else if (key_tap(KEY_R)) { + switch (right_col_selection_loc) { + case R_COL_BPM: { + if (patterns[pattern_selection_loc].bpm < 300) { + set_time(++patterns[pattern_selection_loc].bpm); + draw_bpm(); + } + } break; + } + } else if (key_tap(KEY_B)) { + switch (right_col_selection_loc) { + case R_COL_STOP: { + stop_playing(); + } break; + case R_COL_PLAY: { + pause_playing(); + } break; + } + } +} + void handle_pattern_selection(void) { if (key_tap(KEY_B)) { @@ -2236,7 +2378,7 @@ handle_trigger_selection(void) { draw_parameters(); } } else if (key_tap(KEY_RIGHT)) { - if (trig_selection_loc != 7) { + if (trig_selection_loc != 7 && trig_selection_loc != 15) { draw_trig_cursor(trig_selection_loc, COL_BG); draw_note(trig->note, COL_FG); trig_selection_loc = MIN(trig_selection_loc + 1, 15); @@ -2244,6 +2386,18 @@ handle_trigger_selection(void) { draw_trig_cursor(trig_selection_loc, COL_CURSOR); draw_note(trig->note, COL_NOTE_PRESSED); draw_parameters(); + } else if (trig_selection_loc == 7) { + input_handler = handle_right_col_selection; + right_col_selection_loc = R_COL_STOP; + draw_trig_cursor(trig_selection_loc, COL_BG); + draw_note(trig->note, COL_FG); + draw_right_col_cursor(COL_CURSOR); + } else if (trig_selection_loc == 15) { + right_col_selection_loc = R_COL_BPM; + input_handler = handle_right_col_selection; + draw_trig_cursor(trig_selection_loc, COL_BG); + draw_note(trig->note, COL_FG); + draw_right_col_cursor(COL_CURSOR); } } else if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) { draw_trig_cursor(trig_selection_loc, COL_BG); @@ -2281,31 +2435,10 @@ handle_sequencer_input(void) { if (key_tap(KEY_START)) { // Stop the sequencer or start playing from the beginning. - play_status ^= 1; - if (step_counter != 0) { - draw_current_step(COL_BG); - } - step_counter = 0; - if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) { - set_time(patterns[current_pattern].bpm); - } else { - draw_current_step(COL_RED); - TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; - SOUND_SQUARE1_CTRL = 0; - SOUND_SQUARE2_CTRL = 0; - SOUND_WAVE_CTRL = 0; - SOUND_NOISE_CTRL = 0; - } - draw_play(); + stop_playing(); } else if (key_tap(KEY_SELECT)) { // Play/pause. - play_status ^= 1; - TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE; - SOUND_SQUARE1_CTRL = 0; - SOUND_SQUARE2_CTRL = 0; - SOUND_WAVE_CTRL = 0; - SOUND_NOISE_CTRL = 0; - draw_play(); + pause_playing(); } } -- cgit v1.2.1