aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-04-04 09:38:55 +0200
committerBad Diode <bd@badd10de.dev>2023-04-04 09:38:55 +0200
commit3f3968e15776104c5420a0442364cda5a76d3f77 (patch)
tree9c8920344c62fe39983544227ebe95e6de26cb3b
parent47e1e8a63d466ab540e39eaf0f87326e33f38c67 (diff)
downloadstepper-3f3968e15776104c5420a0442364cda5a76d3f77.tar.gz
stepper-3f3968e15776104c5420a0442364cda5a76d3f77.zip
Add bpm and play/pause buttons control
-rw-r--r--src/sequencer.c241
1 files changed, 187 insertions, 54 deletions
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 @@
2#include "text.h" 2#include "text.h"
3 3
4// TODO 4// TODO
5// - Preview sound keys 5// - Preview sound keys?
6// - Copy paste trigs/notes/params 6// - Copy paste trigs/notes/params
7// - Different banks for storing patterns 7// - Different banks for storing patterns
8// - Buttons on the left side for selecting different patterns 8// - Finish noise channel (parameter editing)
9// - Allow control BPM 9
10// - Finish noise channel
11 10
12// 11//
13// Color indexes. 12// Color indexes.
@@ -59,6 +58,17 @@
59#define PAT_H 12 58#define PAT_H 12
60#define PAT_OFFSET_Y 17 59#define PAT_OFFSET_Y 17
61 60
61#define R_COL_W 24
62#define BPM_START_X (R_SIDEBAR_X)
63#define BPM_START_Y (TRIG_START_Y + TRIG_H + 9)
64#define BPM_H 22
65
66#define PLAY_START_X (R_SIDEBAR_X)
67#define PLAY_START_Y (TRIG_START_Y)
68#define STOP_START_X (R_SIDEBAR_X)
69#define STOP_START_Y (TRIG_START_Y + 14)
70#define PLAY_STOP_H (10)
71
62#define SEQ_N_CHANNELS 4 72#define SEQ_N_CHANNELS 4
63 73
64// 74//
@@ -193,10 +203,17 @@ int trig_selection_loc = 0;
193int param_selection_loc = 0; 203int param_selection_loc = 0;
194int channel_selection_loc = 0; 204int channel_selection_loc = 0;
195int pattern_selection_loc = 0; 205int pattern_selection_loc = 0;
206int right_col_selection_loc = 0;
196int play_status = 0; 207int play_status = 0;
197static int current_pattern = 0; 208static int current_pattern = 0;
198static int next_pattern = 0; 209static int next_pattern = 0;
199 210
211enum RIGHT_COL_LOC {
212 R_COL_BPM = 0,
213 R_COL_STOP = 1,
214 R_COL_PLAY = 2,
215};
216
200typedef struct TriggerNote { 217typedef struct TriggerNote {
201 bool active; 218 bool active;
202 Note note; 219 Note note;
@@ -524,6 +541,31 @@ draw_trig_cursor(size_t i, u8 clr) {
524} 541}
525 542
526void 543void
544draw_right_col_cursor(u8 clr) {
545 size_t x0 = 0;
546 size_t x1 = 0;
547 size_t y = 0;
548 switch (right_col_selection_loc) {
549 case R_COL_BPM: {
550 x0 = BPM_START_X;
551 x1 = x0 + R_COL_W;
552 y = BPM_START_Y + BPM_H + 2;
553 } break;
554 case R_COL_STOP: {
555 x0 = STOP_START_X;
556 x1 = x0 + R_COL_W;
557 y = STOP_START_Y + PLAY_STOP_H + 2;
558 } break;
559 case R_COL_PLAY: {
560 x0 = PLAY_START_X;
561 x1 = x0 + R_COL_W;
562 y = PLAY_START_Y + PLAY_STOP_H + 2;
563 } break;
564 }
565 draw_line(x0, y, x1, y, clr);
566}
567
568void
527draw_current_step(u8 col) { 569draw_current_step(u8 col) {
528 size_t offset_x = TRIG_OFFSET_X * (step_counter % 8); 570 size_t offset_x = TRIG_OFFSET_X * (step_counter % 8);
529 size_t offset_y = step_counter < 8 ? 2 : 2 + TRIG_OFFSET_Y; 571 size_t offset_y = step_counter < 8 ? 2 : 2 + TRIG_OFFSET_Y;
@@ -534,26 +576,6 @@ draw_current_step(u8 col) {
534} 576}
535 577
536void 578void
537draw_play() {
538 size_t x = R_SIDEBAR_X;
539 size_t y = TRIG_START_Y;
540 draw_filled_rect(x, y, x + 24, y + 10, COL_BG);
541 draw_rect(x, y, x + 24, y + 10, COL_CYAN);
542 if (play_status == 1) {
543 // Pause button
544 draw_filled_rect(x + 10, y + 3, x + 11, y + 7, COL_CYAN);
545 draw_filled_rect(x + 13, y + 3, x + 14, y + 7, COL_CYAN);
546 } else {
547 // Play button
548 x += 1;
549 draw_line(x + 10, y + 2, x + 10, y + 8, COL_CYAN);
550 draw_line(x + 11, y + 3, x + 11, y + 7, COL_CYAN);
551 draw_line(x + 12, y + 4, x + 12, y + 6, COL_CYAN);
552 draw_line(x + 13, y + 5, x + 13, y + 5, COL_CYAN);
553 }
554}
555
556void
557draw_pattern_buttons() { 579draw_pattern_buttons() {
558 size_t x = PAT_START_X; 580 size_t x = PAT_START_X;
559 size_t y = PAT_START_Y; 581 size_t y = PAT_START_Y;
@@ -588,20 +610,41 @@ draw_pattern_cursor(size_t i, u8 clr) {
588} 610}
589 611
590void 612void
613draw_play() {
614 size_t x = PLAY_START_X;
615 size_t y = PLAY_START_Y;
616 draw_filled_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_BG);
617 draw_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_CYAN);
618 if (play_status == 1) {
619 // Pause button
620 draw_filled_rect(x + 10, y + 3, x + 11, y + 7, COL_CYAN);
621 draw_filled_rect(x + 13, y + 3, x + 14, y + 7, COL_CYAN);
622 } else {
623 // Play button
624 x += 1;
625 draw_line(x + 10, y + 2, x + 10, y + 8, COL_CYAN);
626 draw_line(x + 11, y + 3, x + 11, y + 7, COL_CYAN);
627 draw_line(x + 12, y + 4, x + 12, y + 6, COL_CYAN);
628 draw_line(x + 13, y + 5, x + 13, y + 5, COL_CYAN);
629 }
630}
631
632void
591draw_stop() { 633draw_stop() {
592 size_t x = R_SIDEBAR_X; 634 size_t x = STOP_START_X;
593 size_t y = TRIG_START_Y + 14; 635 size_t y = STOP_START_Y;
594 draw_rect(x, y, x + 24, y + 10, COL_RED); 636 draw_rect(x, y, x + R_COL_W, y + PLAY_STOP_H, COL_RED);
595 draw_filled_rect(x + 10, y + 3, x + 14, y + 7, COL_RED); 637 draw_filled_rect(x + 10, y + 3, x + 14, y + 7, COL_RED);
596} 638}
597 639
598void 640void
599draw_bpm() { 641draw_bpm() {
600 size_t x = R_SIDEBAR_X; 642 size_t x = BPM_START_X;
601 size_t y = TRIG_START_Y + TRIG_H + 9; 643 size_t y = BPM_START_Y;
602 644
603 // Draw bounding box. 645 // Draw bounding box.
604 draw_rect(x, y, x + 24, y + 22, COL_FG); 646 draw_filled_rect(x, y, x + R_COL_W, y + BPM_H, COL_BG);
647 draw_rect(x, y, x + R_COL_W, y + BPM_H, COL_FG);
605 draw_line(x + 5, y, x + 19, y, COL_BG); 648 draw_line(x + 5, y, x + 19, y, COL_BG);
606 txt_drawf_small("BPM", x + 5, y - 4, 4, COL_FG); 649 txt_drawf_small("BPM", x + 5, y - 4, 4, COL_FG);
607 650
@@ -820,6 +863,9 @@ draw_params_cursor_wave(size_t i, u8 clr) {
820 863
821void 864void
822draw_params_cursor_noise(size_t i, u8 clr) { 865draw_params_cursor_noise(size_t i, u8 clr) {
866 // TODO: Handle this.
867 (void)i;
868 (void)clr;
823 // u8 x_positions[] = { 869 // u8 x_positions[] = {
824 // // 32 half bytes (Wave A). 870 // // 32 half bytes (Wave A).
825 // 0, 4, 8, 12, 16, 20, 24, 28, 871 // 0, 4, 8, 12, 16, 20, 24, 28,
@@ -1611,6 +1657,7 @@ void handle_param_selection_sq1(void);
1611void handle_param_selection_sq2(void); 1657void handle_param_selection_sq2(void);
1612void handle_param_selection_wave(void); 1658void handle_param_selection_wave(void);
1613void handle_param_selection_noise(void); 1659void handle_param_selection_noise(void);
1660void handle_right_col_selection(void);
1614 1661
1615void 1662void
1616handle_channel_selection(void) { 1663handle_channel_selection(void) {
@@ -1666,6 +1713,101 @@ handle_channel_selection(void) {
1666} 1713}
1667 1714
1668void 1715void
1716stop_playing(void) {
1717 play_status ^= 1;
1718 if (step_counter != 0) {
1719 draw_current_step(COL_BG);
1720 }
1721 step_counter = 0;
1722 if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) {
1723 set_time(patterns[current_pattern].bpm);
1724 } else {
1725 TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE;
1726 SOUND_SQUARE1_CTRL = 0;
1727 SOUND_SQUARE2_CTRL = 0;
1728 SOUND_WAVE_CTRL = 0;
1729 SOUND_NOISE_CTRL = 0;
1730 }
1731 draw_current_step(COL_RED);
1732 draw_play();
1733}
1734
1735void
1736pause_playing(void) {
1737 play_status ^= 1;
1738 if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) {
1739 set_time(patterns[current_pattern].bpm);
1740 } else {
1741 TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE;
1742 SOUND_SQUARE1_CTRL = 0;
1743 SOUND_SQUARE2_CTRL = 0;
1744 SOUND_WAVE_CTRL = 0;
1745 SOUND_NOISE_CTRL = 0;
1746 }
1747 draw_play();
1748}
1749
1750void
1751handle_right_col_selection(void) {
1752 if (key_tap(KEY_LEFT)) {
1753 input_handler = handle_trigger_selection;
1754 switch (right_col_selection_loc) {
1755 case R_COL_BPM: {
1756 trig_selection_loc = 15;
1757 } break;
1758 case R_COL_PLAY :
1759 case R_COL_STOP: {
1760 trig_selection_loc = 7;
1761 } break;
1762 }
1763 draw_right_col_cursor(COL_BG);
1764 draw_trig_cursor(trig_selection_loc, COL_CURSOR);
1765 TriggerNote *trig = get_current_trig();
1766 draw_note(trig->note, COL_NOTE_PRESSED);
1767 draw_parameters();
1768 } else if (key_tap(KEY_UP)) {
1769 if (right_col_selection_loc < 2) {
1770 draw_right_col_cursor(COL_BG);
1771 right_col_selection_loc++;
1772 draw_right_col_cursor(COL_CURSOR);
1773 }
1774 } else if (key_tap(KEY_DOWN)) {
1775 if (right_col_selection_loc > 0) {
1776 draw_right_col_cursor(COL_BG);
1777 right_col_selection_loc--;
1778 draw_right_col_cursor(COL_CURSOR);
1779 }
1780 } else if (key_tap(KEY_L)) {
1781 switch (right_col_selection_loc) {
1782 case R_COL_BPM: {
1783 if (patterns[pattern_selection_loc].bpm > 10) {
1784 set_time(--patterns[pattern_selection_loc].bpm);
1785 draw_bpm();
1786 }
1787 } break;
1788 }
1789 } else if (key_tap(KEY_R)) {
1790 switch (right_col_selection_loc) {
1791 case R_COL_BPM: {
1792 if (patterns[pattern_selection_loc].bpm < 300) {
1793 set_time(++patterns[pattern_selection_loc].bpm);
1794 draw_bpm();
1795 }
1796 } break;
1797 }
1798 } else if (key_tap(KEY_B)) {
1799 switch (right_col_selection_loc) {
1800 case R_COL_STOP: {
1801 stop_playing();
1802 } break;
1803 case R_COL_PLAY: {
1804 pause_playing();
1805 } break;
1806 }
1807 }
1808}
1809
1810void
1669handle_pattern_selection(void) { 1811handle_pattern_selection(void) {
1670 if (key_tap(KEY_B)) { 1812 if (key_tap(KEY_B)) {
1671 next_pattern = pattern_selection_loc; 1813 next_pattern = pattern_selection_loc;
@@ -2236,7 +2378,7 @@ handle_trigger_selection(void) {
2236 draw_parameters(); 2378 draw_parameters();
2237 } 2379 }
2238 } else if (key_tap(KEY_RIGHT)) { 2380 } else if (key_tap(KEY_RIGHT)) {
2239 if (trig_selection_loc != 7) { 2381 if (trig_selection_loc != 7 && trig_selection_loc != 15) {
2240 draw_trig_cursor(trig_selection_loc, COL_BG); 2382 draw_trig_cursor(trig_selection_loc, COL_BG);
2241 draw_note(trig->note, COL_FG); 2383 draw_note(trig->note, COL_FG);
2242 trig_selection_loc = MIN(trig_selection_loc + 1, 15); 2384 trig_selection_loc = MIN(trig_selection_loc + 1, 15);
@@ -2244,6 +2386,18 @@ handle_trigger_selection(void) {
2244 draw_trig_cursor(trig_selection_loc, COL_CURSOR); 2386 draw_trig_cursor(trig_selection_loc, COL_CURSOR);
2245 draw_note(trig->note, COL_NOTE_PRESSED); 2387 draw_note(trig->note, COL_NOTE_PRESSED);
2246 draw_parameters(); 2388 draw_parameters();
2389 } else if (trig_selection_loc == 7) {
2390 input_handler = handle_right_col_selection;
2391 right_col_selection_loc = R_COL_STOP;
2392 draw_trig_cursor(trig_selection_loc, COL_BG);
2393 draw_note(trig->note, COL_FG);
2394 draw_right_col_cursor(COL_CURSOR);
2395 } else if (trig_selection_loc == 15) {
2396 right_col_selection_loc = R_COL_BPM;
2397 input_handler = handle_right_col_selection;
2398 draw_trig_cursor(trig_selection_loc, COL_BG);
2399 draw_note(trig->note, COL_FG);
2400 draw_right_col_cursor(COL_CURSOR);
2247 } 2401 }
2248 } else if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) { 2402 } else if (key_tap(KEY_UP) || key_tap(KEY_DOWN)) {
2249 draw_trig_cursor(trig_selection_loc, COL_BG); 2403 draw_trig_cursor(trig_selection_loc, COL_BG);
@@ -2281,31 +2435,10 @@ handle_sequencer_input(void) {
2281 2435
2282 if (key_tap(KEY_START)) { 2436 if (key_tap(KEY_START)) {
2283 // Stop the sequencer or start playing from the beginning. 2437 // Stop the sequencer or start playing from the beginning.
2284 play_status ^= 1; 2438 stop_playing();
2285 if (step_counter != 0) {
2286 draw_current_step(COL_BG);
2287 }
2288 step_counter = 0;
2289 if ((TIMER_CTRL_0 & TIMER_CTRL_ENABLE) == 0) {
2290 set_time(patterns[current_pattern].bpm);
2291 } else {
2292 draw_current_step(COL_RED);
2293 TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE;
2294 SOUND_SQUARE1_CTRL = 0;
2295 SOUND_SQUARE2_CTRL = 0;
2296 SOUND_WAVE_CTRL = 0;
2297 SOUND_NOISE_CTRL = 0;
2298 }
2299 draw_play();
2300 } else if (key_tap(KEY_SELECT)) { 2439 } else if (key_tap(KEY_SELECT)) {
2301 // Play/pause. 2440 // Play/pause.
2302 play_status ^= 1; 2441 pause_playing();
2303 TIMER_CTRL_0 ^= TIMER_CTRL_ENABLE;
2304 SOUND_SQUARE1_CTRL = 0;
2305 SOUND_SQUARE2_CTRL = 0;
2306 SOUND_WAVE_CTRL = 0;
2307 SOUND_NOISE_CTRL = 0;
2308 draw_play();
2309 } 2442 }
2310} 2443}
2311 2444