aboutsummaryrefslogtreecommitdiffstats
path: root/src/sequencer.c
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-07-13 12:00:11 +0200
committerBad Diode <bd@badd10de.dev>2023-07-13 12:00:11 +0200
commit7f57051c51c16c88e5dcaa7bd51ccaec31469c4a (patch)
treeb484dc485d7f9718238343ffb5952428d2f52621 /src/sequencer.c
parentd1c68125b6825f0327a4089aa8ddca5105e78ec1 (diff)
downloadstepper-7f57051c51c16c88e5dcaa7bd51ccaec31469c4a.tar.gz
stepper-7f57051c51c16c88e5dcaa7bd51ccaec31469c4a.zip
Add working pattern chaining prototype
Diffstat (limited to 'src/sequencer.c')
-rw-r--r--src/sequencer.c76
1 files changed, 72 insertions, 4 deletions
diff --git a/src/sequencer.c b/src/sequencer.c
index 44ff90e..8d79c65 100644
--- a/src/sequencer.c
+++ b/src/sequencer.c
@@ -47,6 +47,30 @@ gate_on(void) {
47 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3; 47 TIMER_CTRL_3 = TIMER_CTRL_IRQ | TIMER_CTRL_ENABLE | TIMER_CTRL_FREQ_3;
48} 48}
49 49
50u8
51find_next_pattern(void) {
52 u8 idx = (chain.current + 1) % 16;
53 for (size_t i = 0; i < MAX_CHAIN; i++) {
54 if (chain.active[idx] == 1) {
55 break;
56 }
57 idx = (idx + 1) % 16;
58 }
59 return idx;
60}
61
62u8
63find_prev_pattern(void) {
64 u8 idx = chain.current == 0 ? 15 : (chain.current - 1);
65 for (size_t i = 0; i < MAX_CHAIN; i++) {
66 if (chain.active[idx] == 1) {
67 break;
68 }
69 idx = chain.current == 0 ? 15 : (chain.current - 1);
70 }
71 return idx;
72}
73
50void 74void
51play_step(void) { 75play_step(void) {
52 Pattern *pat = &patterns[current_pattern]; 76 Pattern *pat = &patterns[current_pattern];
@@ -54,6 +78,18 @@ play_step(void) {
54 current_pattern = next_pattern; 78 current_pattern = next_pattern;
55 redraw_pattern_buttons = true; 79 redraw_pattern_buttons = true;
56 update_bpm = true; 80 update_bpm = true;
81 } else if (chain.len != 0 && step_counter == 15) {
82 redraw_pattern_buttons = true;
83 update_bpm = true;
84 if (!chain.playing) {
85 next_pattern = chain.chain[chain.current];
86 current_pattern = next_pattern;
87 } else {
88 chain.current = find_next_pattern();
89 next_pattern = chain.chain[chain.current];
90 current_pattern = next_pattern;
91 }
92 chain.playing = true;
57 } 93 }
58 if (pat->ch1.active) { 94 if (pat->ch1.active) {
59 TriggerNote *trig = &pat->ch1.notes[step_counter]; 95 TriggerNote *trig = &pat->ch1.notes[step_counter];
@@ -316,6 +352,9 @@ stop_sound(void) {
316void 352void
317stop_playing(void) { 353stop_playing(void) {
318 step_counter = 0; 354 step_counter = 0;
355 chain.current = 15;
356 chain.current = find_next_pattern();
357 chain.playing = false;
319 stop_sound(); 358 stop_sound();
320} 359}
321 360
@@ -323,6 +362,15 @@ void
323toggle_playing(void) { 362toggle_playing(void) {
324 play_status ^= 1; 363 play_status ^= 1;
325 step_counter = 0; 364 step_counter = 0;
365 chain.current = 15;
366 chain.current = find_next_pattern();
367 chain.playing = false;
368 if (current_pattern == next_pattern && chain.len > 0) {
369 chain.playing = true;
370 next_pattern = chain.chain[chain.current];
371 current_pattern = next_pattern;
372 }
373 redraw_pattern_buttons = true;
326 SOUND_SQUARE1_CTRL = 0; 374 SOUND_SQUARE1_CTRL = 0;
327 SOUND_SQUARE2_CTRL = 0; 375 SOUND_SQUARE2_CTRL = 0;
328 SOUND_WAVE_CTRL = 0; 376 SOUND_WAVE_CTRL = 0;
@@ -351,6 +399,12 @@ pause_playing(void) {
351 SOUND_SQUARE2_CTRL = 0; 399 SOUND_SQUARE2_CTRL = 0;
352 SOUND_WAVE_CTRL = 0; 400 SOUND_WAVE_CTRL = 0;
353 SOUND_NOISE_CTRL = 0; 401 SOUND_NOISE_CTRL = 0;
402 chain.playing = false;
403 if (current_pattern == next_pattern && chain.len > 0) {
404 chain.playing = true;
405 next_pattern = chain.chain[chain.current];
406 current_pattern = next_pattern;
407 }
354 redraw_play_pause = true; 408 redraw_play_pause = true;
355 if (settings.sync == SYNC_IN_LINK) { 409 if (settings.sync == SYNC_IN_LINK) {
356 return; 410 return;
@@ -530,23 +584,37 @@ handle_pattern_selection(void) {
530 } 584 }
531 } 585 }
532 if (slot > -1) { 586 if (slot > -1) {
587 if (chain.len == 0) {
588 chain.current = slot;
589 }
533 chain.chain[slot] = pattern_selection_loc; 590 chain.chain[slot] = pattern_selection_loc;
534 chain.active[slot] = 1; 591 chain.active[slot] = 1;
535 chain.len++; // TODO: remove 592 chain.len++;
536 } 593 }
537 } 594 }
538 if (key_tap(KEY_L)) { 595 if (key_tap(KEY_L)) {
539 // Find last active slot. 596 // Find last active slot.
540 s16 slot = -1; 597 s16 slot = -1;
598 bool update_current = false;
541 for (size_t i = 0; i < 16; i++) { 599 for (size_t i = 0; i < 16; i++) {
542 if (chain.active[15 - i] == 1) { 600 size_t idx = 15 - i;
543 slot = 15 - i; 601 if (chain.active[idx] == 1) {
602 // If the pattern is currently playing it can't be removed.
603 if (play_status && idx == chain.current) {
604 continue;
605 } else if (idx == chain.current) {
606 update_current = true;
607 }
608 slot = idx;
544 break; 609 break;
545 } 610 }
546 } 611 }
547 if (slot > -1) { 612 if (slot > -1) {
548 chain.active[slot] = 0; 613 chain.active[slot] = 0;
549 chain.len--; // TODO: remove 614 chain.len--;
615 if (update_current) {
616 chain.current = find_prev_pattern();
617 }
550 } 618 }
551 } 619 }
552} 620}