diff --git a/ectocore_compile_definitions.cmake b/ectocore_compile_definitions.cmake index 0b744a915..b5409deb9 100644 --- a/ectocore_compile_definitions.cmake +++ b/ectocore_compile_definitions.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 # pin definitions diff --git a/ectocore_compile_definitions_128.cmake b/ectocore_compile_definitions_128.cmake index d32badfb8..a489cc2f6 100644 --- a/ectocore_compile_definitions_128.cmake +++ b/ectocore_compile_definitions_128.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 # pin definitions diff --git a/ectocore_compile_definitions_256.cmake b/ectocore_compile_definitions_256.cmake index 0dd0c87b6..e7a8e5788 100644 --- a/ectocore_compile_definitions_256.cmake +++ b/ectocore_compile_definitions_256.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 # pin definitions diff --git a/ectocore_compile_definitions_nooverclock.cmake b/ectocore_compile_definitions_nooverclock.cmake index 729e43137..4272e4d19 100644 --- a/ectocore_compile_definitions_nooverclock.cmake +++ b/ectocore_compile_definitions_nooverclock.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 # DO_OVERCLOCK=1 # pin definitions diff --git a/ectocore_compile_definitions_nooverclock_128.cmake b/ectocore_compile_definitions_nooverclock_128.cmake index 7f75c7e16..f423a1811 100644 --- a/ectocore_compile_definitions_nooverclock_128.cmake +++ b/ectocore_compile_definitions_nooverclock_128.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 # DO_OVERCLOCK=1 # pin definitions diff --git a/ectocore_compile_definitions_nooverclock_256.cmake b/ectocore_compile_definitions_nooverclock_256.cmake index cbca82d31..bbfb489f0 100644 --- a/ectocore_compile_definitions_nooverclock_256.cmake +++ b/ectocore_compile_definitions_nooverclock_256.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 # DO_OVERCLOCK=1 # pin definitions diff --git a/ectocore_compile_definitions_v0.3.cmake b/ectocore_compile_definitions_v0.3.cmake index d41c71733..3f1d50dd3 100644 --- a/ectocore_compile_definitions_v0.3.cmake +++ b/ectocore_compile_definitions_v0.3.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 # pin definitions diff --git a/ezeptocore_compile_definitions.cmake b/ezeptocore_compile_definitions.cmake index 125ffad1c..2c18b6703 100644 --- a/ezeptocore_compile_definitions.cmake +++ b/ezeptocore_compile_definitions.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 # pin definitions diff --git a/ezeptocore_compile_definitions_128.cmake b/ezeptocore_compile_definitions_128.cmake index 04b688475..4568f37d3 100644 --- a/ezeptocore_compile_definitions_128.cmake +++ b/ezeptocore_compile_definitions_128.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 # pin definitions diff --git a/ezeptocore_compile_definitions_256.cmake b/ezeptocore_compile_definitions_256.cmake index bfdac7f52..b0ceadb8c 100644 --- a/ezeptocore_compile_definitions_256.cmake +++ b/ezeptocore_compile_definitions_256.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 # pin definitions diff --git a/ezeptocore_compile_definitions_nooverclock.cmake b/ezeptocore_compile_definitions_nooverclock.cmake index 5285ad202..12a0ac721 100644 --- a/ezeptocore_compile_definitions_nooverclock.cmake +++ b/ezeptocore_compile_definitions_nooverclock.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 # DO_OVERCLOCK=1 # pin definitions diff --git a/ezeptocore_compile_definitions_nooverclock_128.cmake b/ezeptocore_compile_definitions_nooverclock_128.cmake index 615a46e47..f48660e6c 100644 --- a/ezeptocore_compile_definitions_nooverclock_128.cmake +++ b/ezeptocore_compile_definitions_nooverclock_128.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 # DO_OVERCLOCK=1 # pin definitions diff --git a/ezeptocore_compile_definitions_nooverclock_256.cmake b/ezeptocore_compile_definitions_nooverclock_256.cmake index 3b343fd20..d36f0e548 100644 --- a/ezeptocore_compile_definitions_nooverclock_256.cmake +++ b/ezeptocore_compile_definitions_nooverclock_256.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 # DO_OVERCLOCK=1 # pin definitions diff --git a/ezeptocore_midi_compile_definitions.cmake b/ezeptocore_midi_compile_definitions.cmake index bb9463084..5e0e7adfe 100644 --- a/ezeptocore_midi_compile_definitions.cmake +++ b/ezeptocore_midi_compile_definitions.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 # pin definitions diff --git a/ezeptocoree_compile_definitions_nooverclock_256.cmake b/ezeptocoree_compile_definitions_nooverclock_256.cmake index 3b343fd20..d36f0e548 100644 --- a/ezeptocoree_compile_definitions_nooverclock_256.cmake +++ b/ezeptocoree_compile_definitions_nooverclock_256.cmake @@ -19,6 +19,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 # DO_OVERCLOCK=1 # pin definitions diff --git a/lib/audio_callback.h b/lib/audio_callback.h index 21fddc3cf..6b28d00e3 100644 --- a/lib/audio_callback.h +++ b/lib/audio_callback.h @@ -48,6 +48,10 @@ void __not_in_flash_func(update_filter_from_envelope)(int32_t val) { #define INTERPOLATE_VALUE 512 int16_t newArray[SAMPLES_PER_BUFFER]; +// Core 1's stack is reserved for control flow and short-lived source buffers. +// This always-present 3.5 KiB render workspace is static so normal stereo +// playback fits within the RP2040 scratch-bank stack. +static int32_t audio_render_samples[SAMPLES_PER_BUFFER * 2]; void __not_in_flash_func(array_resample_linear441)(int16_t *arr, int16_t arr_size) { @@ -140,7 +144,7 @@ void __not_in_flash_func(i2s_callback_func)() { return; } - int32_t samples[buffer->max_sample_count * 2]; + int32_t *samples = audio_render_samples; int16_t *samples16 = (int16_t *)buffer->buffer->bytes; #ifdef DEBUG_AUDIO_WITH_SINE_WAVE @@ -395,7 +399,6 @@ void __not_in_flash_func(i2s_callback_func)() { 1); uint32_t values_to_read_minus_peek = values_len_minus_peek * 2; uint32_t values_to_read = values_len * 2; // 16-bit = 2 x 1 byte reads - int16_t values[values_len]; int32_t vol_main = round((float)volume_vals[sf->vol] * retrig_vol * envelope_volume_val); @@ -508,25 +511,13 @@ void __not_in_flash_func(i2s_callback_func)() { sel_bank_cur = sel_bank_next; sel_sample_cur = sel_sample_next % banks[sel_bank_cur]->num_samples; - FRESULT fr; t0 = time_us_32(); - fr = f_close(&fil_current); - if (fr != FR_OK) { - debugf("[audio_callback] f_close error: %s\n", FRESULT_str(fr)); - } - sprintf(fil_current_name, "bank%d/%d.%d.wav", sel_bank_cur + 1, - sel_sample_cur, sel_variation + audio_variant * 2); - fr = f_open(&fil_current, fil_current_name, FA_READ); + f_close(&fil_current); + format_sample_filename(fil_current_name, sel_bank_cur, sel_sample_cur, + sel_variation + audio_variant * 2); + f_open(&fil_current, fil_current_name, FA_READ); t1 = time_us_32(); sd_card_total_time += (t1 - t0); -#ifdef PRINT_SDCARD_OPEN_TIMING - MessageSync_printf(messagesync, - "[audio_callback] do_open_file f_close+f_open: %d\n", - (t1 - t0)); -#endif - if (fr != FR_OK) { - debugf("[audio_callback] f_open error: %s\n", FRESULT_str(fr)); - } do_open_file = false; realtime_stretch_reset_from_playback_phase(); } @@ -558,6 +549,8 @@ void __not_in_flash_func(i2s_callback_func)() { goto AUDIO_SOURCE_RENDERED; } + { + int16_t values[values_len]; for (int8_t head = 1; head >= 0; head--) { if (head == 1 && (!do_crossfade || do_fade_in)) { continue; @@ -567,30 +560,13 @@ void __not_in_flash_func(i2s_callback_func)() { // setup the next sel_bank_cur = sel_bank_next; sel_sample_cur = sel_sample_next % banks[sel_bank_cur]->num_samples; - // printf("[audio_callback] switch bank/sample %d/%d\n", sel_bank_cur, - // sel_sample_cur); - - FRESULT fr; t0 = time_us_32(); - fr = f_close(&fil_current); - if (fr != FR_OK) { - debugf("[audio_callback] f_close error: %s\n", FRESULT_str(fr)); - } - sprintf(fil_current_name, "bank%d/%d.%d.wav", sel_bank_cur + 1, - sel_sample_cur, sel_variation + audio_variant * 2); - fr = f_open(&fil_current, fil_current_name, FA_READ); + f_close(&fil_current); + format_sample_filename(fil_current_name, sel_bank_cur, sel_sample_cur, + sel_variation + audio_variant * 2); + f_open(&fil_current, fil_current_name, FA_READ); t1 = time_us_32(); sd_card_total_time += (t1 - t0); -#ifdef PRINT_SDCARD_OPEN_TIMING - if (do_open_file) { - MessageSync_printf(messagesync, - "[audio_callback] do_open_file f_close+f_open: %d\n", - (t1 - t0)); - } -#endif - if (fr != FR_OK) { - debugf("[audio_callback] f_open error: %s\n", FRESULT_str(fr)); - } } // optimization here, only seek if the current position is not at the @@ -606,8 +582,6 @@ void __not_in_flash_func(i2s_callback_func)() { if (clock_input_present_first) { clock_input_present_first = false; negative_latency = 0; - MessageSync_printf(messagesync, - "[audio_callback] clock_input_present_first\n"); } } #endif @@ -642,69 +616,17 @@ void __not_in_flash_func(i2s_callback_func)() { return; } t1 = time_us_32(); -#ifdef PRINT_SDCARD_OPEN_TIMING - if (do_open_file) { - MessageSync_printf(messagesync, - "[audio_callback] do_open_file f_lseek: %d\n", - (t1 - t0)); - } -#endif sd_card_total_time += (t1 - t0); } t0 = time_us_32(); if (f_read(&fil_current, values, values_to_read, &fil_bytes_read)) { watchdog_reboot(0, SRAM_END, 0); - // sprintf(fil_current_name, "bank%d/%d.%d.wav", sel_bank_cur + 1, - // sel_sample_cur, sel_variation + audio_variant * 2); - // printf("reopening %s\n", fil_current_name); - // f_close(&fil_current); // close and re-open trick - // f_open(&fil_current, fil_current_name, FA_READ); - // f_lseek(&fil_current, WAV_HEADER + - // ((banks[sel_bank_cur] - // ->sample[sel_sample_cur] - // .snd[FILEZERO] - // ->num_channels + - // 1) * - // (banks[sel_bank_cur] - // ->sample[sel_sample_cur] - // .snd[FILEZERO] - // ->oversampling + - // 1) * - // 44100) + - // (phases[head] / PHASE_DIVISOR) * - // PHASE_DIVISOR); } t1 = time_us_32(); sd_card_total_time += (t1 - t0); -#ifdef PRINT_SDCARD_TIMING - if (do_open_file) { - MessageSync_printf( - messagesync, "[audio_callback] do_open_file f_read: %d\n", (t1 - t0)); - } -#endif last_seeked = phases[head] + fil_bytes_read; - if (fil_bytes_read < values_to_read) { - MessageSync_printf(messagesync, - "%d %d: asked for %d bytes, read %d bytes\n", - phases[head], - WAV_HEADER + - ((banks[sel_bank_cur] - ->sample[sel_sample_cur] - .snd[FILEZERO] - ->num_channels + - 1) * - (banks[sel_bank_cur] - ->sample[sel_sample_cur] - .snd[FILEZERO] - ->oversampling + - 1) * - 44100) + - phases[head], - values_to_read, fil_bytes_read); - } - if (!phase_forward) { // reverse audio for (int i = 0; i < values_len / 2; i++) { @@ -794,6 +716,7 @@ void __not_in_flash_func(i2s_callback_func)() { } phases[head] += (values_to_read_minus_peek * (phase_forward * 2 - 1)); } + } AUDIO_SOURCE_RENDERED: @@ -894,8 +817,6 @@ void __not_in_flash_func(i2s_callback_func)() { } } if (reverb_fade > 0) { - // MessageSync_printf(messagesync, "%d fade: %ld\n", reverb_activated, - // reverb_fade); reverb_fade -= 300; if (reverb_fade < 0) { reverb_fade = 0; @@ -911,8 +832,6 @@ void __not_in_flash_func(i2s_callback_func)() { FV_Reverb_process(freeverb, samples, buffer->max_sample_count); if (first_loop_ever) { - // MessageSync_printf(messagesync, "freeverb : %ld us\n", - // (time_us_32() - t0)); first_loop_ever = false; } } @@ -996,7 +915,8 @@ void __not_in_flash_func(i2s_callback_func)() { if (mode_digital_saturation > 0) { uint8_t amt = mode_digital_saturation; - if (amt > 100) amt = 100; + if (amt > 100) + amt = 100; /* Threshold mapping (Q16.16) @@ -1026,7 +946,8 @@ void __not_in_flash_func(i2s_callback_func)() { if (mode_chaos_trembler > 0) { uint8_t amt = mode_chaos_trembler; - if (amt > 100) amt = 100; + if (amt > 100) + amt = 100; /* Mapping: @@ -1064,7 +985,8 @@ void __not_in_flash_func(i2s_callback_func)() { if (mode_digital_smear > 0) { uint8_t speed = mode_digital_smear; - if (speed > 100) speed = 100; + if (speed > 100) + speed = 100; /* speed = 1 → VERY slow (multi-second sweep) @@ -1074,7 +996,8 @@ void __not_in_flash_func(i2s_callback_func)() { // how often smear_amt advances (samples) uint32_t smear_period = 5000 - (speed * 49); // ~5000 → ~100 - if (smear_period < 256) smear_period = 256; + if (smear_period < 256) + smear_period = 256; for (uint16_t i = 0; i < buffer->max_sample_count; i++) { smear_acc++; @@ -1114,7 +1037,8 @@ void __not_in_flash_func(i2s_callback_func)() { if (mode_digital_jitter > 0) { // mode_digital_jitter: 0..100 uint8_t amt = mode_digital_jitter; - if (amt > 100) amt = 100; + if (amt > 100) + amt = 100; /* Higher amt = more unstable clock @@ -1145,7 +1069,8 @@ void __not_in_flash_func(i2s_callback_func)() { if (mode_digital_bass > 0) { // mode_digital_bass: 0..100 uint8_t amt = mode_digital_bass; - if (amt > 100) amt = 100; + if (amt > 100) + amt = 100; /* ---------------- mix ---------------- */ int32_t wet = (amt << 16) / 120; // stays conservative @@ -1206,71 +1131,19 @@ void __not_in_flash_func(i2s_callback_func)() { 100 * (endTime - startTime) / (US_PER_BLOCK); cpu_utilizations_i++; -#ifdef PRINT_AUDIOBLOCKDROPS - if (sd_card_total_time > 9000) { - MessageSync_printf(messagesync, "BLOCKDROP: %ld\n", sd_card_total_time); - } -#endif if (cpu_utilizations_i == 64 || sd_card_total_time > 9000 || do_open_file) { - uint16_t cpu_utilization = 0; - for (uint8_t i = 0; i < cpu_utilizations_i; i++) { - cpu_utilization = cpu_utilization + cpu_utilizations[i]; - } -#ifdef PRINT_AUDIO_CPU_USAGE - uint32_t total_heap = getTotalHeap(); - uint32_t used_heap = total_heap - getFreeHeap(); - MessageSync_printf(messagesync, - "cpu [mem]: %2.1f [ %2.1f%% (%ld/%ld)] %d\n", - ((float)cpu_utilization) / (float)cpu_utilizations_i, - (float)(used_heap) / (float)(total_heap) * 100.0, - used_heap, total_heap, buffer->max_sample_count); - -#endif cpu_utilizations_i = 0; -#ifdef PRINT_SDCARD_TIMING - MessageSync_printf(messagesync, "sdcard%2.1f %ld %d %d %ld\n", - ((float)cpu_utilization) / 64.0, sd_card_total_time, - values_to_read, give_audio_buffer_time, - take_audio_buffer_time); -#endif } if (cpu_usage_flag == cpu_usage_flag_limit) { cpu_usage_flag = 0; reduce_cpu_usage = BLOCKS_PER_SECOND * 30 / sf->bpm_tempo; - MessageSync_printf(messagesync, "cpu_usage_flag: %d\n", reduce_cpu_usage); } else { if (cpu_utilizations[cpu_utilizations_i] > cpu_usage_limit_threshold) { -#ifdef PRINT_SDCARD_TIMING - MessageSync_printf(messagesync, "sdcard%d %ld %d %d %ld\n", - cpu_utilizations[cpu_utilizations_i], - sd_card_total_time, values_to_read, - give_audio_buffer_time, take_audio_buffer_time); -#endif cpu_usage_flag++; cpu_usage_flag_total++; -#ifdef PRINT_AUDIO_OVERLOADS - if (cpu_usage_flag_total > 0) { - clock_t currentTime = time_us_64(); - MessageSync_printf(messagesync, "cpu overloads every: %d ms\n", - (currentTime - time_of_initialization) / 1000 / - cpu_usage_flag_total); - } -#endif if (cpu_flag_counter == 0) { cpu_flag_counter = BLOCKS_PER_SECOND; } - // char fx_string[17]; - // for (uint8_t i = 0; i < 16; i++) { - // if (sf->fx_active[i]) { - // fx_string[i] = '1'; - // } else { - // fx_string[i] = '0'; - // } - // } - // fx_string[16] = retrig_beat_num > 0 ? '1' : '0'; - // MessageSync_printf(messagesync, "cpu: %d, flag: %d, fx: %s\n", - // cpu_utilizations[cpu_utilizations_i], - // cpu_usage_flag, fx_string); // turn off all fx for (uint8_t i = 0; i < 16; i++) { sf->fx_active[i] = false; @@ -1286,8 +1159,6 @@ void __not_in_flash_func(i2s_callback_func)() { } } - MessageSync_lockIfNotEmpty(messagesync); - // change phase_forward back if it was switched if (change_phase_forward) { phase_forward = !phase_forward; diff --git a/lib/button_handler.h b/lib/button_handler.h index c0e422920..1b9e5621b 100644 --- a/lib/button_handler.h +++ b/lib/button_handler.h @@ -31,7 +31,6 @@ void maybe_toggle_jump_page_lock_on_d_release(uint8_t key) { } 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; } @@ -52,7 +51,6 @@ int8_t single_step_pressed() { } void go_retrigger_3key(uint8_t key1, uint8_t key2, uint8_t key3) { - printf("[button_handler] retrigger 3key: %d %d %d\n", key1, key2, key3); debounce_quantize = 0; retrig_vol = 1.0; retrig_pitch = PITCH_VAL_MID; @@ -180,11 +178,10 @@ void toggle_off_fx(uint8_t fx_num) { update_fx(fx_num); } -void button_key_off_held(uint8_t key) { printf("off held %d\n", key); } +void button_key_off_held(uint8_t key) {} // triggers on ANY key off, used for 1-16 off's void button_key_off_any(uint8_t key) { - printf("off any %d\n", key); if (key_total_pressed < 3) { key3_activated = false; } @@ -198,7 +195,6 @@ void button_key_off_any(uint8_t key) { if (key_total_pressed == 0) { if (mode_hands_on_unmute) { if (!button_mute) { - printf("[button_handler] mode_hands_on_unmute -> mute\n"); trigger_button_mute = true; } } @@ -253,14 +249,12 @@ uint32_t tap_tempo_last = 0; uint8_t tap_tempo_hits = 0; void button_key_on_single(uint8_t key) { - printf("on single %d\n", key); if (key < 4) { if (key == KEY_A) { } } else if (key >= 4) { if (mode_hands_on_unmute) { if (button_mute) { - printf("[button_handler] mode_hands_on_unmute unmute\n"); button_mute = false; trigger_button_mute = false; } @@ -274,7 +268,6 @@ void button_key_on_single(uint8_t key) { dub_step_break = 0; dub_step_divider = 0; dub_step_beat = beat_current; - printf("dub_step_beat: %d\n", dub_step_beat); // if (toggle_chain_rec) { // Chain_add_current(chain, key - 4, bpm_timer_counter); // } @@ -289,7 +282,6 @@ void button_key_on_single(uint8_t key) { bool cued_sound_selector = false; int8_t cued_sound_last_selected = 1; void button_key_on_double(uint8_t key1, uint8_t key2) { - printf("on double %d+%d\n", key1, key2); if (key_on_buttons[KEY_A] && key_on_buttons[KEY_B]) { // make sure KEY_A is on first uint16_t key_a_on = 0; @@ -304,7 +296,6 @@ void button_key_on_double(uint8_t key1, uint8_t key2) { if (key_a_on < key_b_on) { uint8_t tempos[16] = {60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210}; - printf("[button_handler] select tempo: %d %d\n", key2, tempos[key2 - 4]); sf->bpm_tempo = tempos[key2 - 4]; DebounceDigits_set(debouncer_digits, sf->bpm_tempo, led_text_time); return; @@ -319,14 +310,12 @@ void button_key_on_double(uint8_t key1, uint8_t key2) { } do_layer_kicks = cuedsounds_do_play; cued_sound_last_selected = cuedsounds_do_play; - printf("cuedsounds_do_play: %d\n", cuedsounds_do_play); } else { // select volume cuedsounds_volume = (key2 - 4) * 255 / 16; if (cuedsounds_volume == 0) { do_layer_kicks = -1; } - printf("cuedsounds_volume: %d\n", cuedsounds_volume); } cued_sound_selector = !cued_sound_selector; #endif @@ -344,7 +333,6 @@ void button_key_on_double(uint8_t key1, uint8_t key2) { mode_buttons16 = MODE_JUMP; uint16_t val = TapTempo_tap(taptempo); if (val > 0) { - printf("tap bpm -> %d\n", val); sf->bpm_tempo = val; DebounceDigits_set(debouncer_digits, sf->bpm_tempo, led_text_time); } @@ -381,10 +369,8 @@ void button_key_on_double(uint8_t key1, uint8_t key2) { if (key2 == KEY_C) { // A+B if (button_mute) { - printf("[button_handler] button_mute off\n"); button_mute = false; } else if (!button_mute) { - printf("[button_handler] trigger button_mute\n"); trigger_button_mute = true; } @@ -408,7 +394,8 @@ void button_key_on_double(uint8_t key1, uint8_t key2) { update_repeating_timer_to_bpm(sf->bpm_tempo); button_mute = false; } else { - if (!button_mute) trigger_button_mute = true; + if (!button_mute) + trigger_button_mute = true; do_stop_playback = true; } } else if (key2 > 3) { @@ -418,13 +405,10 @@ void button_key_on_double(uint8_t key1, uint8_t key2) { sel_bank_select = banks_with_samples[(key2 - 4) % banks_with_samples_num]; KEY_C_sample_select = true; - printf("sel_bank_select: %d\n", sel_bank_select); } else { sel_bank_next = sel_bank_select; sel_sample_next = ((key2 - 4) % (banks[sel_bank_next]->num_samples)); tunneling_original_sample = sel_sample_next; - printf("sel_bank_next: %d\n", sel_bank_next); - printf("sel_sample_next: %d\n", sel_sample_next); fil_current_change = true; KEY_C_sample_select = false; } @@ -442,7 +426,6 @@ void button_key_on_double(uint8_t key1, uint8_t key2) { !sequencerhandler[mode_buttons16].playing; if (sequencerhandler[mode_buttons16].playing) { - printf("[button_handler] sequence %d playing on\n", mode_buttons16); if (Sequencer_has_data( sf->sequencers[mode_buttons16] [sf->sequence_sel[mode_buttons16]])) { @@ -450,11 +433,9 @@ void button_key_on_double(uint8_t key1, uint8_t key2) { sf->sequencers[mode_buttons16][sf->sequence_sel[mode_buttons16]], true); } else { - printf("[button_handler] sequence %d has no data\n", mode_buttons16); sequencerhandler[mode_buttons16].playing = false; } } else { - printf("[button_handler] sequence %d playing off\n", mode_buttons16); Sequencer_stop( sf->sequencers[mode_buttons16][sf->sequence_sel[mode_buttons16]]); if (mode_buttons16 == MODE_BASS) { @@ -476,9 +457,6 @@ void button_key_on_double(uint8_t key1, uint8_t key2) { // todo [0] should be which sequencer is currently on Sequencer_clear( sf->sequencers[mode_buttons16][sf->sequence_sel[mode_buttons16]]); - printf("[button_handler] sequence %d recording on\n", mode_buttons16); - } else { - printf("[button_handler] sequence %d recording off\n", mode_buttons16); } } else if (key2 > 3) { @@ -505,12 +483,10 @@ void button_key_on_double(uint8_t key1, uint8_t key2) { if (key2 == KEY_B) { // D+B // do load - printf("[button_handler] loading %d to sd card\n", savefile_current); savefile_do_load(); } else if (key2 == KEY_C) { // D+C // do save - printf("[button_handler] saving %d to sd card\n", savefile_current); // save the current bank and sample sf->bank = sel_bank_cur; sf->sample = sel_sample_cur; @@ -522,7 +498,6 @@ void button_key_on_double(uint8_t key1, uint8_t key2) { // load prevoius file f_open(&fil_current, fil_current_name, FA_READ); sync_using_sdcard = false; - printf("[button_handler] loading %s again\n", fil_current_name); savefile_has_data[savefile_current] = true; } else if (key2 == KEY_A) { // D+A @@ -539,15 +514,8 @@ bool button_handler(ButtonMatrix *bm) { key_timer++; } if (key_timer == led_text_time && key_pressed_num > 0) { - // create string - char key_pressed_str[256]; - int pos = snprintf(key_pressed_str, sizeof(key_pressed_str), - "[button_handler](%d)(%ld)combo: ", key_pressed_num, - key_timer_on); - if (key_pressed_num > 2) { if (key_pressed[0] == 1 && key_pressed[1] == 0) { - printf("[button_handler] customseq\n"); random_sequence_length = key_pressed_num - 2; for (uint16_t i = 2; i < key_pressed_num; i++) { random_sequence_arr[i - 2] = key_pressed[i] - 4; @@ -555,35 +523,12 @@ bool button_handler(ButtonMatrix *bm) { } } - // Ensure the snprintf was successful and within the buffer size - if (pos >= 0 && pos < sizeof(key_pressed_str)) { - for (uint8_t i = 0; i < key_pressed_num; i++) { - // Calculate remaining space in the buffer - int remaining = sizeof(key_pressed_str) - pos; - if (remaining > 0) { - int ret = - snprintf(key_pressed_str + pos, remaining, "%d ", key_pressed[i]); - // Check if snprintf was successful - if (ret < 0 || ret >= remaining) { - // Handle error (e.g., truncate string, log error, etc.) - key_pressed_str[sizeof(key_pressed_str) - 1] = '\0'; - break; - } - pos += ret; - } else { - // No space left in the buffer - break; - } - } - printf("%s\n", key_pressed_str); - } - // if in RAND mode, generate new one if (key_pressed_num == 1 && key_timer_on > 400 && random_sequence_length > 0 && key_pressed[0] > 3) { do_random_sequence_len(key_pressed[0] - 3); char random_sequence_str[10]; - sprintf(random_sequence_str, "%d", random_sequence_length); + format_int32_decimal(random_sequence_str, random_sequence_length); DebounceDigits_setText(debouncer_digits, random_sequence_str, led_text_time); } @@ -599,14 +544,11 @@ bool button_handler(ButtonMatrix *bm) { uint8_t merge_sequence_num = key_pressed[1] - 4; if (!Sequencer_has_data( sf->sequencers[mode_buttons16][merge_sequence_num])) { - printf("[button_handler] merging sequences into sequence %d: \n", - merge_sequence_num); // copy the first sequence into the empty slot Sequencer_copy(sf->sequencers[mode_buttons16][key_pressed[2] - 4], sf->sequencers[mode_buttons16][merge_sequence_num]); // merge the rest into that slot for (uint8_t i = 3; i < key_pressed_num; i++) { - printf("merging %d\n", key_pressed[i] - 4); Sequencer *merged = Sequencer_merge( sf->sequencers[mode_buttons16][merge_sequence_num], sf->sequencers[mode_buttons16][key_pressed[i] - 4]); @@ -614,7 +556,6 @@ bool button_handler(ButtonMatrix *bm) { sf->sequencers[mode_buttons16][merge_sequence_num]); free(merged); } - Sequencer_print(sf->sequencers[mode_buttons16][merge_sequence_num]); sf->sequence_sel[mode_buttons16] = merge_sequence_num; sequencerhandler[mode_buttons16].playing = true; Sequencer_play(sf->sequencers[mode_buttons16][merge_sequence_num], @@ -631,7 +572,6 @@ bool button_handler(ButtonMatrix *bm) { ->sample[sel_sample_cur] .snd[FILEZERO] ->one_shot) { - printf("toggle one shot OFF "); banks[sel_bank_cur]->sample[sel_sample_cur].snd[FILEZERO]->one_shot = false; banks[sel_bank_cur]->sample[sel_sample_cur].snd[FILEZERO]->play_mode = @@ -639,17 +579,14 @@ bool button_handler(ButtonMatrix *bm) { DebounceDigits_setText(debouncer_digits, "ONESHOT OFF", led_text_time); } else { - printf("toggle one shot ON "); banks[sel_bank_cur]->sample[sel_sample_cur].snd[FILEZERO]->one_shot = true; banks[sel_bank_cur]->sample[sel_sample_cur].snd[FILEZERO]->play_mode = PLAY_SPLICE_STOP; DebounceDigits_setText(debouncer_digits, "ONESHOT ON", led_text_time); } - printf("combo: 8 9 8!!!\n"); } else if (key_pressed[0] == 10 && key_pressed[1] == 11 && key_pressed[2] == 10) { - printf("combo: 10 11 10!!!\n"); if (banks[sel_bank_cur] ->sample[sel_sample_cur] .snd[FILEZERO] @@ -662,13 +599,8 @@ bool button_handler(ButtonMatrix *bm) { banks[sel_bank_cur]->sample[sel_sample_cur].snd[FILEZERO]->play_mode = 0; } - printf("play_mode: %d\n", banks[sel_bank_cur] - ->sample[sel_sample_cur] - .snd[FILEZERO] - ->play_mode); } else if (key_pressed[0] == 4 && key_pressed[1] == 5 && key_pressed[2] == 4) { - printf("toggling variable splice\n"); banks[sel_bank_cur] ->sample[sel_sample_cur] .snd[FILEZERO] @@ -730,7 +662,8 @@ bool button_handler(ButtonMatrix *bm) { if (random_sequence_length == 0) { // create string with the length char random_sequence_str[10]; - sprintf(random_sequence_str, "RAND %d", do_random_sequence(true)); + format_prefixed_int32(random_sequence_str, "RAND ", + do_random_sequence(true)); DebounceDigits_setText(debouncer_digits, random_sequence_str, led_text_time); } else { @@ -749,7 +682,6 @@ bool button_handler(ButtonMatrix *bm) { } else if (key_pressed[0] == 4 && key_pressed[1] == 5 && key_pressed[2] == 6 && key_pressed[3] == 7) { sf->stay_in_sync = !sf->stay_in_sync; - printf("toggling in sync mode: %d\n", sf->stay_in_sync); if (sf->stay_in_sync) { DebounceDigits_setText(debouncer_digits, "LOCK OONN", led_text_time); } else { @@ -758,9 +690,7 @@ bool button_handler(ButtonMatrix *bm) { } } else if (key_pressed[0] == 7 && key_pressed[1] == 10 && key_pressed[2] == 13 && key_pressed[3] == 16) { - printf("combo: 7 10 13 16!!!\n"); only_play_kicks = !only_play_kicks; - printf("only_play_kicks: %d\n", only_play_kicks); if (only_play_kicks) { DebounceDigits_setText(debouncer_digits, "KICKS", led_text_time); } else { @@ -769,7 +699,6 @@ bool button_handler(ButtonMatrix *bm) { } else if (key_pressed[0] == 16 && key_pressed[1] == 13 && key_pressed[2] == 10 && key_pressed[3] == 6) { only_play_snares = !only_play_snares; - printf("only_play_snares: %d\n", only_play_snares); if (only_play_snares) { DebounceDigits_setText(debouncer_digits, "SNARES", led_text_time); } else { @@ -788,10 +717,8 @@ bool button_handler(ButtonMatrix *bm) { ->sample[sel_sample_cur] .snd[FILEZERO] ->tempo_match) { - printf("combo: enabled to tempo match mode\n"); DebounceDigits_setText(debouncer_digits, "MATCH OONN", led_text_time); } else { - printf("combo: disabled tempo match mode\n"); DebounceDigits_setText(debouncer_digits, "MATCH OOFFF", led_text_time); } @@ -799,8 +726,6 @@ bool button_handler(ButtonMatrix *bm) { } else if (key_pressed[0] == 12 && key_pressed[1] == 13 && key_pressed[2] == 14 && key_pressed[3] == 15) { sf->do_retrig_pitch_changes = !sf->do_retrig_pitch_changes; - printf("combo: enabled to pitch retrig mode: %d\n", - sf->do_retrig_pitch_changes); if (sf->do_retrig_pitch_changes) { DebounceDigits_setText(debouncer_digits, "PIT OONN", led_text_time); } else { @@ -812,8 +737,7 @@ bool button_handler(ButtonMatrix *bm) { if (sf->do_retrig_volume_ramps) { DebounceDigits_setText(debouncer_digits, "RAMP OONN", led_text_time); } else { - DebounceDigits_setText(debouncer_digits, "RAMP OOFF", - led_text_time); + DebounceDigits_setText(debouncer_digits, "RAMP OOFF", led_text_time); } } } else if (key_pressed_num == 8) { @@ -822,10 +746,8 @@ bool button_handler(ButtonMatrix *bm) { key_pressed[6] == 10 && key_pressed[7] == 6) { clock_out_do = !clock_out_do; if (clock_out_do) { - printf("[button_handler]: combo: clock out enabled\n"); DebounceDigits_setText(debouncer_digits, "SYNC OONN", led_text_time); } else { - printf("[button_handler]: combo: clock out disabled\n"); DebounceDigits_setText(debouncer_digits, "SYNC OOFFF", led_text_time); } } @@ -890,10 +812,6 @@ bool button_handler(ButtonMatrix *bm) { key_on_buttons[i] = 0; } } - } else if (key_held_on) { - printf("off %d+%d\n", key_held_num, bm->off[i]); - } else { - printf("off %d\n", bm->off[i]); } if (bm->off[i] < 4) { @@ -944,7 +862,6 @@ bool button_handler(ButtonMatrix *bm) { } } if (all_off) { - printf("playing note: %d\n", octave + bm->on[i] - 4); WaveBass_note_on(wavebass, octave + bm->on[i] - 4); if (sequencerhandler[2].recording) { Sequencer_add(sf->sequencers[2][sf->sequence_sel[2]], @@ -980,7 +897,6 @@ bool button_handler(ButtonMatrix *bm) { bool all_h = true; for (uint8_t i = 0; i < 3; i++) { keys[i] = indexes[BUTTONMATRIX_BUTTONS_MAX - 3 + i]; - printf("keys[%d]: %d\n", i, keys[i]); if (keys[i] < 4) { all_h = false; } @@ -1358,8 +1274,7 @@ bool button_handler(ButtonMatrix *bm) { LEDS_set(leds, 0, LED_BRIGHT); LEDS_set(leds, 1, LED_BLINK); LEDS_set(leds, 2, - (jump_page_lock & JUMP_PAGE_LOCK_FIRST) ? LED_BRIGHT - : LED_NONE); + (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); diff --git a/lib/buttonmatrix3.h b/lib/buttonmatrix3.h index 8a0a40d79..f3505a851 100644 --- a/lib/buttonmatrix3.h +++ b/lib/buttonmatrix3.h @@ -22,28 +22,6 @@ typedef struct ButtonMatrix { uint32_t off_time[BUTTONMATRIX_BUTTONS_MAX]; } ButtonMatrix; -void ButtonMatrix_dec_to_binary(ButtonMatrix *bm, uint32_t num) { - if (num == 0) { - printf("\n"); - } - for (uint8_t i = 0; i < BUTTONMATRIX_BUTTONS_MAX; i++) { - // if ((num >> i) & 1) { - // printf("%d ", bm->mapping[i]); - // } - uint8_t bit = (num >> i) & 1; - printf("%u", bit); // Print the bit - } - printf("\n"); -} - -void ButtonMatrix_print_buttons(ButtonMatrix *bm) { - for (uint8_t i = 0; i < BUTTONMATRIX_BUTTONS_MAX; i++) { - printf("%d) %d\n", i, bm->button_on[i]); - } - printf("\n"); - return; -} - ButtonMatrix *ButtonMatrix_create(uint base_input, uint base_output) { ButtonMatrix *bm = (ButtonMatrix *)malloc(sizeof(ButtonMatrix)); bm->pio = pio0; @@ -182,7 +160,6 @@ void ButtonMatrix_read(ButtonMatrix *bm) { pio_sm_clear_fifos(bm->pio, bm->sm); sleep_ms(1); if (pio_sm_is_rx_fifo_empty(bm->pio, bm->sm)) { - printf("fifo empty\n"); return; } value = pio_sm_get(bm->pio, bm->sm); diff --git a/lib/delay.h b/lib/delay.h index fd7208b33..fcf897383 100644 --- a/lib/delay.h +++ b/lib/delay.h @@ -42,7 +42,6 @@ void Delay_setDuration(Delay *self, uint16_t num_samples) { num_samples = DELAY_RINGBUFFER_SIZE; } if (num_samples != self->duration) { - printf("[delay] duration %d\n", num_samples); self->duration = num_samples; } } @@ -56,7 +55,6 @@ void Delay_setFeedback(Delay *self, uint8_t feedback) { feedback = 16; } if (feedback != self->feedback) { - printf("[delay] feedback %d\n", feedback); self->feedback = feedback; } } @@ -65,8 +63,8 @@ void Delay_setFeedbackf(Delay *self, float feedback) { Delay_setFeedback(self, (uint8_t)(feedback * 8.0f)); } -void __not_in_flash_func(Delay_process)(Delay *self, int32_t *samples, uint16_t num_samples, - uint8_t channel) { +void __not_in_flash_func(Delay_process)(Delay *self, int32_t *samples, + uint16_t num_samples, uint8_t channel) { for (int ii = 0; ii < num_samples; ii++) { while (self->ringbuffer_index > self->duration) { self->ringbuffer_index -= self->duration; diff --git a/lib/ectocore.h b/lib/ectocore.h index 65731a4a0..6e0d1ad9d 100644 --- a/lib/ectocore.h +++ b/lib/ectocore.h @@ -3,10 +3,10 @@ #include "clockhandling.h" // #include "break_knob.h" +#include "ectocore_loopstart_trig.h" #include "mcp3208.h" #include "midicallback.h" #include "onewiremidi2.h" -#include "ectocore_loopstart_trig.h" #ifdef INCLUDE_MIDI #include "midi_comm_callback.h" #endif @@ -85,7 +85,6 @@ void update_gpios_for_mode() { #endif break; case TRIGGER_MODE_HH: - printf("[ectocore] trigger mode: hh\n"); #ifdef ECTOCORE_VERSION_3 gpio_put(GPIO_MODE_LEDA, 0); gpio_put(GPIO_MODE_LEDB, 1); @@ -98,7 +97,6 @@ void update_gpios_for_mode() { #endif break; case TRIGGER_MODE_RANDOM: - printf("[ectocore] trigger mode: random\n"); #ifdef ECTOCORE_VERSION_3 gpio_put(GPIO_MODE_LEDA, 1); gpio_put(GPIO_MODE_LEDB, 1); @@ -534,16 +532,10 @@ void dust_1() { bool clock_input_absent = true; -// CV monitoring feature (bank+mode button toggle) -bool cv_monitor_active = false; -uint32_t cv_monitor_start_time = 0; -uint32_t cv_monitor_last_print = 0; -#define CV_MONITOR_INTERVAL_MS 100 -#define CV_MONITOR_DURATION_MS 60000 - ClockInput *clockinput; void gpio_callback(uint gpio, uint32_t events) { - if (gpio != GPIO_CLOCK_IN) return; + if (gpio != GPIO_CLOCK_IN) + return; bool clock_up = events & 4; if (cv_reset_override == CV_CLOCK) { // check GPIO_CLOCK_IN @@ -573,7 +565,6 @@ bool dont_wait = false; void __not_in_flash_func(input_handling)() { // flash bad signs while (!fil_is_open) { - printf("waiting to start\n"); sleep_ms(10); } @@ -679,10 +670,9 @@ void __not_in_flash_func(input_handling)() { #ifdef INCLUDE_MIDI // Hardware MIDI-in (separate from clock input). - Onewiremidi *onewiremidi = - Onewiremidi_new(pio0, 3, GPIO_MIDI_IN, midi_note_on, midi_note_off, - midi_start, midi_continue, midi_stop, midi_timing, - midi_control_change); + Onewiremidi *onewiremidi = Onewiremidi_new( + pio0, 3, GPIO_MIDI_IN, midi_note_on, midi_note_off, midi_start, + midi_continue, midi_stop, midi_timing, midi_control_change); #endif clockinput = ClockInput_create(GPIO_CLOCK_IN, clock_handling_up, clock_handling_down, clock_handling_start); @@ -755,18 +745,12 @@ void __not_in_flash_func(input_handling)() { // reset probabilities probability_of_random_jump = 0; } else if (debounce_startup == 108) { - printf("[ectocore] startup\n"); // read flash data uint16_t calibration_data[8]; if (PersistentState_load_calibration(calibration_data)) { for (uint8_t i = 0; i < 8; i++) { sf->center_calibration[i] = calibration_data[i]; } - printf("[ectocore] calibration data loaded from flash\n"); - } else { - printf( - "[ectocore] calibration data is corrupted or missing, using " - "defaults\n"); } } else if (debounce_startup >= 100 && debounce_startup < 108) { uint8_t i = debounce_startup - 100; @@ -774,7 +758,6 @@ void __not_in_flash_func(input_handling)() { sleep_ms(1); sf->center_calibration[i] = MCP3208_read(mcp3208, i, false); if (i == 0) { - printf("[ectocore] write calibration\n"); uint16_t flash_time = 250; for (uint8_t ii = 0; ii < 20; ii++) { // make the LEDS go RED @@ -803,7 +786,6 @@ void __not_in_flash_func(input_handling)() { } } } - printf("[ectocore] calibrate %d=%d,", i, sf->center_calibration[i]); } } @@ -818,9 +800,7 @@ void __not_in_flash_func(input_handling)() { if (clock_input_absent_new != clock_input_absent) { clock_input_absent = clock_input_absent_new; if (clock_input_absent) { - printf("[ectocore] clock input absent\n"); } else { - printf("[ectocore] clock input present\n"); } } } @@ -917,7 +897,6 @@ void __not_in_flash_func(input_handling)() { cv_plugged[j] = true; cv_detection_count[j] = 0; last_mean_signal_time = 0; // Trigger mean recalculation - printf("[ectocore] cv_%d plugged\n", j); } } else if (is_signal[j] && cv_plugged[j]) { // Potential unplug detected @@ -927,7 +906,6 @@ void __not_in_flash_func(input_handling)() { cv_detection_count[j] = 0; cv_was_unplugged[j] = true; last_mean_signal_time = 0; // Trigger mean recalculation - printf("[ectocore] cv_%d unplugged\n", j); } } else { // State matches expectation - reset counter @@ -1103,15 +1081,10 @@ void __not_in_flash_func(input_handling)() { int char_input = getchar_timeout_us(10); if (char_input >= 0) { if (char_input == 118) { - printf("version=v7.3.0\n"); + puts("version=v7.3.0"); } } - if (MessageSync_hasMessage(messagesync)) { - MessageSync_print(messagesync); - MessageSync_clear(messagesync); - } - #ifdef PRINT_SDCARD_TIMING // random stuff if (random_integer_in_range(1, 20000) < 10) { @@ -1211,7 +1184,6 @@ void __not_in_flash_func(input_handling)() { // mode selection // 0 - 100 mode_chaos_trembler = val * 100 / 1024; - printf("[ectocore] mode_chaos_trembler %d\n", mode_chaos_trembler); ws2812_set_wheel(ws2812, val * 4, 255, 0, 0); } else if (gpio_get(GPIO_BTN_BANK) == 0 && fil_current_change == false) { @@ -1287,8 +1259,6 @@ void __not_in_flash_func(input_handling)() { if (mode_held_duration > MODE_HOLD_DURATION_THRESHOLD) { // mode_break_index setting (0 to 20) mode_digital_saturation = val * 100 / 1024; - printf("[ectocore] mode_digital_saturation %d\n", - mode_digital_saturation); ws2812_set_wheel(ws2812, val * 4, 255, 0, 0); } else { break_set(val, false, true); @@ -1298,7 +1268,6 @@ void __not_in_flash_func(input_handling)() { if (mode_held_duration > MODE_HOLD_DURATION_THRESHOLD) { // mode_amiga_index setting (0 to 20) mode_amiga_index = val * 37 / 1024; - printf("[ectocore] amiga mode %d\n", mode_amiga_index); ws2812_set_wheel(ws2812, val * 4, 255, 0, 0); } else if (gpio_btn_taptempo_val == 0) { // TODO: change the filter cutoff! @@ -1400,7 +1369,6 @@ void __not_in_flash_func(input_handling)() { if (mode_held_duration > MODE_HOLD_DURATION_THRESHOLD) { // mode_digital_depth setting (0 to 100) mode_digital_smear = val * 100 / 1024; - printf("[ectocore] mode_digital_smear %d\n", mode_digital_smear); ws2812_set_wheel(ws2812, val * 4, 255, 0, 0); } else if (gpio_btn_taptempo_val == 0) { planned_retrig_probability = val * 100 / 1024; @@ -1425,7 +1393,6 @@ void __not_in_flash_func(input_handling)() { if (mode_held_duration > MODE_HOLD_DURATION_THRESHOLD) { // mode_amiga_depth setting (0 to 100) mode_digital_jitter = val * 100 / 1024; - printf("[ectocore] mode_digital_jitter %d\n", mode_digital_jitter); ws2812_set_wheel(ws2812, val * 4, 255, 0, 0); } else if (gpio_btn_taptempo_val == 0) { if (val < 512 - 24) { @@ -1486,8 +1453,6 @@ void __not_in_flash_func(input_handling)() { uint32_t mode_held_new_duration = current_time - mode_held_start_time; if (mode_held_new_duration >= MODE_HOLD_DURATION_THRESHOLD && mode_held_duration < MODE_HOLD_DURATION_THRESHOLD) { - printf("[ectocore] MODE held for %dms\n", - MODE_HOLD_DURATION_THRESHOLD); if (ectocore_trigger_mode > 0) { ectocore_trigger_mode--; } else { @@ -1638,7 +1603,8 @@ void __not_in_flash_func(input_handling)() { // A+C if (!playback_stopped && !do_stop_playback) { // printf("[ectocore] ectocore stop\n"); - if (!button_mute) trigger_button_mute = true; + if (!button_mute) + trigger_button_mute = true; do_stop_playback = true; } else if (playback_stopped && !do_restart_playback) { // printf("[ectocore] ectocore start\n"); @@ -1683,22 +1649,6 @@ void __not_in_flash_func(input_handling)() { } } } - // check for CV monitor toggle (bank+mode, but not mult) - if (val == 1 && gpio_btn_state[BTN_BANK] > 0 && - gpio_btn_state[BTN_MODE] > 0 && gpio_btn_state[BTN_MULT] == 0 && - gpio_btn_state[BTN_TAPTEMPO] == 0) { - if (gpio_btns[i] == GPIO_BTN_BANK || gpio_btns[i] == GPIO_BTN_MODE) { - // Toggle CV monitoring feature - cv_monitor_active = !cv_monitor_active; - if (cv_monitor_active) { - cv_monitor_start_time = current_time; - cv_monitor_last_print = 0; - printf("[ectocore] CV monitor enabled\n"); - } else { - printf("[ectocore] CV monitor disabled\n"); - } - } - } // check for reset if (gpio_btn_state[BTN_BANK] > 0 && gpio_btn_state[BTN_MODE] > 0 && gpio_btn_state[BTN_MULT] > 0) { @@ -1755,18 +1705,10 @@ void __not_in_flash_func(input_handling)() { } if (do_try_change) { sync_using_sdcard = true; - // measure the time it takes - uint32_t time_start = time_us_32(); - FRESULT fr = f_close(&fil_current); - if (fr != FR_OK) { - printf("[main] f_close error: %s\n", FRESULT_str(fr)); - } - sprintf(fil_current_name, "bank%d/%d.%d.wav", sel_bank_cur + 1, - sel_sample_cur, sel_variation_next + audio_variant * 2); - fr = f_open(&fil_current, fil_current_name, FA_READ); - if (fr != FR_OK) { - printf("[main] f_open error: %s\n", FRESULT_str(fr)); - } + f_close(&fil_current); + format_sample_filename(fil_current_name, sel_bank_cur, sel_sample_cur, + sel_variation_next + audio_variant * 2); + f_open(&fil_current, fil_current_name, FA_READ); // TODO: fix this // if sel_variation_next == 0 @@ -1780,30 +1722,6 @@ void __not_in_flash_func(input_handling)() { } } - // CV monitoring - print raw CV values every 100ms for 1 minute - if (cv_monitor_active) { - uint32_t elapsed = current_time - cv_monitor_start_time; - - // Check if 1 minute has elapsed - if (elapsed >= CV_MONITOR_DURATION_MS) { - cv_monitor_active = false; - printf("[ectocore] CV monitor disabled (timeout)\n"); - } else if (current_time - cv_monitor_last_print >= - CV_MONITOR_INTERVAL_MS) { - // Read raw CV values - int16_t cv_amen = MCP3208_read(mcp3208, MCP_CV_AMEN, false); - int16_t cv_break = MCP3208_read(mcp3208, MCP_CV_BREAK, false); - int16_t cv_clock = gpio_get(GPIO_CLOCK_IN); // Digital read for clock - int16_t cv_sample = MCP3208_read(mcp3208, MCP_CV_SAMPLE, false); - - // Print in requested format: cv1=x,cv2=x,cv3=x,cv4=x - printf("cv1=%d,cv2=%d,cv3=%d,cv4=%d\n", cv_amen, cv_break, cv_clock, - cv_sample); - - cv_monitor_last_print = current_time; - } - } - // Fallback trig at playback start or strict loop wrap when a selected // mode has a transient at the beginning of the file. { @@ -1814,8 +1732,7 @@ void __not_in_flash_func(input_handling)() { uint8_t slice_num = sample_info != NULL ? sample_info->slice_num : 0; uint32_t transport_start_generation = ecto_loopstart_transport_start_generation; - bool transport_started = - transport_start_generation != + bool transport_started = transport_start_generation != loopstart_trig_seen_transport_start_generation; loopstart_trig_seen_transport_start_generation = transport_start_generation; diff --git a/lib/freeverb_fp.h b/lib/freeverb_fp.h index a5c46639c..b7f5dd88e 100644 --- a/lib/freeverb_fp.h +++ b/lib/freeverb_fp.h @@ -2,6 +2,7 @@ #include #include +#include #include "fixedpoint.h" @@ -19,7 +20,14 @@ void FV_AllPass_set_feedback(FV_AllPass *self, int32_t feedback) { FV_AllPass *FV_AllPass_malloc(int bufsize, int32_t feedback) { FV_AllPass *self = (FV_AllPass *)malloc(sizeof(FV_AllPass)); + if (self == NULL) { + return NULL; + } self->buffer = (int32_t *)malloc(bufsize * sizeof(int32_t)); + if (self->buffer == NULL) { + free(self); + return NULL; + } memset(self->buffer, 0, bufsize * sizeof(int32_t)); self->bufsize = bufsize; self->bufidx = 0; @@ -41,7 +49,8 @@ static inline int32_t FV_AllPass_process(FV_AllPass *self, int32_t input) { int32_t bufout; bufout = self->buffer[self->bufidx]; self->buffer[self->bufidx] = input + q16_16_multiply(bufout, self->feedback); - if (++(self->bufidx) >= self->bufsize) self->bufidx = 0; + if (++(self->bufidx) >= self->bufsize) + self->bufidx = 0; return -input + bufout; } @@ -67,12 +76,19 @@ void FV_Comb_set_damp(FV_Comb *self, int32_t damp) { FV_Comb *FV_Comb_malloc(int bufsize, int32_t feedback, int32_t damp) { FV_Comb *self = (FV_Comb *)malloc(sizeof(FV_Comb)); + if (self == NULL) { + return NULL; + } self->feedback = feedback; self->filterstore = 0; self->damp1 = damp; self->damp2 = Q16_16_1 - damp; self->bufidx = 0; self->buffer = (int32_t *)malloc(bufsize * sizeof(int32_t)); + if (self->buffer == NULL) { + free(self); + return NULL; + } memset(self->buffer, 0, bufsize * sizeof(int32_t)); self->bufsize = bufsize; return self; @@ -96,13 +112,17 @@ static inline int32_t FV_Comb_process(FV_Comb *self, int32_t input) { q16_16_multiply(self->filterstore, self->damp1); self->buffer[self->bufidx] = input + q16_16_multiply(self->filterstore, self->feedback); - if (++self->bufidx >= self->bufsize) self->bufidx = 0; + if (++self->bufidx >= self->bufsize) + self->bufidx = 0; return output; } // tuning #define FV_NUMCOMBS_MAX 8 #define FV_NUMALLPASSES_MAX 4 +#define FV_NUMCOMBS_DEFAULT 1 +#define FV_NUMALLPASSES_DEFAULT 1 +#define FV_REVERB_HEAP_RESERVE 4096 #define FV_MUTED 0 #define FV_FIXEDGAIN (q16_16_float_to_fp(0.015f)) #define FV_SCALEWET (3 * Q16_16_1) @@ -141,6 +161,8 @@ typedef struct FV_Reverb { } FV_Reverb; +void FV_Reverb_free(FV_Reverb *self); + int FV_Reverb_heap_size(int num_combs, int num_allpasses) { int total_size = sizeof(FV_Reverb); for (int i = 0; i < num_combs; i++) { @@ -184,15 +206,12 @@ void FV_Reverb_set_wet(FV_Reverb *self, int32_t wet) { FV_Reverb *FV_Reverb_malloc(int32_t roomsize, int32_t damp, int32_t wet, int32_t dry) { - int8_t num_allpasses = 3; - int8_t num_combs = 8; - for (int i = 0; i <= FV_NUMALLPASSES_MAX; i++) { - num_combs = i; - if (getFreeHeap() < FV_Reverb_heap_size(num_combs, num_allpasses)) { - break; - } - } - if (num_combs <= 0 || num_allpasses <= 0) { + const int8_t num_combs = FV_NUMCOMBS_DEFAULT; + const int8_t num_allpasses = FV_NUMALLPASSES_DEFAULT; + const int heap_size = FV_Reverb_heap_size(num_combs, num_allpasses); + if (getFreeHeap() < (uint32_t)(heap_size + FV_REVERB_HEAP_RESERVE)) { + printf("[FV_Reverb_malloc] skipped: need %d bytes plus %d-byte reserve\n", + heap_size, FV_REVERB_HEAP_RESERVE); return NULL; } printf("[FV_Reverb_malloc] num_combs: %d, num_allpasses: %d\n", num_combs, @@ -202,8 +221,7 @@ FV_Reverb *FV_Reverb_malloc(int32_t roomsize, int32_t damp, int32_t wet, if (self == NULL) { return NULL; } - self->num_combs = num_combs; - self->num_allpasses = num_allpasses; + memset(self, 0, sizeof(*self)); self->width = Q16_16_1; self->roomsize = q16_16_multiply(roomsize, FV_SCALEROOM) + FV_OFFSETROOM; self->damp = q16_16_multiply(damp, FV_SCALEDAMP); @@ -212,30 +230,42 @@ FV_Reverb *FV_Reverb_malloc(int32_t roomsize, int32_t damp, int32_t wet, self->wet1 = self->wet * (self->width / 2 + 0.5); self->wet2 = self->wet * ((1 - self->width) / 2); - self->gain = q16_16_float_to_fp( - 1.0 / (float)(self->num_combs + self->num_allpasses) / 6.0f); + self->gain = + q16_16_float_to_fp(1.0 / (float)(num_combs + num_allpasses) / 6.0f); - for (int i = 0; i < self->num_combs; i++) { + for (int i = 0; i < num_combs; i++) { self->combL[i] = FV_Comb_malloc(combtunings[i], self->roomsize, self->damp); if (self->combL[i] == NULL) { - self->num_combs = i + 1; - break; + goto allocation_failed; } self->combR[i] = FV_Comb_malloc(combtunings[i] + FV_STEREOSPREAD, self->roomsize, self->damp); if (self->combR[i] == NULL) { FV_Comb_free(self->combL[i]); - self->num_combs = i + 1; - break; + self->combL[i] = NULL; + goto allocation_failed; } + self->num_combs++; } - for (int i = 0; i < self->num_allpasses; i++) { + for (int i = 0; i < num_allpasses; i++) { self->allpassL[i] = FV_AllPass_malloc(allpasstunings[i], self->damp); self->allpassR[i] = FV_AllPass_malloc(allpasstunings[i] + FV_STEREOSPREAD, self->damp); + if (self->allpassL[i] == NULL || self->allpassR[i] == NULL) { + FV_AllPass_free(self->allpassL[i]); + FV_AllPass_free(self->allpassR[i]); + self->allpassL[i] = NULL; + self->allpassR[i] = NULL; + goto allocation_failed; + } + self->num_allpasses++; } // printf("[freeverb_fp] allocated\n"); return self; + +allocation_failed: + FV_Reverb_free(self); + return NULL; } void FV_Reverb_free(FV_Reverb *self) { @@ -260,7 +290,7 @@ void FV_Reverb_free(FV_Reverb *self) { void FV_Reverb_process(FV_Reverb *self, int32_t *buf, unsigned int nr_samples) { int32_t outL, outR, inputL, inputR; - for (int i = 0; i < nr_samples; i++) { + for (unsigned int i = 0; i < nr_samples; i++) { outL = outR = 0; // convert int32_t to float inputL = q16_16_multiply(buf[2 * i + 0], self->gain); diff --git a/lib/globals.h b/lib/globals.h index 4fb2d857e..8f1a70283 100644 --- a/lib/globals.h +++ b/lib/globals.h @@ -285,7 +285,6 @@ DebounceUint8 *debouncer_uint8[DEBOUNCE_UINT8_NUM]; DebounceDigits *debouncer_digits; #endif -MessageSync *messagesync; bool sdcard_startup_is_starting = false; volatile bool button_mute = false; bool trigger_button_mute = false; @@ -626,11 +625,6 @@ void do_update_phase_from_beat_current() { beat_current_show = slice; banks[sel_bank_cur]->sample[sel_sample_cur].snd[FILEZERO]->slice_current = slice; -#ifdef INCLUDE_MIDI - if (midi_input_activated) { - printf_sysex("slice=%d", slice); - } -#endif if (phase_forward) { phase_new = banks[sel_bank_cur] ->sample[sel_sample_cur] @@ -727,7 +721,7 @@ void step_sequencer_emit(uint8_t key) { #endif key_do_jump(key); } -void step_sequencer_stop() { printf("stop\n"); } +void step_sequencer_stop() {} uint8_t do_random_sequence(bool on) { if (on) { diff --git a/lib/includes.h b/lib/includes.h index e52023531..8916066e9 100644 --- a/lib/includes.h +++ b/lib/includes.h @@ -118,10 +118,13 @@ bool usb_midi_present = false; #include "filterexp.h" #include "flashmem.h" #include "persistent_state.h" +#ifdef INCLUDE_ECTOCORE +#include "freeverb_fp.h" +#else #include "freeverb_fp_mono.h" +#endif #include "gate.h" #include "knob_change.h" -#include "messagesync.h" #include "sequencehandler.h" #include "tapedelay.h" #include "taptempo.h" diff --git a/lib/ledtext.h b/lib/ledtext.h index c75a8b42c..80423dbd2 100644 --- a/lib/ledtext.h +++ b/lib/ledtext.h @@ -27,15 +27,11 @@ void LEDText_showGlyph(LEDText *lt, LEDS *leds, uint8_t char_glyph) { for (uint8_t i = 0; i < 4; i++) { uint8_t b = tinyfont_glyphs[char_index + i]; - printf("0x%02X: ", b); for (uint8_t j = 4 - (char_side * 4); j < 8 - char_side * 4; j++) { uint8_t led_index = (j * 4 + i + 4 - (16 * (1 - char_side))); - // print out the jth bit of the byte b - printf("%d (%2d) ", (b >> j) & 1, led_index); // read the jth bit of the byte b LEDS_set(leds, led_index, 2 * ((b >> j) & 1)); } - printf("\n"); } LEDS_render(leds); lt->debounce = LEDTEXT_DEBOUNCE_TIME; @@ -51,7 +47,7 @@ void LEDText_display(LEDText *lt, char *text) { void LEDText_displayNumber(LEDText *lt, uint16_t number) { char number_string[8]; - sprintf(number_string, "%d", number); + format_int32_decimal(number_string, number); LEDText_display(lt, number_string); } diff --git a/lib/midicallback.h b/lib/midicallback.h index 4cf8d27e7..e2eb638ca 100644 --- a/lib/midicallback.h +++ b/lib/midicallback.h @@ -19,9 +19,6 @@ uint32_t midi_timing_count = 0; const uint8_t midi_timing_modulus = 24; void midi_note_off(int note) { -#ifdef DEBUG_MIDI - printf("note_off: %d\n", note); -#endif #if MIDI_NOTE_KEY == 1 input_button[note % NUM_BUTTONS].Set(false); if (midi_button2 > -1) { @@ -33,9 +30,6 @@ void midi_note_off(int note) { } void midi_note_on(int note, int velocity) { -#ifdef DEBUG_MIDI - printf("note_on: %d\n", note); -#endif #if MIDI_NOTE_KEY == 1 if (midi_button1 > -1) { midi_button2 = note % NUM_BUTTONS; @@ -47,9 +41,6 @@ void midi_note_on(int note, int velocity) { } void midi_start() { -#ifdef DEBUG_MIDI - printf("[midicallback] midi start\n"); -#endif midi_timing_count = 24 * MIDI_RESET_EVERY_BEAT - 1; cancel_repeating_timer(&timer); do_restart_playback = true; @@ -58,16 +49,8 @@ void midi_start() { button_mute = false; trigger_button_mute = false; } -void midi_continue() { -#ifdef DEBUG_MIDI - printf("[midicallback] midi continue (starting)\n"); -#endif - midi_start(); -} +void midi_continue() { midi_start(); } void midi_stop() { -#ifdef DEBUG_MIDI - printf("[midicallback] midi stop\n"); -#endif midi_timing_count = 24 * MIDI_RESET_EVERY_BEAT - 1; trigger_button_mute = true; do_stop_playback = true; @@ -112,7 +95,8 @@ void midi_control_change (uint8_t channel, uint8_t control, uint8_t value) { } else if (new_adcvalue > 127 + 10) { new_adcvalue -= 127 + 10; sf->pitch_val_index = - new_adcvalue * (PITCH_VAL_MAX - PITCH_VAL_MID) / (127 - 10) + PITCH_VAL_MID; + new_adcvalue * (PITCH_VAL_MAX - PITCH_VAL_MID) / (127 - 10) + + PITCH_VAL_MID; } else { sf->pitch_val_index = PITCH_VAL_MID; } @@ -127,16 +111,12 @@ void midi_control_change (uint8_t channel, uint8_t control, uint8_t value) { f_sel_sample_next != sel_sample_cur) { sel_bank_next = f_sel_bank_next; sel_sample_next = f_sel_sample_next; - printf("[zeptocore] %d bank %d, sample %d\n", - sample_selection_index, sel_bank_next, sel_sample_next); fil_current_change = true; } break; } case cc_quantize: { // Qunatize - const uint8_t quantizations[10] = {1, 6, 12, 24, 48, - 64, 96, 144, 192, 192}; - printf("quantization: %d\n", quantizations[new_adcvalue * 9 / 255 ]); + const uint8_t quantizations[10] = {1, 6, 12, 24, 48, 64, 96, 144, 192, 192}; Sequencer_quantize( sf->sequencers[mode_buttons16][sf->sequence_sel[mode_buttons16]], quantizations[new_adcvalue * 9 / 255]); @@ -159,22 +139,19 @@ void midi_control_change (uint8_t channel, uint8_t control, uint8_t value) { global_filter_index = new_adcvalue * (resonantfilter_fc_max) / (128 - filter_spacing); global_filter_lphp = 0; - ResonantFilter_setFilterType(resFilter[channel], - global_filter_lphp); + ResonantFilter_setFilterType(resFilter[channel], global_filter_lphp); ResonantFilter_setFc(resFilter[channel], global_filter_index); } else if (value >= 64 + filter_spacing) { global_filter_index = (new_adcvalue - (128 + filter_spacing)) * (resonantfilter_fc_max) / (128 - filter_spacing); global_filter_lphp = 1; - ResonantFilter_setFilterType(resFilter[channel], - global_filter_lphp); + ResonantFilter_setFilterType(resFilter[channel], global_filter_lphp); ResonantFilter_setFc(resFilter[channel], global_filter_index); } else { global_filter_index = resonantfilter_fc_max; global_filter_lphp = 0; - ResonantFilter_setFilterType(resFilter[channel], - global_filter_lphp); + ResonantFilter_setFilterType(resFilter[channel], global_filter_lphp); ResonantFilter_setFc(resFilter[channel], resonantfilter_fc_max); } } @@ -190,22 +167,19 @@ void midi_control_change (uint8_t channel, uint8_t control, uint8_t value) { global_filter_index = new_adcvalue * (resonantfilter_fc_max) / (128 - filter_spacing); global_filter_lphp = 0; - ResonantFilter_setFilterType(resFilter[channel], - global_filter_lphp); + ResonantFilter_setFilterType(resFilter[channel], global_filter_lphp); ResonantFilter_setFc(resFilter[channel], global_filter_index); } else if (value >= 64 + filter_spacing) { global_filter_index = (new_adcvalue - (128 + filter_spacing)) * (resonantfilter_fc_max) / (128 - filter_spacing); global_filter_lphp = 1; - ResonantFilter_setFilterType(resFilter[channel], - global_filter_lphp); + ResonantFilter_setFilterType(resFilter[channel], global_filter_lphp); ResonantFilter_setFc(resFilter[channel], global_filter_index); } else { global_filter_index = resonantfilter_fc_max; global_filter_lphp = 0; - ResonantFilter_setFilterType(resFilter[channel], - global_filter_lphp); + ResonantFilter_setFilterType(resFilter[channel], global_filter_lphp); ResonantFilter_setFc(resFilter[channel], resonantfilter_fc_max); } } @@ -220,7 +194,8 @@ void midi_control_change (uint8_t channel, uint8_t control, uint8_t value) { break_knob_set_point = new_adcvalue * 1024 / 255; break; case cc_randsequence: // Random sequencer - if (new_adcvalue > 255) new_adcvalue = 255; + if (new_adcvalue > 255) + new_adcvalue = 255; if (new_adcvalue < 32) { // normal do_retrig_at_end_of_phrase = false; @@ -231,7 +206,8 @@ void midi_control_change (uint8_t channel, uint8_t control, uint8_t value) { 1, 2, 4, 6, 8, 12, 16, 24, 32, 48, 64, }; random_sequence_length = - sequence_lengths[((int16_t)(new_adcvalue - 32) * 11 / (255 - 32)) % 11]; + sequence_lengths[((int16_t)(new_adcvalue - 32) * 11 / (255 - 32)) % + 11]; } else { // new random sequence regenerate_random_sequence_arr(); @@ -251,7 +227,6 @@ void midi_control_change (uint8_t channel, uint8_t control, uint8_t value) { default: return; } - } // Comparator function for qsort int compare_ints(const void *a, const void *b) { @@ -276,9 +251,6 @@ void midi_timing() { midi_timing_count++; if (midi_timing_count % (24 * MIDI_RESET_EVERY_BEAT) == 0) { // reset -#ifdef DEBUG_MIDI - printf("[midicallback] midi resetting\n"); -#endif clock_in_beat_total = -1; clock_in_beat_last = -1; } @@ -303,9 +275,6 @@ void midi_timing() { int bpm_new = findMedian(midi_bpm_detect, 7); if (bpm_new > 60 && bpm_new < 260 && bpm_new != sf->bpm_tempo) { sf->bpm_tempo = bpm_new; -#ifdef DEBUG_MIDI - printf("[midicallback] midi bpm = %d\n", bpm_new); -#endif } // if (bpm_input - 7 != bpm_set) { // // set bpm diff --git a/lib/onewiremidi2.h b/lib/onewiremidi2.h index 2a7c184bb..533e83137 100644 --- a/lib/onewiremidi2.h +++ b/lib/onewiremidi2.h @@ -110,9 +110,6 @@ void Onewiremidi_receive_(Onewiremidi *self) { self->last_time = t; uint8_t b = uart_rx_program_getc(self->pio, self->sm); // b = ~b; - if (b != 0xf8 && b != 0xfe) { - printf("[onewiremidi] received: %02x\n", b); - } enum { DATA0_PRESENT = 0x80 }; midi_message msg = {0}; diff --git a/lib/persistent_state.h b/lib/persistent_state.h index 4c98b034a..a58487390 100644 --- a/lib/persistent_state.h +++ b/lib/persistent_state.h @@ -3,8 +3,8 @@ #ifndef PERSISTENT_STATE_LIB #define PERSISTENT_STATE_LIB 1 -#include #include +#include #include // Magic number to validate flash data integrity (ASCII for "CORE") @@ -22,7 +22,8 @@ typedef struct { } PersistentState; // Calculate a simple checksum for the state -uint16_t __not_in_flash_func(PersistentState_calculate_checksum)(PersistentState *state) { +uint16_t __not_in_flash_func(PersistentState_calculate_checksum)( + PersistentState *state) { uint16_t sum = 0; sum += state->magic & 0xFFFF; sum += (state->magic >> 16) & 0xFFFF; @@ -69,35 +70,32 @@ void __not_in_flash_func(PersistentState_save)(uint8_t bank, uint8_t sample) { state.checksum = PersistentState_calculate_checksum(&state); state.padding = 0; - printf("[PersistentState] Saving bank=%d sample=%d to flash (preserving calibration)\n", bank, sample); write_struct_to_flash(&state, sizeof(PersistentState)); } // Load and validate the bank and sample from flash // Returns true if valid data was loaded, false otherwise -bool __not_in_flash_func(PersistentState_load)(uint8_t *bank, uint8_t *sample, uint8_t max_banks, uint8_t *banks_with_samples, uint8_t banks_with_samples_num, SampleList **banks_list) { +bool __not_in_flash_func(PersistentState_load)(uint8_t *bank, uint8_t *sample, + uint8_t max_banks, + uint8_t *banks_with_samples, + uint8_t banks_with_samples_num, + SampleList **banks_list) { PersistentState state; read_struct_from_flash(&state, sizeof(PersistentState)); // Validate magic number if (state.magic != PERSISTENT_STATE_MAGIC) { - printf("[PersistentState] Invalid magic number: 0x%08X (expected 0x%08X)\n", - state.magic, PERSISTENT_STATE_MAGIC); return false; } // Validate checksum uint16_t expected_checksum = PersistentState_calculate_checksum(&state); if (state.checksum != expected_checksum) { - printf("[PersistentState] Invalid checksum: 0x%04X (expected 0x%04X)\n", - state.checksum, expected_checksum); return false; } // Validate bank is within bounds if (state.bank >= max_banks) { - printf("[PersistentState] Bank %d out of bounds (max %d)\n", - state.bank, max_banks - 1); return false; } @@ -111,27 +109,23 @@ bool __not_in_flash_func(PersistentState_load)(uint8_t *bank, uint8_t *sample, u } if (!bank_exists) { - printf("[PersistentState] Bank %d has no samples\n", state.bank); return false; } // Validate sample exists in the bank if (state.sample >= banks_list[state.bank]->num_samples) { - printf("[PersistentState] Sample %d out of bounds for bank %d (max %d)\n", - state.sample, state.bank, banks_list[state.bank]->num_samples - 1); return false; } *bank = state.bank; *sample = state.sample; - printf("[PersistentState] Successfully loaded bank=%d sample=%d from flash\n", - *bank, *sample); return true; } // Save calibration data to flash (preserves bank/sample data) -void __not_in_flash_func(PersistentState_save_calibration)(uint16_t calibration[8]) { +void __not_in_flash_func(PersistentState_save_calibration)( + uint16_t calibration[8]) { PersistentState state; // First, read existing data to preserve bank/sample @@ -141,7 +135,8 @@ void __not_in_flash_func(PersistentState_save_calibration)(uint16_t calibration[ bool has_valid_bank_sample = false; if (state.magic == PERSISTENT_STATE_MAGIC) { uint16_t expected_checksum = PersistentState_calculate_checksum(&state); - if (state.checksum == expected_checksum && state.bank < 16 && state.sample < 16) { + if (state.checksum == expected_checksum && state.bank < 16 && + state.sample < 16) { has_valid_bank_sample = true; } } @@ -160,35 +155,30 @@ void __not_in_flash_func(PersistentState_save_calibration)(uint16_t calibration[ state.checksum = PersistentState_calculate_checksum(&state); state.padding = 0; - printf("[PersistentState] Saving calibration to flash (preserving bank/sample)\n"); write_struct_to_flash(&state, sizeof(PersistentState)); } // Load calibration data from flash // Returns true if valid calibration data was loaded -bool __not_in_flash_func(PersistentState_load_calibration)(uint16_t calibration[8]) { +bool __not_in_flash_func(PersistentState_load_calibration)( + uint16_t calibration[8]) { PersistentState state; read_struct_from_flash(&state, sizeof(PersistentState)); // Validate magic number if (state.magic != PERSISTENT_STATE_MAGIC) { - printf("[PersistentState] Invalid magic number for calibration: 0x%08X\n", state.magic); return false; } // Validate checksum uint16_t expected_checksum = PersistentState_calculate_checksum(&state); if (state.checksum != expected_checksum) { - printf("[PersistentState] Invalid checksum for calibration: 0x%04X (expected 0x%04X)\n", - state.checksum, expected_checksum); return false; } // Validate calibration data is within reasonable bounds for (uint8_t i = 0; i < 8; i++) { if (state.center_calibration[i] > 1024) { - printf("[PersistentState] Calibration data out of bounds: %d\n", - state.center_calibration[i]); return false; } } @@ -198,7 +188,6 @@ bool __not_in_flash_func(PersistentState_load_calibration)(uint16_t calibration[ calibration[i] = state.center_calibration[i]; } - printf("[PersistentState] Successfully loaded calibration from flash\n"); return true; } diff --git a/lib/realtime_stretch.h b/lib/realtime_stretch.h index 5352caea8..1a0a9479b 100644 --- a/lib/realtime_stretch.h +++ b/lib/realtime_stretch.h @@ -28,8 +28,10 @@ uint64_t realtime_stretch_phase_q32 = 0; RealtimeStretchGrain realtime_stretch_grains[2] = { {0, REALTIME_STRETCH_PHASE_INC_Q32, 0}, {0, REALTIME_STRETCH_PHASE_INC_Q32, REALTIME_STRETCH_GRAIN_HOP}}; -static int16_t realtime_stretch_readbuf[2][REALTIME_STRETCH_MAX_SOURCE_FRAMES * - 2]; +// Each grain is read and accumulated before the next one, so both grains can +// share this temporary buffer. This saves 7,072 bytes at 441-frame blocks. +static int16_t + realtime_stretch_readbuf[REALTIME_STRETCH_MAX_SOURCE_FRAMES * 2]; uint32_t realtime_stretch_from_knob_q8(uint16_t knob) { if (knob > 4095) { @@ -302,35 +304,29 @@ bool realtime_stretch_render(int16_t *values, uint32_t sample_count, for (uint8_t grain_index = 0; grain_index < 2; grain_index++) { RealtimeStretchGrain *grain = &realtime_stretch_grains[grain_index]; - const uint64_t start_phase_q32 = + const uint64_t segment_start_phase_q32 = grain->start_phase_q32 + (uint64_t)grain->age * grain->phase_inc_q32; const uint64_t local_span_q32 = - (start_phase_q32 & 0xffffffffull) + + (segment_start_phase_q32 & 0xffffffffull) + (uint64_t)(segment - 1) * grain->phase_inc_q32; uint32_t frames_to_read = (uint32_t)((local_span_q32 >> 32u) + 3u); if (frames_to_read > REALTIME_STRETCH_MAX_SOURCE_FRAMES) { frames_to_read = REALTIME_STRETCH_MAX_SOURCE_FRAMES; } - if (!realtime_stretch_read_frames(start_phase_q32, frames_to_read, - realtime_stretch_readbuf[grain_index])) { + if (!realtime_stretch_read_frames(segment_start_phase_q32, + frames_to_read, + realtime_stretch_readbuf)) { return false; } - } - for (uint32_t i = 0; i < segment; i++) { - int32_t mixed[2] = {0, 0}; - for (uint8_t grain_index = 0; grain_index < 2; grain_index++) { - RealtimeStretchGrain *grain = &realtime_stretch_grains[grain_index]; + for (uint32_t i = 0; i < segment; i++) { const uint32_t weight = realtime_stretch_grain_window(grain->age + i); if (weight == 0) { continue; } - const uint64_t segment_start_phase_q32 = - grain->start_phase_q32 + - (uint64_t)grain->age * grain->phase_inc_q32; const uint64_t local_phase_q32 = (segment_start_phase_q32 & 0xffffffffull) + (uint64_t)i * grain->phase_inc_q32; @@ -338,18 +334,20 @@ bool realtime_stretch_render(int16_t *values, uint32_t sample_count, const uint32_t frac = (uint32_t)local_phase_q32; for (uint8_t channel = 0; channel < 2; channel++) { const uint8_t source_channel = channels == 1 ? 0 : channel; - mixed[channel] += + const uint32_t output_index = (rendered + i) * 2 + channel; + const int32_t contribution = (int32_t)realtime_stretch_interpolated_frame( - realtime_stretch_readbuf[grain_index], frame_offset, - source_channel, channels, frac) * + realtime_stretch_readbuf, frame_offset, source_channel, + channels, frac) * (int32_t)weight; + const int32_t accumulated = + (int32_t)values[output_index] * + (1 << REALTIME_STRETCH_GRAIN_HOP_SHIFT) + + contribution; + values[output_index] = (int16_t)( + accumulated >> REALTIME_STRETCH_GRAIN_HOP_SHIFT); } } - - for (uint8_t channel = 0; channel < 2; channel++) { - values[(rendered + i) * 2 + channel] = - (int16_t)(mixed[channel] >> REALTIME_STRETCH_GRAIN_HOP_SHIFT); - } } realtime_stretch_advance_grains(segment, grain_phase_inc_q32); diff --git a/lib/savefile.h b/lib/savefile.h index 7d26e6f7e..551f3264e 100644 --- a/lib/savefile.h +++ b/lib/savefile.h @@ -4,6 +4,7 @@ #define LIB_SAVEFILE 1 #include "sequencer.h" +#include "utils.h" typedef struct SaveFile { uint32_t vol : 9; @@ -27,8 +28,6 @@ typedef struct SaveFile { #define SAVEFILE_PATHNAME "save.bin" #define SAVEFILE_FEATURE_MAGIC 0xA5 -void test_sequencer_emit(uint8_t key) { printf("key %d\n", key); } -void test_sequencer_stop() { printf("stop\n"); } void SaveFile_sanitize(SaveFile *sf) { if (sf->feature_magic != SAVEFILE_FEATURE_MAGIC) { sf->do_retrig_volume_ramps = 1; @@ -37,7 +36,9 @@ void SaveFile_sanitize(SaveFile *sf) { } SaveFile *SaveFile_malloc() { SaveFile *sf; - sf = malloc(sizeof(SaveFile) + (sizeof(Sequencer) * 3 * 16)); + // Each Sequencer owns a separate allocation below. The previous parent + // allocation also reserved space for 48 unused Sequencers. + sf = malloc(sizeof(SaveFile)); sf->bank = 0; sf->sample = 0; sf->vol = 120; @@ -97,22 +98,6 @@ SaveFile *SaveFile_malloc() { return sf; } -void SaveFile_test_sequencer(SaveFile *sf) { - Sequencer_set_callbacks(sf->sequencers[0][sf->sequence_sel[0]], - test_sequencer_emit, test_sequencer_stop); - Sequencer_add(sf->sequencers[0][sf->sequence_sel[0]], 1, 1); - Sequencer_add(sf->sequencers[0][sf->sequence_sel[0]], 2, 3); - Sequencer_add(sf->sequencers[0][sf->sequence_sel[0]], 3, 7); - Sequencer_add(sf->sequencers[0][sf->sequence_sel[0]], 4, 11); - Sequencer_add(sf->sequencers[0][sf->sequence_sel[0]], 5, 15); - Sequencer_play(sf->sequencers[0][sf->sequence_sel[0]], false); - for (int i = 0; i < 18; i++) { - printf("step %d ", i); - Sequencer_step(sf->sequencers[0][sf->sequence_sel[0]], i); - printf("\n"); - } -} - void SaveFile_free(SaveFile *sf) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 16; j++) { @@ -124,34 +109,15 @@ void SaveFile_free(SaveFile *sf) { #ifdef NOSDCARD bool SaveFile_load(SaveFile *sf, uint8_t savefile_index) { - printf("[SaveFile] loading\n"); char fname[32]; - sprintf(fname, "savefile%d", savefile_index); - printf("[SaveFile] reading %s\n", fname); + format_prefixed_int32(fname, "savefile", savefile_index); // load from the file on the file system FILE *file = fopen(fname, "rb"); if (file == NULL) { - printf("[SaveFile] no save file, skipping "); return false; } fread(sf, sizeof(SaveFile), 1, file); SaveFile_sanitize(sf); - // print everything in the savefile - printf("[SaveFile] vol: %d\n", sf->vol); - printf("[SaveFile] bpm_tempo: %d\n", sf->bpm_tempo); - printf("[SaveFile] bank: %d\n", sf->bank); - printf("[SaveFile] sample: %d\n", sf->sample); - // print which effects are on - for (int i = 0; i < 16; i++) { - printf("[SaveFile] fx_active[%d]: %d\n", i, sf->fx_active[i]); - } - // print stay in sync - printf("[SaveFile] stay_in_sync: %d\n", sf->stay_in_sync); - // print pitch_val_index - printf("[SaveFile] pitch_val_index: %d\n", sf->pitch_val_index); - // print do_retrig_pitch_changes - printf("[SaveFile] do_retrig_pitch_changes: %d\n", - sf->do_retrig_pitch_changes); // read sequencers for (int i = 0; i < 3; i++) { @@ -168,25 +134,16 @@ bool SaveFile_load(SaveFile *sf, uint8_t savefile_index) { bool SaveFile_load(SaveFile *sf, uint8_t savefile_index) { FIL fil; /* File object */ char fname[32]; - sprintf(fname, "savefile%d", savefile_index); - printf("[SaveFile] reading %s\n", fname); - if (f_open(&fil, fname, FA_READ)) { - printf("[SaveFile] no save file, skipping "); - } else { + format_prefixed_int32(fname, "savefile", savefile_index); + if (f_open(&fil, fname, FA_READ) == FR_OK) { unsigned int bytes_read; - if (f_read(&fil, sf, sizeof(SaveFile), &bytes_read)) { - printf("[SaveFile] problem reading save file"); - } else { - printf("[SaveFile] bpm_tempo = %d\n", sf->bpm_tempo); + if (f_read(&fil, sf, sizeof(SaveFile), &bytes_read) == FR_OK) { SaveFile_sanitize(sf); } // read sequencers for (int i = 0; i < 3; i++) { for (int j = 0; j < 16; j++) { - if (f_read(&fil, sf->sequencers[i][j], sizeof(Sequencer), - &bytes_read)) { - printf("[SaveFile] problem reading sequencer %d %d\n", i, j); - } + f_read(&fil, sf->sequencers[i][j], sizeof(Sequencer), &bytes_read); } } } @@ -195,36 +152,24 @@ bool SaveFile_load(SaveFile *sf, uint8_t savefile_index) { } bool SaveFile_save(SaveFile *sf, uint8_t savefile_index) { - printf("[SaveFile] writing\n"); FRESULT fr; FIL file; /* File object */ char fname[32]; - sprintf(fname, "savefile%d", savefile_index); - printf("[SaveFile] opening savefile for writing\n"); + format_prefixed_int32(fname, "savefile", savefile_index); fr = f_open(&file, fname, FA_WRITE | FA_CREATE_ALWAYS); if (FR_OK != fr) { - printf("f_open error: %s (%d)\n", FRESULT_str(fr), fr); return false; } - unsigned int total_bytes_written; unsigned int bw; SaveFile_sanitize(sf); - if (f_write(&file, sf, sizeof(SaveFile), &bw)) { - printf("[SaveFile] problem writing save\n"); - } - total_bytes_written = bw; + f_write(&file, sf, sizeof(SaveFile), &bw); for (int i = 0; i < 3; i++) { for (int j = 0; j < 16; j++) { - if (f_write(&file, sf->sequencers[i][j], sizeof(Sequencer), &bw)) { - printf("[SaveFile] problem writing sequencer %d %d\n", i, j); - } else { - total_bytes_written += bw; + f_write(&file, sf->sequencers[i][j], sizeof(Sequencer), &bw); } } - } - printf("[SaveFile] wrote %d bytes\n", total_bytes_written); f_close(&file); return true; } diff --git a/lib/sdcard_startup.h b/lib/sdcard_startup.h index 15116efb5..3bb6a6c4f 100644 --- a/lib/sdcard_startup.h +++ b/lib/sdcard_startup.h @@ -335,11 +335,6 @@ void update_reverb() { bool filter_was_activated = false; void update_fx(uint8_t fx_num) { -#ifdef INCLUDE_MIDI - if (midi_input_activated) { - printf_sysex("fx=%d,%d", fx_num, sf->fx_active[fx_num]); - } -#endif switch (fx_num) { case FX_REVERSE: phase_forward = !sf->fx_active[fx_num]; @@ -349,8 +344,8 @@ void update_fx(uint8_t fx_num) { break; case FX_COMB: // printf("[update_fx] comb: %d\n", sf->fx_active[fx_num]); - Comb_setActive(combfilter, sf->fx_active[fx_num], - sf->fx_param[FX_COMB][0], sf->fx_param[FX_COMB][1]); + Comb_setActive(combfilter, sf->fx_active[fx_num], sf->fx_param[FX_COMB][0], + sf->fx_param[FX_COMB][1]); break; case FX_BEATREPEAT: if (sf->fx_active[fx_num]) { @@ -437,31 +432,26 @@ void update_fx(uint8_t fx_num) { // break; case FX_TAPE_STOP: if (sf->fx_active[FX_TAPE_STOP]) { - Envelope2_reset(envelope_pitch, BLOCKS_PER_SECOND, - Envelope2_update(envelope_pitch), + Envelope2_reset( + envelope_pitch, BLOCKS_PER_SECOND, Envelope2_update(envelope_pitch), ENVELOPE_PITCH_THRESHOLD / 2, - linlin((float)sf->fx_param[FX_TAPE_STOP][0], 0.0, 255.0, - 0.15, 6.0)); + linlin((float)sf->fx_param[FX_TAPE_STOP][0], 0.0, 255.0, 0.15, 6.0)); } else { if (sf->fx_active[FX_REPITCH]) { Envelope2_reset( - envelope_pitch, BLOCKS_PER_SECOND, - Envelope2_update(envelope_pitch), + envelope_pitch, BLOCKS_PER_SECOND, Envelope2_update(envelope_pitch), linlin((float)sf->fx_param[FX_REPITCH][0], 0.0, 255.0, 0.5, 2.0), linlin((float)sf->fx_param[FX_TAPE_STOP][1], 0.0, 255.0, 0.15, 6.0)); } else { Envelope2_reset(envelope_pitch, BLOCKS_PER_SECOND, Envelope2_update(envelope_pitch), 1.0, - linlin((float)sf->fx_param[FX_TAPE_STOP][1], 0.0, - 255.0, 0.15, 6.0)); + linlin((float)sf->fx_param[FX_TAPE_STOP][1], 0.0, 255.0, + 0.15, 6.0)); } } break; case FX_FUZZ: - if (sf->fx_active[FX_FUZZ]) { - printf("fuzz activated!\n"); - } break; case FX_FILTER: if (sf->fx_active[FX_FILTER] && !filter_was_activated) { @@ -471,8 +461,7 @@ void update_fx(uint8_t fx_num) { EnvelopeLinearInteger_reset( envelope_filter, BLOCKS_PER_SECOND, EnvelopeLinearInteger_update(envelope_filter, NULL), - linlin(sf->fx_param[FX_FILTER][0], 0, 255, 5, - resonantfilter_fc_max), + linlin(sf->fx_param[FX_FILTER][0], 0, 255, 5, resonantfilter_fc_max), linlin(sf->fx_param[FX_FILTER][1], 0, 255, 0.5, 5)); } else if (filter_was_activated) { // turn off filter @@ -518,7 +507,6 @@ void fx_sequencer_emit(uint8_t key) { // midi out MidiOut_on(midiout[4], key, 127); #endif - printf("[fx_sequencer_emit] key %d\n", key); if (key < 16) { sf->fx_active[key] = true; update_fx(key); @@ -528,14 +516,13 @@ void fx_sequencer_emit(uint8_t key) { } } -void fx_sequencer_stop() { printf("[fx_sequencer_stop] stop\n"); } +void fx_sequencer_stop() {} void bass_sequencer_emit(uint8_t key) { #ifdef INCLUDE_MIDI // midi out MidiOut_on(midiout[5], key, 127); #endif - printf("[bass_sequencer_emit] key %d\n", key); #ifdef INCLUDE_SINEBASS if (key < 16) { WaveBass_note_on(wavebass, key); @@ -545,7 +532,7 @@ void bass_sequencer_emit(uint8_t key) { #endif } -void bass_sequencer_stop() { printf("[bass_sequencer_stop] stop\n"); } +void bass_sequencer_stop() {} void savefile_do_load() { if (savefile_has_data[savefile_current]) { @@ -556,7 +543,6 @@ void savefile_do_load() { SaveFile_load(sf, savefile_current); f_open(&fil_current, fil_current_name, FA_READ); sync_using_sdcard = false; - printf("[button_handler] loading %s again\n", fil_current_name); // update all the fx for (uint8_t i = 0; i < 16; i++) { update_fx(i); @@ -578,8 +564,6 @@ void savefile_do_load() { // load new bank and sample sel_bank_next = sf->bank; sel_sample_next = sf->sample; - printf("[SaveFile] loaded bank %d sample %d\n", sel_bank_next, - sel_sample_next); fil_current_change = true; } } @@ -649,40 +633,34 @@ void sdcard_startup() { continue; if (bi == 0) { for (uint8_t variation = 0; variation < 2; variation++) { - printf( - "[sdcard_startup] " + printf("[sdcard_startup] " "banks[%d]->sample[%d].snd[variation]->size: %d\n", bi, si, banks[bi]->sample[si].snd[variation]->size); - printf( - "[sdcard_startup] " + printf("[sdcard_startup] " "banks[%d]->sample[%d].snd[variation]->num_channels: %d\n", bi, si, banks[bi]->sample[si].snd[variation]->num_channels); - printf( - "[sdcard_startup] " + printf("[sdcard_startup] " "banks[%d]->sample[%d].snd[variation]->oversampling: %d\n", bi, si, banks[bi]->sample[si].snd[variation]->oversampling); - printf( - "[sdcard_startup] " + printf("[sdcard_startup] " "banks[%d]->sample[%d].snd[variation]->splice_trigger:% " "d\n", - bi, si, banks[bi]->sample[si].snd[variation]->splice_trigger); - printf( - "[sdcard_startup] " + bi, si, + banks[bi]->sample[si].snd[variation]->splice_trigger); + printf("[sdcard_startup] " "banks[%d]->sample[%d].snd[variation]->splice_variable:% " "d\n", - bi, si, banks[bi]->sample[si].snd[variation]->splice_variable); - printf( - "[sdcard_startup] " + bi, si, + banks[bi]->sample[si].snd[variation]->splice_variable); + printf("[sdcard_startup] " "banks[%d]->sample[%d].snd[variation]->play_mode: " "% d\n ", bi, si, banks[bi]->sample[si].snd[variation]->play_mode); - printf( - "[sdcard_startup] " + printf("[sdcard_startup] " "banks[%d]->sample[%d].snd[variation]->bpm: " "%d\n", bi, si, banks[bi]->sample[si].snd[variation]->bpm); - printf( - "[sdcard_startup] " + printf("[sdcard_startup] " "banks[%d]->sample[%d].snd[variation]->slice_num: " "% d\n ", bi, si, banks[bi]->sample[si].snd[variation]->slice_num); @@ -822,14 +800,16 @@ void sdcard_startup() { savefile_do_load(); #ifdef INCLUDE_ECTOCORE - // If no savefile was loaded, restore bank/sample from flash by triggering file change - // This happens after savefile_do_load so that savefiles take precedence + // If no savefile was loaded, restore bank/sample from flash by triggering + // file change This happens after savefile_do_load so that savefiles take + // precedence if (!savefile_has_data[savefile_current]) { // Use the restored values from flash sel_bank_next = sel_bank_cur; sel_sample_next = sel_sample_cur; fil_current_change = true; - printf("[sdcard_startup] No savefile loaded, applying flash-restored bank/sample\n"); + printf("[sdcard_startup] No savefile loaded, applying flash-restored " + "bank/sample\n"); } #endif diff --git a/lib/sequencer.h b/lib/sequencer.h index 9e0b86acb..eddeec317 100644 --- a/lib/sequencer.h +++ b/lib/sequencer.h @@ -83,8 +83,6 @@ uint16_t Sequencer_add(Sequencer *seq, uint8_t key, int64_t step) { } else { seq->rec_steps[seq->rec_len] = (step - seq->rec_step_offset); } - printf("[sequencer] step %d: %d\n", seq->rec_len, - seq->rec_steps[seq->rec_len]); seq->rec_key[seq->rec_len] = key; seq->rec_step_offset = step; seq->rec_len++; @@ -93,15 +91,6 @@ uint16_t Sequencer_add(Sequencer *seq, uint8_t key, int64_t step) { return 0; } -void Sequencer_print(Sequencer *seq) { - uint32_t step = 0; - for (uint16_t i = 0; i < seq->rec_len; i++) { - printf("%d) %d -> key %d\n", i, - step + round_uint16_to(seq->rec_steps[i], seq->quantization), - seq->rec_key[i]); - step += round_uint16_to(seq->rec_steps[i], seq->quantization); - } -} void Sequencer_quantize(Sequencer *seq, uint8_t quantization) { seq->quantization = quantization; } diff --git a/lib/test/reverb/Makefile b/lib/test/reverb/Makefile index 74b7254c2..927b70c8e 100644 --- a/lib/test/reverb/Makefile +++ b/lib/test/reverb/Makefile @@ -1,3 +1,6 @@ -build: - gcc -o main main.c - valgrind ./main \ No newline at end of file +test: + $(CC) -std=c11 -O2 -Wall -Wextra -Werror -I../.. main.c -lm -o main + ./main + +clean: + rm -f main diff --git a/lib/test/reverb/main.c b/lib/test/reverb/main.c index 5c9db1abf..02de56cab 100644 --- a/lib/test/reverb/main.c +++ b/lib/test/reverb/main.c @@ -1,24 +1,38 @@ // Copyright 2023-2025 Zack Scholl, GPLv3.0 // gcc -o main main.c && ./main | gnuplot -p -e 'plot "/dev/stdin" using 0:1 +#include #include #include #include -int getFreeHeap() { return 20000; } + +static uint32_t available_heap; +uint32_t getFreeHeap() { return available_heap; } + +#define __not_in_flash_func(name) name #include "../../freeverb_fp.h" -int main() { - FV_Reverb *freeverb = NULL; - printf("%d\n", freeverb == NULL); +int main(void) { + const uint32_t allocation = (uint32_t)FV_Reverb_heap_size( + FV_NUMCOMBS_DEFAULT, FV_NUMALLPASSES_DEFAULT); + available_heap = allocation + FV_REVERB_HEAP_RESERVE - 1; + FV_Reverb *freeverb = FV_Reverb_malloc(FV_INITIALROOM, FV_INITIALDAMP, + FV_INITIALWET, FV_INITIALDRY); + assert(freeverb == NULL); + + available_heap = allocation + FV_REVERB_HEAP_RESERVE; freeverb = FV_Reverb_malloc(FV_INITIALROOM, FV_INITIALDAMP, FV_INITIALWET, FV_INITIALDRY); - printf("%d\n", freeverb == NULL); + assert(freeverb != NULL); + assert(freeverb->num_combs == 1); + assert(freeverb->num_allpasses == 1); FV_Reverb_free(freeverb); - printf("%d\n", freeverb == NULL); + freeverb = FV_Reverb_malloc(FV_INITIALROOM, FV_INITIALDAMP, FV_INITIALWET, FV_INITIALDRY); - printf("%d\n", freeverb == NULL); + assert(freeverb != NULL); FV_Reverb_free(freeverb); + puts("bounded Freeverb tests passed"); return 0; -} \ No newline at end of file +} diff --git a/lib/utils.h b/lib/utils.h index ba9ca4b16..5ab9396f6 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -4,6 +4,8 @@ #define LIB_UTILS 1 #include +#include +#include #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c\n" #define BYTE_TO_BINARY(byte) \ @@ -74,6 +76,52 @@ void hue_to_rgb2(uint8_t hue, uint8_t *r, uint8_t *g, uint8_t *b) { util_clamp((ymin + (x - xmin) * (ymax - ymin) / (xmax - xmin)), (ymin), \ (ymax)) +static inline char *append_uint32_decimal(char *dest, uint32_t value) { + char reversed[10]; + uint8_t digits = 0; + + do { + reversed[digits++] = (char)('0' + value % 10); + value /= 10; + } while (value != 0); + + while (digits > 0) { + *dest++ = reversed[--digits]; + } + return dest; +} + +static inline void format_int32_decimal(char *dest, int32_t value) { + uint32_t magnitude; + if (value < 0) { + *dest++ = '-'; + magnitude = (uint32_t)(-(value + 1)) + 1; + } else { + magnitude = (uint32_t)value; + } + dest = append_uint32_decimal(dest, magnitude); + *dest = '\0'; +} + +static inline void format_prefixed_int32(char *dest, const char *prefix, + int32_t value) { + while (*prefix != '\0') { + *dest++ = *prefix++; + } + format_int32_decimal(dest, value); +} + +static inline void format_sample_filename(char *dest, uint8_t bank, + uint8_t sample, uint8_t variation) { + memcpy(dest, "bank", 4); + dest = append_uint32_decimal(dest + 4, (uint32_t)bank + 1); + *dest++ = '/'; + dest = append_uint32_decimal(dest, sample); + *dest++ = '.'; + dest = append_uint32_decimal(dest, variation); + memcpy(dest, ".wav", 5); +} + // multiplies and clips the output void MultipyAndClip_process(int32_t mul, int16_t max_val, int16_t *values, uint16_t num_values) { @@ -90,32 +138,32 @@ void MultipyAndClip_process(int32_t mul, int16_t max_val, int16_t *values, static inline uint8_t linlin_uint8_t(uint8_t in, uint8_t in_min, uint8_t in_max, uint8_t out_min, uint8_t out_max) { - return util_clamp( - (in - in_min) * (out_max - out_min) / (in_max - in_min) + out_min, + return util_clamp((in - in_min) * (out_max - out_min) / (in_max - in_min) + + out_min, out_min, out_max); } static inline uint16_t linlin_uint16_t(uint8_t in, uint8_t in_min, uint8_t in_max, uint16_t out_min, uint16_t out_max) { - return util_clamp( - (in - in_min) * (out_max - out_min) / (in_max - in_min) + out_min, + return util_clamp((in - in_min) * (out_max - out_min) / (in_max - in_min) + + out_min, out_min, out_max); } static inline uint32_t linlin_uint32_t(uint8_t in, uint8_t in_min, uint8_t in_max, uint32_t out_min, uint32_t out_max) { - return util_clamp( - (in - in_min) * (out_max - out_min) / (in_max - in_min) + out_min, + return util_clamp((in - in_min) * (out_max - out_min) / (in_max - in_min) + + out_min, out_min, out_max); } static inline uint8_t linlin_int32_uint8(int32_t in, int32_t in_min, int32_t in_max, uint8_t out_min, uint8_t out_max) { - return util_clamp( - (in - in_min) * (out_max - out_min) / (in_max - in_min) + out_min, + return util_clamp((in - in_min) * (out_max - out_min) / (in_max - in_min) + + out_min, out_min, out_max); } void generate_euclidean_rhythm(int n, int k, int offset, bool *rhythm) { diff --git a/lib/zeptoboard.h b/lib/zeptoboard.h index 382bbe0cf..5e6be5719 100644 --- a/lib/zeptoboard.h +++ b/lib/zeptoboard.h @@ -3,7 +3,6 @@ void input_handling() { // flash bad signs while (!fil_is_open) { - printf("waiting to start\n"); sleep_ms(10); } @@ -14,14 +13,10 @@ void input_handling() { while (1) { #ifdef INCLUDE_MIDI tud_task(); - midi_comm_task(midi_comm_callback_fn, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + midi_comm_task(midi_comm_callback_fn, NULL, NULL, NULL, NULL, NULL, NULL, + NULL); #endif - if (MessageSync_hasMessage(messagesync)) { - MessageSync_print(messagesync); - MessageSync_clear(messagesync); - } - // load the new sample if variation changed if (sel_variation_next != sel_variation) { if (!audio_callback_in_mute) { @@ -33,18 +28,10 @@ void input_handling() { } } sync_using_sdcard = true; - // measure the time it takes - uint32_t time_start = time_us_32(); - FRESULT fr = f_close(&fil_current); - if (fr != FR_OK) { - debugf("[zeptocore] f_close error: %s\n", FRESULT_str(fr)); - } - sprintf(fil_current_name, "bank%d/%d.%d.wav", sel_bank_cur + 1, - sel_sample_cur, sel_variation_next + audio_variant * 2); - fr = f_open(&fil_current, fil_current_name, FA_READ); - if (fr != FR_OK) { - debugf("[zeptocore] f_close error: %s\n", FRESULT_str(fr)); - } + f_close(&fil_current); + format_sample_filename(fil_current_name, sel_bank_cur, sel_sample_cur, + sel_variation_next + audio_variant * 2); + f_open(&fil_current, fil_current_name, FA_READ); // TODO: fix this // if sel_variation_next == 0 @@ -54,8 +41,6 @@ void input_handling() { sel_variation = sel_variation_next; sync_using_sdcard = false; - printf("[zeptocore] loading new sample variation took %d us\n", - time_us_32() - time_start); } } } \ No newline at end of file diff --git a/lib/zeptocore.h b/lib/zeptocore.h index 8bb3f4611..0dd0e8d5d 100644 --- a/lib/zeptocore.h +++ b/lib/zeptocore.h @@ -29,9 +29,7 @@ void printStringWithDelay(char *str) { } led++; } - printf("\n"); } - printf("\n"); LEDS_render(leds); if (currentChar == '.') { sleep_ms(50); @@ -52,7 +50,8 @@ void clear_debouncers() { } void make_random_sequence(uint8_t adcValue) { - if (adcValue > 255) adcValue = 255; + if (adcValue > 255) + adcValue = 255; if (adcValue < 32) { // normal do_retrig_at_end_of_phrase = false; @@ -76,10 +75,8 @@ void make_random_sequence(uint8_t adcValue) { } void __not_in_flash_func(input_handling)() { - printf("core1 running!\n"); // flash bad signs while (!fil_is_open) { - printf("waiting to start\n"); sleep_ms(10); } LEDS_clear(leds); @@ -101,8 +98,6 @@ void __not_in_flash_func(input_handling)() { } #endif - printf("entering while loop\n"); - uint8_t new_vol; // ( // a=Array.fill(72,{ arg i; @@ -143,9 +138,6 @@ void __not_in_flash_func(input_handling)() { // debug test printStringWithDelay("zv7.3.0"); - // print to screen - printf("version=v7.3.0\n"); - // initialize the resonsant filter global_filter_index = 12; for (uint8_t channel = 0; channel < 2; channel++) { @@ -218,9 +210,6 @@ void __not_in_flash_func(input_handling)() { // if in startup deduct if (adc_startup > 0) { adc_startup--; - if (adc_startup == 0) { - printf("adc startup done\n"); - } // if (adc_startup == 0) { // for (int i = 1; i < 2; i++) { // PIO p = (i == 0) ? pio0 : pio1; @@ -241,7 +230,7 @@ void __not_in_flash_func(input_handling)() { int char_input = getchar_timeout_us(10); if (char_input >= 0) { if (char_input == 118) { - printf("version=v7.3.0\n"); + send_text_as_sysex("version=v7.3.0"); } } @@ -278,14 +267,9 @@ void __not_in_flash_func(input_handling)() { } #endif - if (MessageSync_hasMessage(messagesync)) { - MessageSync_print(messagesync); - MessageSync_clear(messagesync); - } - #ifdef INCLUDE_SSD1306 char buf_ssd1306[16]; - sprintf(buf_ssd1306, "%d", beat_current); + format_int32_decimal(buf_ssd1306, beat_current); ssd1306_clear(&disp); ssd1306_draw_string(&disp, 8, 24, 1, buf_ssd1306); ssd1306_bmp_show_image_with_offset(&disp, output_bmp_data, output_bmp_size, @@ -310,14 +294,12 @@ void __not_in_flash_func(input_handling)() { if (random_integer_in_range(0, 96) < probability_max_values_off[sf->fx_param[i][2] >> 4]) { toggle_fx(i); - printf("[zeptocore] random fx: %d %d\n", i, sf->fx_active[i]); } } else { if (random_integer_in_range(0, 96) < probability_max_values[sf->fx_param[i][2] >> 4]) { toggle_fx(i); // TODO: also randomize the parameters? - printf("[zeptocore] random fx: %d %d\n", i, sf->fx_active[i]); } } } @@ -403,13 +385,11 @@ void __not_in_flash_func(input_handling)() { clear_debouncers(); DebounceUint8_set(debouncer_uint8[DEBOUNCE_UINT8_LED_BAR], sf->fx_param[single_key - 4][0], 100); - printf("fx_param %d: %d %d\n", 0, single_key - 4, adc * 255 / 4096); if (key_on_buttons[FX_BEATREPEAT + 4] && do_update_beat_repeat == 0) { debounce_beat_repeat = 30; } else if (key_on_buttons[FX_DELAY + 4]) { Delay_setFeedbackf(delay, (float)adc / 8192.0f + 0.49f); } else if (key_on_buttons[FX_TIGHTEN + 4]) { - printf("updating gate\n"); Gate_set_amount(audio_gate, sf->fx_param[FX_TIGHTEN][0]); // deactivated // } else if (key_on_buttons[FX_TREMELO + 4]) { @@ -442,7 +422,6 @@ void __not_in_flash_func(input_handling)() { // round to nearest 2 bpm_new_tempo = (bpm_new_tempo / 2) * 2; } - printf("bpm_new_tempo: %d\n", bpm_new_tempo); sf->bpm_tempo = util_clamp(bpm_new_tempo, 30, 300); clear_debouncers(); DebounceUint8_set(debouncer_uint8[DEBOUNCE_UINT8_LED_DIAGONAL], @@ -461,7 +440,6 @@ void __not_in_flash_func(input_handling)() { MidiOut_cc(midiout[0], cc_sampleselect, adc * 127 / 4096); #endif sample_selection_index = adc_raw * sample_selection_num / 4096; - printf("sample_selection_index: %d\n", sample_selection_index); } else if (button_is_pressed(KEY_D)) { #ifdef INCLUDE_MIDI // send out midi cc @@ -485,7 +463,6 @@ void __not_in_flash_func(input_handling)() { #endif if (sample_selection_index_last != sample_selection_index) { - printf("sample_selection_index: %d\n", sample_selection_index); sample_selection_index_last = sample_selection_index; debounce_sample_selection = 40; } else if (debounce_sample_selection > 0) { @@ -498,15 +475,14 @@ void __not_in_flash_func(input_handling)() { f_sel_sample_next != sel_sample_cur) { sel_bank_next = f_sel_bank_next; sel_sample_next = f_sel_sample_next; - printf("[zeptocore] %d bank %d, sample %d\n", sample_selection_index, - sel_bank_next, sel_sample_next); fil_current_change = true; } } } #ifdef BTN_COL_START - if (!is_arcade_box) button_handler(bm); + if (!is_arcade_box) + button_handler(bm); #endif #ifdef INCLUDE_CLOCKINPUT @@ -543,7 +519,6 @@ void __not_in_flash_func(input_handling)() { adc_debounce[1]--; if (mode_buttons16 == MODE_MASH && single_key > -1) { sf->fx_param[single_key - 4][1] = adc * 255 / 4096; - printf("fx_param %d: %d %d\n", 1, single_key - 4, adc * 255 / 4096); if (key_on_buttons[FX_EXPAND + 4]) { update_reverb(); } else if (key_on_buttons[FX_DELAY + 4]) { @@ -662,7 +637,8 @@ void __not_in_flash_func(input_handling)() { #endif #ifdef BTN_COL_START - if (!is_arcade_box) button_handler(bm); + if (!is_arcade_box) + button_handler(bm); #endif #ifdef INCLUDE_CLOCKINPUT @@ -697,7 +673,6 @@ void __not_in_flash_func(input_handling)() { adc_debounce[2]--; if (mode_buttons16 == MODE_MASH && single_key > -1) { sf->fx_param[single_key - 4][2] = adc * 255 / 4096; - printf("fx_param %d: %d %d\n", 2, single_key - 4, adc * 255 / 4096); } else if (adc_startup == 0) { if (button_is_pressed(KEY_A)) { #ifdef INCLUDE_MIDI @@ -708,7 +683,6 @@ void __not_in_flash_func(input_handling)() { // new_vol = 100; if (new_vol != sf->vol) { sf->vol = new_vol; - printf("sf-vol: %d\n", sf->vol); } clear_debouncers(); DebounceUint8_set(debouncer_uint8[DEBOUNCE_UINT8_LED_WALL], @@ -729,7 +703,6 @@ void __not_in_flash_func(input_handling)() { const uint8_t quantizations[10] = {1, 6, 12, 24, 48, 64, 96, 144, 192, 192}; - printf("quantization: %d\n", quantizations[adc * 9 / 4096]); Sequencer_quantize( sf->sequencers[mode_buttons16][sf->sequence_sel[mode_buttons16]], quantizations[adc * 9 / 4096]); @@ -779,7 +752,6 @@ void __not_in_flash_func(input_handling)() { new_vol = (255 - adcValue) * VOLUME_STEPS * 6 / 7 / 255; if (new_vol != sf->vol) { sf->vol = new_vol; - printf("sf-vol: %d\n", sf->vol); } clear_debouncers(); DebounceUint8_set(debouncer_uint8[DEBOUNCE_UINT8_LED_BAR], @@ -808,8 +780,6 @@ void __not_in_flash_func(input_handling)() { f_sel_sample_next != sel_sample_cur) { sel_bank_next = f_sel_bank_next; sel_sample_next = f_sel_sample_next; - printf("[zeptocore] %d bank %d, sample %d\n", - sample_selection_index, sel_bank_next, sel_sample_next); fil_current_change = true; } clear_debouncers(); @@ -899,7 +869,8 @@ void __not_in_flash_func(input_handling)() { LEDS_render(leds); #ifdef BTN_COL_START - if (!is_arcade_box) button_handler(bm); + if (!is_arcade_box) + button_handler(bm); #endif #ifdef INCLUDE_CLOCKINPUT @@ -965,7 +936,6 @@ void __not_in_flash_func(input_handling)() { while (sync_using_sdcard) { sleep_us(100); } - printf("sync2: %ld\n", time_us_32() - time_start); // make sure the audio block was faster than usual if (time_us_32() - time_start < 4000) { do_try_change = true; @@ -973,18 +943,10 @@ void __not_in_flash_func(input_handling)() { } if (do_try_change) { sync_using_sdcard = true; - // measure the time it takes - uint32_t time_start = time_us_32(); - FRESULT fr = f_close(&fil_current); - if (fr != FR_OK) { - debugf("[zeptocore] f_close error: %s\n", FRESULT_str(fr)); - } - sprintf(fil_current_name, "bank%d/%d.%d.wav", sel_bank_cur + 1, - sel_sample_cur, sel_variation_next + audio_variant * 2); - fr = f_open(&fil_current, fil_current_name, FA_READ); - if (fr != FR_OK) { - debugf("[zeptocore] f_close error: %s\n", FRESULT_str(fr)); - } + f_close(&fil_current); + format_sample_filename(fil_current_name, sel_bank_cur, sel_sample_cur, + sel_variation_next + audio_variant * 2); + f_open(&fil_current, fil_current_name, FA_READ); // TODO: fix this // if sel_variation_next == 0 @@ -994,8 +956,6 @@ void __not_in_flash_func(input_handling)() { sel_variation = sel_variation_next; sync_using_sdcard = false; - printf("[zeptocore] loading new sample variation took %d us\n", - time_us_32() - time_start); } } } diff --git a/main.c b/main.c index 60e5ad005..f3f855388 100644 --- a/main.c +++ b/main.c @@ -905,7 +905,6 @@ int main() { random_initialize(); // initialize message sync - messagesync = MessageSync_malloc(); // intialize beat repeater beatrepeat = BeatRepeat_malloc(); diff --git a/zeptoboard_compile_definitions.cmake b/zeptoboard_compile_definitions.cmake index d4f5daa06..3c874d05d 100644 --- a/zeptoboard_compile_definitions.cmake +++ b/zeptoboard_compile_definitions.cmake @@ -14,6 +14,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE INCLUDE_FILTER=1 INCLUDE_BOARDCORE=1 CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 INCLUDE_MIDI=1 # INCLUDE_SSD1306=1 diff --git a/zeptocore_compile_definitions.cmake b/zeptocore_compile_definitions.cmake index 68b5fa18d..d35aa8317 100644 --- a/zeptocore_compile_definitions.cmake +++ b/zeptocore_compile_definitions.cmake @@ -63,6 +63,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 # debug printing diff --git a/zeptocore_compile_definitions_128.cmake b/zeptocore_compile_definitions_128.cmake index 119909a74..d5150cf0e 100644 --- a/zeptocore_compile_definitions_128.cmake +++ b/zeptocore_compile_definitions_128.cmake @@ -63,6 +63,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 # debug printing diff --git a/zeptocore_compile_definitions_256.cmake b/zeptocore_compile_definitions_256.cmake index b5bd54885..1c0819895 100644 --- a/zeptocore_compile_definitions_256.cmake +++ b/zeptocore_compile_definitions_256.cmake @@ -63,6 +63,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE # utilize core1 for audio to avoid dropouts CORE1_PROCESS_I2S_CALLBACK=1 + PICO_CORE1_STACK_SIZE=0x1000 DO_OVERCLOCK=1 # debug printing