@@ -98,9 +98,9 @@ void common_hal_audiodelays_echo_construct(audiodelays_echo_obj_t *self, uint32_
9898
9999 // read is where we read previous echo from delay_ms ago to play back now
100100 // write is where the store the latest playing sample to echo back later
101- self -> echo_buffer_pos = 0 ;
101+ self -> echo_buffer_left_pos = 0 ;
102102
103- // use a separate buffer position for the right channel when using freq_shift
103+ // use a separate buffer position for the right channel
104104 self -> echo_buffer_right_pos = 0 ;
105105}
106106
@@ -127,18 +127,21 @@ void recalculate_delay(audiodelays_echo_obj_t *self, mp_float_t f_delay_ms) {
127127 // Require that delay is at least 1 sample long
128128 f_delay_ms = MAX (f_delay_ms , self -> sample_ms );
129129
130+ // Calculate the maximum buffer size per channel in bytes
131+ uint32_t max_echo_buffer_len = self -> max_echo_buffer_len >> (self -> base .channel_count - 1 );
132+
130133 if (self -> freq_shift ) {
131134 // Calculate the rate of iteration over the echo buffer with 8 sub-bits
132135 self -> echo_buffer_rate = (uint32_t )MAX (self -> max_delay_ms / f_delay_ms * MICROPY_FLOAT_CONST (256.0 ), MICROPY_FLOAT_CONST (1.0 ));
133136 // Only use half of the buffer per channel if stereo
134- self -> echo_buffer_len = self -> max_echo_buffer_len >> ( self -> base . channel_count - 1 ) ;
137+ self -> echo_buffer_len = max_echo_buffer_len ;
135138 } else {
136139 // Calculate the current echo buffer length in bytes
137- 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 ) );
140+ uint32_t new_echo_buffer_len = (uint32_t )(self -> base .sample_rate / MICROPY_FLOAT_CONST (1000.0 ) * f_delay_ms ) * sizeof (uint16_t );
138141
139142 // Limit to valid range
140- if (new_echo_buffer_len > self -> max_echo_buffer_len ) {
141- new_echo_buffer_len = self -> max_echo_buffer_len ;
143+ if (new_echo_buffer_len > max_echo_buffer_len ) {
144+ new_echo_buffer_len = max_echo_buffer_len ;
142145 } else if (new_echo_buffer_len < self -> buffer_len ) {
143146 // If the echo buffer is smaller than our audio buffer, weird things happen
144147 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) {
147150 self -> echo_buffer_len = new_echo_buffer_len ;
148151
149152 // Clear the now unused part of the buffer or some weird artifacts appear
150- memset (self -> echo_buffer + self -> echo_buffer_len , 0 , self -> max_echo_buffer_len - self -> echo_buffer_len );
153+ for (uint32_t i = 0 ; i < self -> base .channel_count ; i ++ ) {
154+ memset (self -> echo_buffer + (i * max_echo_buffer_len ) + self -> echo_buffer_len , 0 , max_echo_buffer_len - self -> echo_buffer_len );
155+ }
151156 }
152157
153158 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
177182 // Clear the echo buffer and reset buffer position if changing freq_shift modes
178183 if (self -> freq_shift != freq_shift ) {
179184 memset (self -> echo_buffer , 0 , self -> max_echo_buffer_len );
180- self -> echo_buffer_pos = 0 ;
185+ self -> echo_buffer_left_pos = 0 ;
181186 self -> echo_buffer_right_pos = 0 ;
182187 }
183188 self -> freq_shift = freq_shift ;
@@ -279,12 +284,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
279284 }
280285
281286 uint32_t echo_buf_len = self -> echo_buffer_len / sizeof (uint16_t );
282-
283- // Set our echo buffer position accounting for stereo
284- uint32_t echo_buffer_pos = self -> echo_buffer_pos ;
285- if (self -> freq_shift && channel == 1 ) {
286- echo_buffer_pos = self -> echo_buffer_right_pos ;
287- }
287+ uint32_t max_echo_buf_len = (self -> max_echo_buffer_len >> (self -> base .channel_count - 1 )) / sizeof (uint16_t );
288288
289289 // If we have no sample keep the echo echoing
290290 if (self -> sample == NULL ) {
@@ -307,7 +307,10 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
307307 for (uint32_t i = 0 ; i < length ; i ++ ) {
308308 int16_t echo , word = 0 ;
309309 uint32_t next_buffer_pos = 0 ;
310- 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 )));
310+
311+ // Get our echo buffer position and offset depending on current channel
312+ uint32_t echo_buffer_offset = max_echo_buf_len * ((single_channel_output && channel == 1 ) || (!single_channel_output && (i % self -> base .channel_count ) == 1 ));
313+ uint32_t echo_buffer_pos = echo_buffer_offset ? self -> echo_buffer_right_pos : self -> echo_buffer_left_pos ;
311314
312315 if (self -> freq_shift ) {
313316 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 *
318321 echo_buffer [(j % echo_buf_len ) + echo_buffer_offset ] = word ;
319322 }
320323 } else {
321- echo = echo_buffer [echo_buffer_pos ];
324+ echo = echo_buffer [echo_buffer_pos + echo_buffer_offset ];
322325 word = (int16_t )(echo * decay );
323- echo_buffer [echo_buffer_pos ++ ] = word ;
326+ echo_buffer [echo_buffer_pos ++ + echo_buffer_offset ] = word ;
324327 }
325328
326329 word = (int16_t )(echo * mix );
@@ -337,11 +340,18 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
337340 }
338341 }
339342
340- if (self -> freq_shift && ( self -> base . channel_count == 1 || single_channel_output || (! single_channel_output && ( i % self -> base . channel_count ) == 1 )) ) {
343+ if (self -> freq_shift ) {
341344 echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8 );
342345 } else if (!self -> freq_shift && echo_buffer_pos >= echo_buf_len ) {
343346 echo_buffer_pos = 0 ;
344347 }
348+
349+ // Update buffer position
350+ if (echo_buffer_offset ) {
351+ self -> echo_buffer_right_pos = echo_buffer_pos ;
352+ } else {
353+ self -> echo_buffer_left_pos = echo_buffer_pos ;
354+ }
345355 }
346356 }
347357
@@ -375,13 +385,16 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
375385
376386 int32_t echo , word = 0 ;
377387 uint32_t next_buffer_pos = 0 ;
378- 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 )));
388+
389+ // Get our echo buffer position and offset depending on current channel
390+ uint32_t echo_buffer_offset = max_echo_buf_len * ((single_channel_output && channel == 1 ) || (!single_channel_output && (i % self -> base .channel_count ) == 1 ));
391+ uint32_t echo_buffer_pos = echo_buffer_offset ? self -> echo_buffer_right_pos : self -> echo_buffer_left_pos ;
379392
380393 if (self -> freq_shift ) {
381394 echo = echo_buffer [(echo_buffer_pos >> 8 ) + echo_buffer_offset ];
382395 next_buffer_pos = echo_buffer_pos + self -> echo_buffer_rate ;
383396 } else {
384- echo = echo_buffer [echo_buffer_pos ];
397+ echo = echo_buffer [echo_buffer_pos + echo_buffer_offset ];
385398 word = (int32_t )(echo * decay + sample_word );
386399 }
387400
@@ -394,7 +407,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
394407 }
395408 } else {
396409 word = synthio_mix_down_sample (word , SYNTHIO_MIX_DOWN_SCALE (2 ));
397- echo_buffer [echo_buffer_pos ++ ] = (int16_t )word ;
410+ echo_buffer [echo_buffer_pos ++ + echo_buffer_offset ] = (int16_t )word ;
398411 }
399412 } else {
400413 if (self -> freq_shift ) {
@@ -407,7 +420,7 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
407420 } else {
408421 // Do not have mix_down for 8 bit so just hard cap samples into 1 byte
409422 word = MIN (MAX (word , -128 ), 127 );
410- echo_buffer [echo_buffer_pos ++ ] = (int8_t )word ;
423+ echo_buffer [echo_buffer_pos ++ + echo_buffer_offset ] = (int8_t )word ;
411424 }
412425 }
413426
@@ -428,11 +441,18 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
428441 }
429442 }
430443
431- if (self -> freq_shift && ( self -> base . channel_count == 1 || single_channel_output || (! single_channel_output && ( i % self -> base . channel_count ) == 1 )) ) {
444+ if (self -> freq_shift ) {
432445 echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8 );
433446 } else if (!self -> freq_shift && echo_buffer_pos >= echo_buf_len ) {
434447 echo_buffer_pos = 0 ;
435448 }
449+
450+ // Update buffer position
451+ if (echo_buffer_offset ) {
452+ self -> echo_buffer_right_pos = echo_buffer_pos ;
453+ } else {
454+ self -> echo_buffer_left_pos = echo_buffer_pos ;
455+ }
436456 }
437457 }
438458
@@ -443,13 +463,6 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
443463 self -> sample_remaining_buffer += (n * (self -> base .bits_per_sample / 8 ));
444464 self -> sample_buffer_length -= n ;
445465 }
446-
447- // Update buffer position
448- if (self -> freq_shift && channel == 1 ) {
449- self -> echo_buffer_right_pos = echo_buffer_pos ;
450- } else {
451- self -> echo_buffer_pos = echo_buffer_pos ;
452- }
453466 }
454467
455468 // Finally pass our buffer and length to the calling audio function
0 commit comments