diff options
Diffstat (limited to 'src/sequencer.c')
-rw-r--r-- | src/sequencer.c | 76 |
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 | ||
50 | u8 | ||
51 | find_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 | |||
62 | u8 | ||
63 | find_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 | |||
50 | void | 74 | void |
51 | play_step(void) { | 75 | play_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) { | |||
316 | void | 352 | void |
317 | stop_playing(void) { | 353 | stop_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 | |||
323 | toggle_playing(void) { | 362 | toggle_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 | } |