@@ -98,11 +98,10 @@ 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_read_pos = self -> buffer_len / sizeof (uint16_t );
102- self -> echo_buffer_write_pos = 0 ;
101+ self -> echo_buffer_pos = 0 ;
103102
104- // where we read the previous echo from delay_ms ago to play back now (for freq shift)
105- self -> echo_buffer_left_pos = self -> echo_buffer_right_pos = 0 ;
103+ // use a separate buffer position for the right channel when using freq_shift
104+ self -> echo_buffer_right_pos = 0 ;
106105}
107106
108107void 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) {
131130 if (self -> freq_shift ) {
132131 // Calculate the rate of iteration over the echo buffer with 8 sub-bits
133132 self -> echo_buffer_rate = (uint32_t )MAX (self -> max_delay_ms / f_delay_ms * MICROPY_FLOAT_CONST (256.0 ), MICROPY_FLOAT_CONST (1.0 ));
134- self -> echo_buffer_len = self -> max_echo_buffer_len ;
133+ // 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 );
135135 } else {
136136 // Calculate the current echo buffer length in bytes
137137 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) {
174174}
175175
176176void common_hal_audiodelays_echo_set_freq_shift (audiodelays_echo_obj_t * self , bool freq_shift ) {
177+ // Clear the echo buffer and reset buffer position if changing freq_shift modes
178+ if (self -> freq_shift != freq_shift ) {
179+ memset (self -> echo_buffer , 0 , self -> max_echo_buffer_len );
180+ self -> echo_buffer_pos = 0 ;
181+ self -> echo_buffer_right_pos = 0 ;
182+ }
177183 self -> freq_shift = freq_shift ;
178184 uint32_t delay_ms = (uint32_t )synthio_block_slot_get (& self -> delay_ms );
179185 recalculate_delay (self , delay_ms );
@@ -275,12 +281,9 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
275281 uint32_t echo_buf_len = self -> echo_buffer_len / sizeof (uint16_t );
276282
277283 // Set our echo buffer position accounting for stereo
278- uint32_t echo_buffer_pos = 0 ;
279- if (self -> freq_shift ) {
280- echo_buffer_pos = self -> echo_buffer_left_pos ;
281- if (channel == 1 ) {
282- echo_buffer_pos = self -> echo_buffer_right_pos ;
283- }
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 ;
284287 }
285288
286289 // 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 *
304307 for (uint32_t i = 0 ; i < length ; i ++ ) {
305308 int16_t echo , word = 0 ;
306309 uint32_t next_buffer_pos = 0 ;
310+ uint32_t echo_buffer_offset = echo_buf_len * (self -> freq_shift && (channel == 1 || (i % self -> base .channel_count ) == 1 ));
307311
308312 if (self -> freq_shift ) {
309- echo = echo_buffer [echo_buffer_pos >> 8 ];
313+ echo = echo_buffer [( echo_buffer_pos >> 8 ) + echo_buffer_offset ];
310314 next_buffer_pos = echo_buffer_pos + self -> echo_buffer_rate ;
311315
312316 for (uint32_t j = echo_buffer_pos >> 8 ; j < next_buffer_pos >> 8 ; j ++ ) {
313- word = (int16_t )(echo_buffer [j % echo_buf_len ] * decay );
314- echo_buffer [j % echo_buf_len ] = word ;
317+ word = (int16_t )(echo_buffer [( j % echo_buf_len ) + echo_buffer_offset ] * decay );
318+ echo_buffer [( j % echo_buf_len ) + echo_buffer_offset ] = word ;
315319 }
316320 } else {
317- echo = echo_buffer [self -> echo_buffer_read_pos ++ ];
321+ echo = echo_buffer [echo_buffer_pos ];
318322 word = (int16_t )(echo * decay );
319- echo_buffer [self -> echo_buffer_write_pos ++ ] = word ;
323+ echo_buffer [echo_buffer_pos ++ ] = word ;
320324 }
321325
322326 word = (int16_t )(echo * mix );
@@ -333,15 +337,10 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
333337 }
334338 }
335339
336- if (self -> freq_shift ) {
340+ if (self -> freq_shift && ( single_channel_output || echo_buffer_offset ) ) {
337341 echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8 );
338- } else {
339- if (self -> echo_buffer_read_pos >= echo_buf_len ) {
340- self -> echo_buffer_read_pos = 0 ;
341- }
342- if (self -> echo_buffer_write_pos >= echo_buf_len ) {
343- self -> echo_buffer_write_pos = 0 ;
344- }
342+ } else if (!self -> freq_shift && echo_buffer_pos >= echo_buf_len ) {
343+ echo_buffer_pos = 0 ;
345344 }
346345 }
347346 }
@@ -376,37 +375,39 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
376375
377376 int32_t echo , word = 0 ;
378377 uint32_t next_buffer_pos = 0 ;
378+ uint32_t echo_buffer_offset = echo_buf_len * (self -> freq_shift && (channel == 1 || (i % self -> base .channel_count ) == 1 ));
379+
379380 if (self -> freq_shift ) {
380- echo = echo_buffer [echo_buffer_pos >> 8 ];
381+ echo = echo_buffer [( echo_buffer_pos >> 8 ) + echo_buffer_offset ];
381382 next_buffer_pos = echo_buffer_pos + self -> echo_buffer_rate ;
382383 } else {
383- echo = echo_buffer [self -> echo_buffer_read_pos ++ ];
384+ echo = echo_buffer [echo_buffer_pos ];
384385 word = (int32_t )(echo * decay + sample_word );
385386 }
386387
387388 if (MP_LIKELY (self -> base .bits_per_sample == 16 )) {
388389 if (self -> freq_shift ) {
389390 for (uint32_t j = echo_buffer_pos >> 8 ; j < next_buffer_pos >> 8 ; j ++ ) {
390- word = (int32_t )(echo_buffer [j % echo_buf_len ] * decay + sample_word );
391+ word = (int32_t )(echo_buffer [( j % echo_buf_len ) + echo_buffer_offset ] * decay + sample_word );
391392 word = synthio_mix_down_sample (word , SYNTHIO_MIX_DOWN_SCALE (2 ));
392- echo_buffer [j % echo_buf_len ] = (int16_t )word ;
393+ echo_buffer [( j % echo_buf_len ) + echo_buffer_offset ] = (int16_t )word ;
393394 }
394395 } else {
395396 word = synthio_mix_down_sample (word , SYNTHIO_MIX_DOWN_SCALE (2 ));
396- echo_buffer [self -> echo_buffer_write_pos ++ ] = (int16_t )word ;
397+ echo_buffer [echo_buffer_pos ++ ] = (int16_t )word ;
397398 }
398399 } else {
399400 if (self -> freq_shift ) {
400401 for (uint32_t j = echo_buffer_pos >> 8 ; j < next_buffer_pos >> 8 ; j ++ ) {
401- word = (int32_t )(echo_buffer [j % echo_buf_len ] * decay + sample_word );
402+ word = (int32_t )(echo_buffer [( j % echo_buf_len ) + echo_buffer_offset ] * decay + sample_word );
402403 // Do not have mix_down for 8 bit so just hard cap samples into 1 byte
403404 word = MIN (MAX (word , -128 ), 127 );
404- echo_buffer [j % echo_buf_len ] = (int8_t )word ;
405+ echo_buffer [( j % echo_buf_len ) + echo_buffer_offset ] = (int8_t )word ;
405406 }
406407 } else {
407408 // Do not have mix_down for 8 bit so just hard cap samples into 1 byte
408409 word = MIN (MAX (word , -128 ), 127 );
409- echo_buffer [self -> echo_buffer_write_pos ++ ] = (int8_t )word ;
410+ echo_buffer [echo_buffer_pos ++ ] = (int8_t )word ;
410411 }
411412 }
412413
@@ -427,15 +428,10 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
427428 }
428429 }
429430
430- if (self -> freq_shift ) {
431+ if (self -> freq_shift && ( single_channel_output || echo_buffer_offset ) ) {
431432 echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8 );
432- } else {
433- if (self -> echo_buffer_read_pos >= echo_buf_len ) {
434- self -> echo_buffer_read_pos = 0 ;
435- }
436- if (self -> echo_buffer_write_pos >= echo_buf_len ) {
437- self -> echo_buffer_write_pos = 0 ;
438- }
433+ } else if (!self -> freq_shift && echo_buffer_pos >= echo_buf_len ) {
434+ echo_buffer_pos = 0 ;
439435 }
440436 }
441437 }
@@ -448,12 +444,11 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
448444 self -> sample_buffer_length -= n ;
449445 }
450446
451- if (self -> freq_shift ) {
452- if (channel == 0 ) {
453- self -> echo_buffer_left_pos = echo_buffer_pos ;
454- } else if (channel == 1 ) {
455- self -> echo_buffer_right_pos = echo_buffer_pos ;
456- }
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 ;
457452 }
458453 }
459454
0 commit comments