diff --git a/.gitignore b/.gitignore index 84e7a0787..1ca279d74 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,12 @@ dev/sdcards6/ dev/sdcards5/sdcard_timings5.png ezeptocore.uf2 .codex +dev/sdcards7/gigastone32gb_1.txt +dev/sdcards7/kexing16gb_1.txt +dev/sdcards7/kexing16gb_2.txt +dev/sdcards7/kexing16gb_3.txt +dev/sdcards7/kexing16gb_4.txt +dev/sdcards7/kootion16gb_1.txt +dev/sdcards7/kootion16gb_2.txt +dev/sdcards7/kootion16gb_4.txt +dev/analyze_sdcards7.py diff --git a/docs/content/combos/jump_page_lock.md b/docs/content/combos/jump_page_lock.md new file mode 100644 index 000000000..3c70a0c2b --- /dev/null +++ b/docs/content/combos/jump_page_lock.md @@ -0,0 +1,13 @@ ++++ +title = 'Jump page lock' +date = 2024-02-01T12:33:06-08:00 +short = 'Lock jump buttons to a slice page' +buttons = ['D'] +weight = 11 +mode = 'jump' +icon = 'lock' ++++ + +In `JUMP` mode, press **D** by itself to cycle where the **1-16** jump buttons point: current page, first page, second page, third page. + +The top **C** and **D** lights show the lock: both off follows the current page, **C** is first page, **D** is second page, and both lit is third page. Locked pages wrap around if the sample has fewer slices. diff --git a/lib/button_handler.h b/lib/button_handler.h index 169b4f00a..194cb873d 100644 --- a/lib/button_handler.h +++ b/lib/button_handler.h @@ -21,9 +21,21 @@ int16_t key_on_buttons_last[BUTTONMATRIX_BUTTONS_MAX]; bool key_did_go_off[BUTTONMATRIX_BUTTONS_MAX]; uint16_t key_num_presses; bool KEY_C_sample_select = false; +bool jump_page_lock_d_alone_candidate = false; bool button_is_pressed(uint8_t key) { return key_on_buttons[key] > 0; } +void maybe_toggle_jump_page_lock_on_d_release(uint8_t key) { + if (key != KEY_D) { + return; + } + if (jump_page_lock_d_alone_candidate && mode_buttons16 == MODE_JUMP) { + jump_page_lock = (jump_page_lock + 1) % 4; + printf("[button_handler] jump_page_lock: %d\n", jump_page_lock); + } + jump_page_lock_d_alone_candidate = false; +} + int8_t single_step_pressed() { uint8_t pressed = 0; int8_t val = -1; @@ -258,7 +270,7 @@ void button_key_on_single(uint8_t key) { // 1-16 (jump mode) // do jump debounce_quantize = 2; - key_do_jump(key - 4); + key_do_physical_jump(key - 4); dub_step_break = 0; dub_step_divider = 0; dub_step_beat = beat_current; @@ -849,6 +861,7 @@ bool button_handler(ButtonMatrix *bm) { if (bm->off[i] == KEY_A || bm->off[i] == KEY_D) { cued_sound_selector = false; } + maybe_toggle_jump_page_lock_on_d_release(bm->off[i]); // printf("turned off %d\n", bm->off[i]); if (key_held_on && (bm->off[i] == key_held_num)) { button_key_off_held(bm->off[i]); @@ -894,6 +907,12 @@ bool button_handler(ButtonMatrix *bm) { if (key_total_pressed == 1) { key_timer_on = 0; } + if (bm->on[i] == KEY_D) { + jump_page_lock_d_alone_candidate = + mode_buttons16 == MODE_JUMP && key_total_pressed == 1; + } else if (key_on_buttons[KEY_D] > 0) { + jump_page_lock_d_alone_candidate = false; + } if (!key_held_on) { key_held_on = true; key_held_num = bm->on[i]; @@ -1329,8 +1348,12 @@ bool button_handler(ButtonMatrix *bm) { } else if (mode_buttons16 == MODE_JUMP) { LEDS_set(leds, 0, LED_BRIGHT); LEDS_set(leds, 1, LED_BLINK); - LEDS_set(leds, 2, 0); - LEDS_set(leds, 3, 0); + LEDS_set(leds, 2, + (jump_page_lock & JUMP_PAGE_LOCK_FIRST) ? LED_BRIGHT + : LED_NONE); + LEDS_set(leds, 3, + (jump_page_lock & JUMP_PAGE_LOCK_SECOND) ? LED_BRIGHT + : LED_NONE); } else if (mode_buttons16 == MODE_BASS) { LEDS_set(leds, 0, LED_BRIGHT); LEDS_set(leds, 1, 0); diff --git a/lib/globals.h b/lib/globals.h index 3325c5f1e..4b187b734 100644 --- a/lib/globals.h +++ b/lib/globals.h @@ -130,6 +130,13 @@ void regenerate_random_sequence_arr() { // mode toggles // mode ==0 ==1 uint8_t mode_buttons16 = 0; +#ifdef INCLUDE_ZEPTOCORE +#define JUMP_PAGE_LOCK_DEFAULT 0 +#define JUMP_PAGE_LOCK_FIRST 1 +#define JUMP_PAGE_LOCK_SECOND 2 +#define JUMP_PAGE_LOCK_THIRD 3 +uint8_t jump_page_lock = JUMP_PAGE_LOCK_DEFAULT; +#endif bool mode_mute = 0; bool mode_play = 0; bool mute_because_of_playback_type = false; @@ -632,46 +639,61 @@ void do_update_phase_from_beat_current() { jump_precedence = false; } -void key_do_jump(uint8_t beat) { - if (beat >= 0 && beat < 16) { +void key_do_jump_to_slice(int32_t slice, uint8_t sequencer_beat) { #ifdef INCLUDE_ZEPTOCORE - if (clock_in_do && clock_input_absent_zeptocore && - clock_in_activator >= 3) { - // reset beats - bpm_timer_counter = 0; - beat_total = 0; - key_jump_debounce = 0; - dub_step_break = -1; - retrig_beat_num = 0; - beat_current = 0; - playback_stopped = false; - clock_in_ready = false; - clock_in_activator = 0; - clock_in_do = false; - } + if (clock_in_do && clock_input_absent_zeptocore && clock_in_activator >= 3) { + // reset beats + bpm_timer_counter = 0; + beat_total = 0; + key_jump_debounce = 0; + dub_step_break = -1; + retrig_beat_num = 0; + beat_current = 0; + playback_stopped = false; + clock_in_ready = false; + clock_in_activator = 0; + clock_in_do = false; + } #endif - // printf("key_do_jump %d\n", beat); - // TODO: [0] should be which sequencer it is on - if (sequencerhandler[0].recording) { - Sequencer_add(sf->sequencers[0][sf->sequence_sel[0]], beat, - bpm_timer_counter); + // TODO: [0] should be which sequencer it is on + if (sequencerhandler[0].recording) { + Sequencer_add(sf->sequencers[0][sf->sequence_sel[0]], sequencer_beat, + bpm_timer_counter); + } + key_jump_debounce = 1; + beat_current = slice; + retrig_pitch = PITCH_VAL_MID; + // reset filter + if (global_filter_index != retrig_filter_original && + retrig_filter_original > 0) { + global_filter_index = retrig_filter_original; + for (uint8_t channel = 0; channel < 2; channel++) { + ResonantFilter_setFc(resFilter[channel], global_filter_index); } - key_jump_debounce = 1; - beat_current = floor(beat_current / 16) * 16 + beat; - retrig_pitch = PITCH_VAL_MID; - // reset filter - if (global_filter_index != retrig_filter_original && - retrig_filter_original > 0) { - global_filter_index = retrig_filter_original; - for (uint8_t channel = 0; channel < 2; channel++) { - ResonantFilter_setFc(resFilter[channel], global_filter_index); - } - retrig_filter_original = 0; + retrig_filter_original = 0; + } + jump_precedence = true; + do_update_phase_from_beat_current(); +} + +void key_do_jump(uint8_t beat) { + if (beat < 16) { + // printf("key_do_jump %d\n", beat); + key_do_jump_to_slice(floor(beat_current / 16) * 16 + beat, beat); + } +} + +#ifdef INCLUDE_ZEPTOCORE +void key_do_physical_jump(uint8_t beat) { + if (beat < 16) { + int32_t slice = floor(beat_current / 16) * 16 + beat; + if (jump_page_lock > JUMP_PAGE_LOCK_DEFAULT) { + slice = (jump_page_lock - 1) * 16 + beat; } - jump_precedence = true; - do_update_phase_from_beat_current(); + key_do_jump_to_slice(slice, beat); } } +#endif void step_sequencer_emit(uint8_t key) { #ifdef INCLUDE_MIDI