@@ -98,11 +98,10 @@ void common_hal_audiodelays_echo_construct(audiodelays_echo_obj_t *self, uint32_
98
98
99
99
// read is where we read previous echo from delay_ms ago to play back now
100
100
// 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 ;
103
102
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 ;
106
105
}
107
106
108
107
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) {
131
130
if (self -> freq_shift ) {
132
131
// Calculate the rate of iteration over the echo buffer with 8 sub-bits
133
132
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 );
135
135
} else {
136
136
// Calculate the current echo buffer length in bytes
137
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 ));
@@ -174,6 +174,12 @@ bool common_hal_audiodelays_echo_get_freq_shift(audiodelays_echo_obj_t *self) {
174
174
}
175
175
176
176
void 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
+ }
177
183
self -> freq_shift = freq_shift ;
178
184
uint32_t delay_ms = (uint32_t )synthio_block_slot_get (& self -> delay_ms );
179
185
recalculate_delay (self , delay_ms );
@@ -275,12 +281,9 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
275
281
uint32_t echo_buf_len = self -> echo_buffer_len / sizeof (uint16_t );
276
282
277
283
// 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 ;
284
287
}
285
288
286
289
// 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 *
304
307
for (uint32_t i = 0 ; i < length ; i ++ ) {
305
308
int16_t echo , word = 0 ;
306
309
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 ));
307
311
308
312
if (self -> freq_shift ) {
309
- echo = echo_buffer [echo_buffer_pos >> 8 ];
313
+ echo = echo_buffer [( echo_buffer_pos >> 8 ) + echo_buffer_offset ];
310
314
next_buffer_pos = echo_buffer_pos + self -> echo_buffer_rate ;
311
315
312
316
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 ;
315
319
}
316
320
} else {
317
- echo = echo_buffer [self -> echo_buffer_read_pos ++ ];
321
+ echo = echo_buffer [echo_buffer_pos ];
318
322
word = (int16_t )(echo * decay );
319
- echo_buffer [self -> echo_buffer_write_pos ++ ] = word ;
323
+ echo_buffer [echo_buffer_pos ++ ] = word ;
320
324
}
321
325
322
326
word = (int16_t )(echo * mix );
@@ -333,15 +337,10 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
333
337
}
334
338
}
335
339
336
- if (self -> freq_shift ) {
340
+ if (self -> freq_shift && ( single_channel_output || echo_buffer_offset ) ) {
337
341
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 ;
345
344
}
346
345
}
347
346
}
@@ -376,37 +375,39 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
376
375
377
376
int32_t echo , word = 0 ;
378
377
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
+
379
380
if (self -> freq_shift ) {
380
- echo = echo_buffer [echo_buffer_pos >> 8 ];
381
+ echo = echo_buffer [( echo_buffer_pos >> 8 ) + echo_buffer_offset ];
381
382
next_buffer_pos = echo_buffer_pos + self -> echo_buffer_rate ;
382
383
} else {
383
- echo = echo_buffer [self -> echo_buffer_read_pos ++ ];
384
+ echo = echo_buffer [echo_buffer_pos ];
384
385
word = (int32_t )(echo * decay + sample_word );
385
386
}
386
387
387
388
if (MP_LIKELY (self -> base .bits_per_sample == 16 )) {
388
389
if (self -> freq_shift ) {
389
390
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 );
391
392
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 ;
393
394
}
394
395
} else {
395
396
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 ;
397
398
}
398
399
} else {
399
400
if (self -> freq_shift ) {
400
401
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 );
402
403
// Do not have mix_down for 8 bit so just hard cap samples into 1 byte
403
404
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 ;
405
406
}
406
407
} else {
407
408
// Do not have mix_down for 8 bit so just hard cap samples into 1 byte
408
409
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 ;
410
411
}
411
412
}
412
413
@@ -427,15 +428,10 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
427
428
}
428
429
}
429
430
430
- if (self -> freq_shift ) {
431
+ if (self -> freq_shift && ( single_channel_output || echo_buffer_offset ) ) {
431
432
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 ;
439
435
}
440
436
}
441
437
}
@@ -448,12 +444,11 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
448
444
self -> sample_buffer_length -= n ;
449
445
}
450
446
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 ;
457
452
}
458
453
}
459
454
0 commit comments