From 47c9fc1f356ccf75850d3b983efe1363b3c8a562 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Mon, 14 Apr 2025 20:04:58 -0500 Subject: [PATCH 1/6] Always update `echo_buffer_len` during `recalculate_delay`. --- shared-module/audiodelays/Echo.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/shared-module/audiodelays/Echo.c b/shared-module/audiodelays/Echo.c index 968c3bbddb693..2a0eee2ca7b0c 100644 --- a/shared-module/audiodelays/Echo.c +++ b/shared-module/audiodelays/Echo.c @@ -136,16 +136,12 @@ void recalculate_delay(audiodelays_echo_obj_t *self, mp_float_t f_delay_ms) { // Calculate the current echo buffer length in bytes uint32_t new_echo_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * f_delay_ms) * (self->base.channel_count * sizeof(uint16_t)); - // Check if our new echo is too long for our maximum buffer + // Limit to valid range if (new_echo_buffer_len > self->max_echo_buffer_len) { - return; - } else if (new_echo_buffer_len < 0.0) { // or too short! - return; - } - - // If the echo buffer is larger then our audio buffer weird things happen - if (new_echo_buffer_len < self->buffer_len) { - return; + new_echo_buffer_len = self->max_echo_buffer_len; + } else if (new_echo_buffer_len < self->buffer_len) { + // If the echo buffer is smaller than our audio buffer, weird things happen + new_echo_buffer_len = self->buffer_len; } self->echo_buffer_len = new_echo_buffer_len; From 57391fa44b4ff2070eabed9245af18393a928611 Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Mon, 14 Apr 2025 20:09:35 -0500 Subject: [PATCH 2/6] Unify `echo_buffer_pos` regardless of `freq_shift`, remove redundant `echo_buffer_write_pos`, and split buffer for stereo output when `freq_shift=True`. --- shared-module/audiodelays/Echo.c | 87 +++++++++++++++----------------- shared-module/audiodelays/Echo.h | 7 +-- 2 files changed, 43 insertions(+), 51 deletions(-) diff --git a/shared-module/audiodelays/Echo.c b/shared-module/audiodelays/Echo.c index 2a0eee2ca7b0c..f69b65316a9cc 100644 --- a/shared-module/audiodelays/Echo.c +++ b/shared-module/audiodelays/Echo.c @@ -98,11 +98,10 @@ void common_hal_audiodelays_echo_construct(audiodelays_echo_obj_t *self, uint32_ // read is where we read previous echo from delay_ms ago to play back now // write is where the store the latest playing sample to echo back later - self->echo_buffer_read_pos = self->buffer_len / sizeof(uint16_t); - self->echo_buffer_write_pos = 0; + self->echo_buffer_pos = 0; - // where we read the previous echo from delay_ms ago to play back now (for freq shift) - self->echo_buffer_left_pos = self->echo_buffer_right_pos = 0; + // use a separate buffer position for the right channel when using freq_shift + self->echo_buffer_right_pos = 0; } void common_hal_audiodelays_echo_deinit(audiodelays_echo_obj_t *self) { @@ -131,7 +130,8 @@ void recalculate_delay(audiodelays_echo_obj_t *self, mp_float_t f_delay_ms) { if (self->freq_shift) { // Calculate the rate of iteration over the echo buffer with 8 sub-bits self->echo_buffer_rate = (uint32_t)MAX(self->max_delay_ms / f_delay_ms * MICROPY_FLOAT_CONST(256.0), MICROPY_FLOAT_CONST(1.0)); - self->echo_buffer_len = self->max_echo_buffer_len; + // Only use half of the buffer per channel if stereo + self->echo_buffer_len = self->max_echo_buffer_len >> (self->base.channel_count - 1); } else { // Calculate the current echo buffer length in bytes uint32_t new_echo_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * f_delay_ms) * (self->base.channel_count * sizeof(uint16_t)); @@ -174,6 +174,12 @@ bool common_hal_audiodelays_echo_get_freq_shift(audiodelays_echo_obj_t *self) { } void common_hal_audiodelays_echo_set_freq_shift(audiodelays_echo_obj_t *self, bool freq_shift) { + // Clear the echo buffer and reset buffer position if changing freq_shift modes + if (self->freq_shift != freq_shift) { + memset(self->echo_buffer, 0, self->max_echo_buffer_len); + self->echo_buffer_pos = 0; + self->echo_buffer_right_pos = 0; + } self->freq_shift = freq_shift; uint32_t delay_ms = (uint32_t)synthio_block_slot_get(&self->delay_ms); recalculate_delay(self, delay_ms); @@ -275,12 +281,9 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * uint32_t echo_buf_len = self->echo_buffer_len / sizeof(uint16_t); // Set our echo buffer position accounting for stereo - uint32_t echo_buffer_pos = 0; - if (self->freq_shift) { - echo_buffer_pos = self->echo_buffer_left_pos; - if (channel == 1) { - echo_buffer_pos = self->echo_buffer_right_pos; - } + uint32_t echo_buffer_pos = self->echo_buffer_pos; + if (self->freq_shift && channel == 1) { + echo_buffer_pos = self->echo_buffer_right_pos; } // If we have no sample keep the echo echoing @@ -304,19 +307,20 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * for (uint32_t i = 0; i < length; i++) { int16_t echo, word = 0; uint32_t next_buffer_pos = 0; + uint32_t echo_buffer_offset = echo_buf_len * (self->freq_shift && (channel == 1 || (i % self->base.channel_count) == 1)); if (self->freq_shift) { - echo = echo_buffer[echo_buffer_pos >> 8]; + echo = echo_buffer[(echo_buffer_pos >> 8) + echo_buffer_offset]; next_buffer_pos = echo_buffer_pos + self->echo_buffer_rate; for (uint32_t j = echo_buffer_pos >> 8; j < next_buffer_pos >> 8; j++) { - word = (int16_t)(echo_buffer[j % echo_buf_len] * decay); - echo_buffer[j % echo_buf_len] = word; + word = (int16_t)(echo_buffer[(j % echo_buf_len) + echo_buffer_offset] * decay); + echo_buffer[(j % echo_buf_len) + echo_buffer_offset] = word; } } else { - echo = echo_buffer[self->echo_buffer_read_pos++]; + echo = echo_buffer[echo_buffer_pos]; word = (int16_t)(echo * decay); - echo_buffer[self->echo_buffer_write_pos++] = word; + echo_buffer[echo_buffer_pos++] = word; } word = (int16_t)(echo * mix); @@ -333,15 +337,10 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * } } - if (self->freq_shift) { + if (self->freq_shift && (single_channel_output || echo_buffer_offset)) { echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8); - } else { - if (self->echo_buffer_read_pos >= echo_buf_len) { - self->echo_buffer_read_pos = 0; - } - if (self->echo_buffer_write_pos >= echo_buf_len) { - self->echo_buffer_write_pos = 0; - } + } else if (!self->freq_shift && echo_buffer_pos >= echo_buf_len) { + echo_buffer_pos = 0; } } } @@ -376,37 +375,39 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * int32_t echo, word = 0; uint32_t next_buffer_pos = 0; + uint32_t echo_buffer_offset = echo_buf_len * (self->freq_shift && (channel == 1 || (i % self->base.channel_count) == 1)); + if (self->freq_shift) { - echo = echo_buffer[echo_buffer_pos >> 8]; + echo = echo_buffer[(echo_buffer_pos >> 8) + echo_buffer_offset]; next_buffer_pos = echo_buffer_pos + self->echo_buffer_rate; } else { - echo = echo_buffer[self->echo_buffer_read_pos++]; + echo = echo_buffer[echo_buffer_pos]; word = (int32_t)(echo * decay + sample_word); } if (MP_LIKELY(self->base.bits_per_sample == 16)) { if (self->freq_shift) { for (uint32_t j = echo_buffer_pos >> 8; j < next_buffer_pos >> 8; j++) { - word = (int32_t)(echo_buffer[j % echo_buf_len] * decay + sample_word); + word = (int32_t)(echo_buffer[(j % echo_buf_len) + echo_buffer_offset] * decay + sample_word); word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2)); - echo_buffer[j % echo_buf_len] = (int16_t)word; + echo_buffer[(j % echo_buf_len) + echo_buffer_offset] = (int16_t)word; } } else { word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2)); - echo_buffer[self->echo_buffer_write_pos++] = (int16_t)word; + echo_buffer[echo_buffer_pos++] = (int16_t)word; } } else { if (self->freq_shift) { for (uint32_t j = echo_buffer_pos >> 8; j < next_buffer_pos >> 8; j++) { - word = (int32_t)(echo_buffer[j % echo_buf_len] * decay + sample_word); + word = (int32_t)(echo_buffer[(j % echo_buf_len) + echo_buffer_offset] * decay + sample_word); // Do not have mix_down for 8 bit so just hard cap samples into 1 byte word = MIN(MAX(word, -128), 127); - echo_buffer[j % echo_buf_len] = (int8_t)word; + echo_buffer[(j % echo_buf_len) + echo_buffer_offset] = (int8_t)word; } } else { // Do not have mix_down for 8 bit so just hard cap samples into 1 byte word = MIN(MAX(word, -128), 127); - echo_buffer[self->echo_buffer_write_pos++] = (int8_t)word; + echo_buffer[echo_buffer_pos++] = (int8_t)word; } } @@ -427,15 +428,10 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * } } - if (self->freq_shift) { + if (self->freq_shift && (single_channel_output || echo_buffer_offset)) { echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8); - } else { - if (self->echo_buffer_read_pos >= echo_buf_len) { - self->echo_buffer_read_pos = 0; - } - if (self->echo_buffer_write_pos >= echo_buf_len) { - self->echo_buffer_write_pos = 0; - } + } else if (!self->freq_shift && echo_buffer_pos >= echo_buf_len) { + echo_buffer_pos = 0; } } } @@ -448,12 +444,11 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * self->sample_buffer_length -= n; } - if (self->freq_shift) { - if (channel == 0) { - self->echo_buffer_left_pos = echo_buffer_pos; - } else if (channel == 1) { - self->echo_buffer_right_pos = echo_buffer_pos; - } + // Update buffer position + if (self->freq_shift && channel == 1) { + self->echo_buffer_right_pos = echo_buffer_pos; + } else { + self->echo_buffer_pos = echo_buffer_pos; } } diff --git a/shared-module/audiodelays/Echo.h b/shared-module/audiodelays/Echo.h index 7f5dbb69f090a..247a27ce5f23c 100644 --- a/shared-module/audiodelays/Echo.h +++ b/shared-module/audiodelays/Echo.h @@ -37,12 +37,9 @@ typedef struct { uint32_t echo_buffer_len; // bytes uint32_t max_echo_buffer_len; // bytes - uint32_t echo_buffer_read_pos; // words - uint32_t echo_buffer_write_pos; // words - - uint32_t echo_buffer_rate; // words << 8 - uint32_t echo_buffer_left_pos; // words << 8 + uint32_t echo_buffer_pos; // words (<< 8 when freq_shift=True) uint32_t echo_buffer_right_pos; // words << 8 + uint32_t echo_buffer_rate; // words << 8 mp_obj_t sample; } audiodelays_echo_obj_t; From feee74a5e2279e3cfd6d17bccf89233ebc50c6ad Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Mon, 21 Apr 2025 17:31:58 -0500 Subject: [PATCH 3/6] Improve right channel logic. --- shared-module/audiodelays/Echo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shared-module/audiodelays/Echo.c b/shared-module/audiodelays/Echo.c index f69b65316a9cc..4acb00cfc3baf 100644 --- a/shared-module/audiodelays/Echo.c +++ b/shared-module/audiodelays/Echo.c @@ -307,7 +307,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * for (uint32_t i = 0; i < length; i++) { int16_t echo, word = 0; uint32_t next_buffer_pos = 0; - uint32_t echo_buffer_offset = echo_buf_len * (self->freq_shift && (channel == 1 || (i % self->base.channel_count) == 1)); + uint32_t echo_buffer_offset = echo_buf_len * (self->freq_shift && ((single_channel_output && channel == 1) || (!single_channel_output && (i % self->base.channel_count) == 1))); if (self->freq_shift) { echo = echo_buffer[(echo_buffer_pos >> 8) + echo_buffer_offset]; @@ -337,7 +337,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * } } - if (self->freq_shift && (single_channel_output || echo_buffer_offset)) { + if (self->freq_shift && (self->base.channel_count == 1 || single_channel_output || (!single_channel_output && (i % self->base.channel_count) == 1))) { echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8); } else if (!self->freq_shift && echo_buffer_pos >= echo_buf_len) { echo_buffer_pos = 0; @@ -375,7 +375,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * int32_t echo, word = 0; uint32_t next_buffer_pos = 0; - uint32_t echo_buffer_offset = echo_buf_len * (self->freq_shift && (channel == 1 || (i % self->base.channel_count) == 1)); + uint32_t echo_buffer_offset = echo_buf_len * (self->freq_shift && ((single_channel_output && channel == 1) || (!single_channel_output && (i % self->base.channel_count) == 1))); if (self->freq_shift) { echo = echo_buffer[(echo_buffer_pos >> 8) + echo_buffer_offset]; @@ -428,7 +428,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * } } - if (self->freq_shift && (single_channel_output || echo_buffer_offset)) { + if (self->freq_shift && (self->base.channel_count == 1 || single_channel_output || (!single_channel_output && (i % self->base.channel_count) == 1))) { echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8); } else if (!self->freq_shift && echo_buffer_pos >= echo_buf_len) { echo_buffer_pos = 0; From 7d0e72e5ca03d64bf648a1b65841727f36e56ece Mon Sep 17 00:00:00 2001 From: Cooper Dalrymple Date: Mon, 21 Apr 2025 17:42:39 -0500 Subject: [PATCH 4/6] Unify echo buffer channel splitting. --- shared-module/audiodelays/Echo.c | 73 +++++++++++++++++++------------- shared-module/audiodelays/Echo.h | 4 +- 2 files changed, 45 insertions(+), 32 deletions(-) diff --git a/shared-module/audiodelays/Echo.c b/shared-module/audiodelays/Echo.c index 4acb00cfc3baf..35b3556db35b2 100644 --- a/shared-module/audiodelays/Echo.c +++ b/shared-module/audiodelays/Echo.c @@ -98,9 +98,9 @@ void common_hal_audiodelays_echo_construct(audiodelays_echo_obj_t *self, uint32_ // read is where we read previous echo from delay_ms ago to play back now // write is where the store the latest playing sample to echo back later - self->echo_buffer_pos = 0; + self->echo_buffer_left_pos = 0; - // use a separate buffer position for the right channel when using freq_shift + // use a separate buffer position for the right channel self->echo_buffer_right_pos = 0; } @@ -127,18 +127,21 @@ void recalculate_delay(audiodelays_echo_obj_t *self, mp_float_t f_delay_ms) { // Require that delay is at least 1 sample long f_delay_ms = MAX(f_delay_ms, self->sample_ms); + // Calculate the maximum buffer size per channel in bytes + uint32_t max_echo_buffer_len = self->max_echo_buffer_len >> (self->base.channel_count - 1); + if (self->freq_shift) { // Calculate the rate of iteration over the echo buffer with 8 sub-bits self->echo_buffer_rate = (uint32_t)MAX(self->max_delay_ms / f_delay_ms * MICROPY_FLOAT_CONST(256.0), MICROPY_FLOAT_CONST(1.0)); // Only use half of the buffer per channel if stereo - self->echo_buffer_len = self->max_echo_buffer_len >> (self->base.channel_count - 1); + self->echo_buffer_len = max_echo_buffer_len; } else { // Calculate the current echo buffer length in bytes - uint32_t new_echo_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * f_delay_ms) * (self->base.channel_count * sizeof(uint16_t)); + uint32_t new_echo_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * f_delay_ms) * sizeof(uint16_t); // Limit to valid range - if (new_echo_buffer_len > self->max_echo_buffer_len) { - new_echo_buffer_len = self->max_echo_buffer_len; + if (new_echo_buffer_len > max_echo_buffer_len) { + new_echo_buffer_len = max_echo_buffer_len; } else if (new_echo_buffer_len < self->buffer_len) { // If the echo buffer is smaller than our audio buffer, weird things happen new_echo_buffer_len = self->buffer_len; @@ -147,7 +150,9 @@ void recalculate_delay(audiodelays_echo_obj_t *self, mp_float_t f_delay_ms) { self->echo_buffer_len = new_echo_buffer_len; // Clear the now unused part of the buffer or some weird artifacts appear - memset(self->echo_buffer + self->echo_buffer_len, 0, self->max_echo_buffer_len - self->echo_buffer_len); + for (uint32_t i = 0; i < self->base.channel_count; i++) { + memset(self->echo_buffer + (i * max_echo_buffer_len) + self->echo_buffer_len, 0, max_echo_buffer_len - self->echo_buffer_len); + } } self->current_delay_ms = f_delay_ms; @@ -177,7 +182,7 @@ void common_hal_audiodelays_echo_set_freq_shift(audiodelays_echo_obj_t *self, bo // Clear the echo buffer and reset buffer position if changing freq_shift modes if (self->freq_shift != freq_shift) { memset(self->echo_buffer, 0, self->max_echo_buffer_len); - self->echo_buffer_pos = 0; + self->echo_buffer_left_pos = 0; self->echo_buffer_right_pos = 0; } self->freq_shift = freq_shift; @@ -279,12 +284,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * } uint32_t echo_buf_len = self->echo_buffer_len / sizeof(uint16_t); - - // Set our echo buffer position accounting for stereo - uint32_t echo_buffer_pos = self->echo_buffer_pos; - if (self->freq_shift && channel == 1) { - echo_buffer_pos = self->echo_buffer_right_pos; - } + uint32_t max_echo_buf_len = (self->max_echo_buffer_len >> (self->base.channel_count - 1)) / sizeof(uint16_t); // If we have no sample keep the echo echoing if (self->sample == NULL) { @@ -307,7 +307,10 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * for (uint32_t i = 0; i < length; i++) { int16_t echo, word = 0; uint32_t next_buffer_pos = 0; - uint32_t echo_buffer_offset = echo_buf_len * (self->freq_shift && ((single_channel_output && channel == 1) || (!single_channel_output && (i % self->base.channel_count) == 1))); + + // Get our echo buffer position and offset depending on current channel + uint32_t echo_buffer_offset = max_echo_buf_len * ((single_channel_output && channel == 1) || (!single_channel_output && (i % self->base.channel_count) == 1)); + uint32_t echo_buffer_pos = echo_buffer_offset ? self->echo_buffer_right_pos : self->echo_buffer_left_pos; if (self->freq_shift) { echo = echo_buffer[(echo_buffer_pos >> 8) + echo_buffer_offset]; @@ -318,9 +321,9 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * echo_buffer[(j % echo_buf_len) + echo_buffer_offset] = word; } } else { - echo = echo_buffer[echo_buffer_pos]; + echo = echo_buffer[echo_buffer_pos + echo_buffer_offset]; word = (int16_t)(echo * decay); - echo_buffer[echo_buffer_pos++] = word; + echo_buffer[echo_buffer_pos++ + echo_buffer_offset] = word; } word = (int16_t)(echo * mix); @@ -337,11 +340,18 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * } } - if (self->freq_shift && (self->base.channel_count == 1 || single_channel_output || (!single_channel_output && (i % self->base.channel_count) == 1))) { + if (self->freq_shift) { echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8); } else if (!self->freq_shift && echo_buffer_pos >= echo_buf_len) { echo_buffer_pos = 0; } + + // Update buffer position + if (echo_buffer_offset) { + self->echo_buffer_right_pos = echo_buffer_pos; + } else { + self->echo_buffer_left_pos = echo_buffer_pos; + } } } @@ -375,13 +385,16 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * int32_t echo, word = 0; uint32_t next_buffer_pos = 0; - uint32_t echo_buffer_offset = echo_buf_len * (self->freq_shift && ((single_channel_output && channel == 1) || (!single_channel_output && (i % self->base.channel_count) == 1))); + + // Get our echo buffer position and offset depending on current channel + uint32_t echo_buffer_offset = max_echo_buf_len * ((single_channel_output && channel == 1) || (!single_channel_output && (i % self->base.channel_count) == 1)); + uint32_t echo_buffer_pos = echo_buffer_offset ? self->echo_buffer_right_pos : self->echo_buffer_left_pos; if (self->freq_shift) { echo = echo_buffer[(echo_buffer_pos >> 8) + echo_buffer_offset]; next_buffer_pos = echo_buffer_pos + self->echo_buffer_rate; } else { - echo = echo_buffer[echo_buffer_pos]; + echo = echo_buffer[echo_buffer_pos + echo_buffer_offset]; word = (int32_t)(echo * decay + sample_word); } @@ -394,7 +407,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * } } else { word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2)); - echo_buffer[echo_buffer_pos++] = (int16_t)word; + echo_buffer[echo_buffer_pos++ + echo_buffer_offset] = (int16_t)word; } } else { if (self->freq_shift) { @@ -407,7 +420,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * } else { // Do not have mix_down for 8 bit so just hard cap samples into 1 byte word = MIN(MAX(word, -128), 127); - echo_buffer[echo_buffer_pos++] = (int8_t)word; + echo_buffer[echo_buffer_pos++ + echo_buffer_offset] = (int8_t)word; } } @@ -428,11 +441,18 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * } } - if (self->freq_shift && (self->base.channel_count == 1 || single_channel_output || (!single_channel_output && (i % self->base.channel_count) == 1))) { + if (self->freq_shift) { echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8); } else if (!self->freq_shift && echo_buffer_pos >= echo_buf_len) { echo_buffer_pos = 0; } + + // Update buffer position + if (echo_buffer_offset) { + self->echo_buffer_right_pos = echo_buffer_pos; + } else { + self->echo_buffer_left_pos = echo_buffer_pos; + } } } @@ -443,13 +463,6 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t * self->sample_remaining_buffer += (n * (self->base.bits_per_sample / 8)); self->sample_buffer_length -= n; } - - // Update buffer position - if (self->freq_shift && channel == 1) { - self->echo_buffer_right_pos = echo_buffer_pos; - } else { - self->echo_buffer_pos = echo_buffer_pos; - } } // Finally pass our buffer and length to the calling audio function diff --git a/shared-module/audiodelays/Echo.h b/shared-module/audiodelays/Echo.h index 247a27ce5f23c..cc37f7030be0e 100644 --- a/shared-module/audiodelays/Echo.h +++ b/shared-module/audiodelays/Echo.h @@ -37,8 +37,8 @@ typedef struct { uint32_t echo_buffer_len; // bytes uint32_t max_echo_buffer_len; // bytes - uint32_t echo_buffer_pos; // words (<< 8 when freq_shift=True) - uint32_t echo_buffer_right_pos; // words << 8 + uint32_t echo_buffer_left_pos; // words (<< 8 when freq_shift=True) + uint32_t echo_buffer_right_pos; // words (<< 8 when freq_shift=True) uint32_t echo_buffer_rate; // words << 8 mp_obj_t sample; From db14b3b7ac34afc9b81bf8141c7ab7138db2d9a6 Mon Sep 17 00:00:00 2001 From: Bernhard Bablok Date: Tue, 22 Apr 2025 18:00:23 +0200 Subject: [PATCH 5/6] fixed I2C pins --- .../boards/pimoroni_inky_frame_5_7/mpconfigboard.h | 4 ++-- .../boards/pimoroni_inky_frame_7_3/mpconfigboard.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.h index d2547cc161568..a8c404c422501 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.h @@ -14,8 +14,8 @@ #define MICROPY_HW_LED_STATUS (&pin_GPIO6) -#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) -#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) #define DEFAULT_UART_BUS_RX (&pin_GPIO1) diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.h index 42cb1196a5475..32477b12c299f 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.h @@ -14,8 +14,8 @@ #define MICROPY_HW_LED_STATUS (&pin_GPIO6) -#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) -#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) #define DEFAULT_UART_BUS_RX (&pin_GPIO1) From 66d0f753b152f4cdc958f529d4c7a6de8b89e572 Mon Sep 17 00:00:00 2001 From: Bernhard Bablok Date: Wed, 23 Apr 2025 08:03:17 +0200 Subject: [PATCH 6/6] fix memory corruption caused by pre-loading --- ports/espressif/common-hal/audiobusio/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/espressif/common-hal/audiobusio/__init__.c b/ports/espressif/common-hal/audiobusio/__init__.c index 226e371c5b0b0..d07a0b521ba9b 100644 --- a/ports/espressif/common-hal/audiobusio/__init__.c +++ b/ports/espressif/common-hal/audiobusio/__init__.c @@ -184,7 +184,7 @@ void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) { self->next_buffer_size = sizeof(starting_frame); i2s_fill_buffer(self); i2s_channel_preload_data(self->handle, &starting_frame, sizeof(uint32_t), &bytes_loaded); - preloaded += 1; + preloaded += bytes_loaded; } // enable the channel