Skip to content

Commit 57391fa

Browse files
committed
Unify echo_buffer_pos regardless of freq_shift, remove redundant echo_buffer_write_pos, and split buffer for stereo output when freq_shift=True.
1 parent 47c9fc1 commit 57391fa

File tree

2 files changed

+43
-51
lines changed

2 files changed

+43
-51
lines changed

shared-module/audiodelays/Echo.c

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -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

108107
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) {
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

176176
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+
}
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

shared-module/audiodelays/Echo.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,9 @@ typedef struct {
3737
uint32_t echo_buffer_len; // bytes
3838
uint32_t max_echo_buffer_len; // bytes
3939

40-
uint32_t echo_buffer_read_pos; // words
41-
uint32_t echo_buffer_write_pos; // words
42-
43-
uint32_t echo_buffer_rate; // words << 8
44-
uint32_t echo_buffer_left_pos; // words << 8
40+
uint32_t echo_buffer_pos; // words (<< 8 when freq_shift=True)
4541
uint32_t echo_buffer_right_pos; // words << 8
42+
uint32_t echo_buffer_rate; // words << 8
4643

4744
mp_obj_t sample;
4845
} audiodelays_echo_obj_t;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy