Skip to content

Commit 70c0bf9

Browse files
committed
8 bit unsigned samples working
1 parent bbd3e01 commit 70c0bf9

File tree

1 file changed

+90
-82
lines changed
  • shared-module/audiodelays

1 file changed

+90
-82
lines changed

shared-module/audiodelays/Echo.c

Lines changed: 90 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ void common_hal_audiodelays_echo_construct(audiodelays_echo_obj_t *self, uint32_
7676

7777
// Allocate the echo buffer for the max possible delay
7878
self->max_delay_ms = max_delay_ms;
79-
self->max_echo_buffer_len = self->sample_rate / 1000.0f * max_delay_ms * (self->channel_count * (self->bits_per_sample / 8)); // bytes
79+
self->max_echo_buffer_len = self->sample_rate / 1000.0f * max_delay_ms * (self->channel_count * 2);// (self->bits_per_sample / 8)); // bytes
8080
self->echo_buffer = m_malloc(self->max_echo_buffer_len);
8181
if (self->echo_buffer == NULL) {
8282
common_hal_audiodelays_echo_deinit(self);
@@ -86,11 +86,11 @@ void common_hal_audiodelays_echo_construct(audiodelays_echo_obj_t *self, uint32_
8686

8787
// calculate current echo buffer size we use for the given delay
8888
mp_float_t f_delay_ms = synthio_block_slot_get(&self->delay_ms);
89-
self->echo_buffer_len = self->sample_rate / 1000.0f * f_delay_ms * (self->channel_count * (self->bits_per_sample / 8));
89+
self->echo_buffer_len = self->sample_rate / 1000.0f * f_delay_ms * (self->channel_count * 2);// (self->bits_per_sample / 8));
9090

9191
// read is where we store the incoming sample + previous echo
9292
// write is what we send to the outgoing buffer
93-
self->echo_buffer_read_pos = self->buffer_len / (self->bits_per_sample / 8);
93+
self->echo_buffer_read_pos = self->buffer_len / 2;// (self->bits_per_sample / 8);
9494
self->echo_buffer_write_pos = 0;
9595
}
9696

@@ -119,9 +119,9 @@ void common_hal_audiodelays_echo_set_delay_ms(audiodelays_echo_obj_t *self, mp_o
119119
synthio_block_assign_slot(delay_ms, &self->delay_ms, MP_QSTR_delay_ms);
120120

121121
mp_float_t f_delay_ms = synthio_block_slot_get(&self->delay_ms);
122-
self->echo_buffer_len = self->sample_rate / 1000.0f * f_delay_ms * (self->channel_count * (self->bits_per_sample / 8));
122+
self->echo_buffer_len = self->sample_rate / 1000.0f * f_delay_ms * (self->channel_count * 2);// (self->bits_per_sample / 8));
123123

124-
uint32_t max_ebuf_length = self->echo_buffer_len / sizeof(uint32_t);
124+
uint32_t max_ebuf_length = self->echo_buffer_len / sizeof(uint16_t);
125125

126126
if (self->echo_buffer_read_pos > max_ebuf_length) {
127127
self->echo_buffer_read_pos = 0;
@@ -249,12 +249,15 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
249249
// Switch our buffers to the other buffer
250250
self->last_buf_idx = !self->last_buf_idx;
251251

252-
// If we are using 16 bit samples we need a 16 bit pointer, for 8 bit we can just use the buffer
252+
// If we are using 16 bit samples we need a 16 bit pointer
253253
int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx];
254+
int8_t *hword_buffer = self->buffer[self->last_buf_idx];
254255
uint32_t length = self->buffer_len / (self->bits_per_sample / 8);
255256

257+
// The echo buffer is always stored as a 16-bit value internally
256258
int16_t *echo_buffer = (int16_t *)self->echo_buffer;
257-
uint32_t echo_buf_len = self->echo_buffer_len / (self->bits_per_sample / 8);
259+
uint32_t echo_buf_len = self->echo_buffer_len / 2;// (self->bits_per_sample / 8);
260+
258261

259262
// Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample
260263
while (length != 0) {
@@ -279,45 +282,38 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
279282

280283
// If we have no sample keep the echo echoing
281284
if (self->sample == NULL) {
282-
if (MP_LIKELY(self->bits_per_sample == 16)) {
283-
if (mix <= 0.01) { // Mix of 0 is pure sample sound. We have no sample so no sound
284-
memset(word_buffer, 0, length * sizeof(uint16_t));
285+
if (mix <= 0.01) { // Mix of 0 is pure sample sound. We have no sample so no sound
286+
if (self->samples_signed) {
287+
memset(word_buffer, 0, length * (self->bits_per_sample / 8));
285288
} else {
286-
// Since we have no sample we can just iterate over the our entire buffer
287-
for (uint32_t i = 0; i < length; i++) {
288-
word_buffer[i] = echo_buffer[self->echo_buffer_read_pos++] * decay;
289-
290-
echo_buffer[self->echo_buffer_write_pos++] = word_buffer[i];
291-
292-
word_buffer[i] = word_buffer[i] * mix;
293-
294-
if (self->echo_buffer_read_pos >= echo_buf_len) {
295-
self->echo_buffer_read_pos = 0;
289+
memset(hword_buffer, 128, length * (self->bits_per_sample / 8));
290+
}
291+
} else {
292+
// Since we have no sample we can just iterate over the our entire remaining buffer
293+
for (uint32_t i = 0; i < length; i++) {
294+
int16_t echo = echo_buffer[self->echo_buffer_read_pos++] * decay;
295+
echo_buffer[self->echo_buffer_write_pos++] = echo;
296+
297+
if (MP_LIKELY(self->bits_per_sample == 16)) {
298+
word_buffer[i] = echo * mix;
299+
if (!self->samples_signed) {
300+
word_buffer[i] ^= 0x8000;
296301
}
297-
if (self->echo_buffer_write_pos >= echo_buf_len) {
298-
self->echo_buffer_write_pos = 0;
302+
} else {
303+
echo = echo * mix;
304+
hword_buffer[i] = echo;
305+
if (!self->samples_signed) {
306+
hword_buffer[i] ^= 0x80;
299307
}
300308
}
301309

302-
}
303-
} else { // bits per sample is 8
304-
/* Still to be updated
305-
uint16_t *hword_buffer = (uint16_t *)word_buffer;
306-
uint16_t *echo_hsrc = (uint16_t *)self->echo_buffer;
307-
for (uint32_t i = 0; i < length * 2; i++) {
308-
uint32_t echo_word = unpack8(echo_hsrc[i]);
309-
echo_word = echo_word * decay;
310-
hword_buffer[i] = pack8(echo_word);
311-
312-
echo_hsrc[self->echo_buffer_write_pos++] = hword_buffer[i];
313-
if (self->echo_buffer_read_pos >= echo_buf_len) {
314-
self->echo_buffer_read_pos = 0;
315-
}
316-
if (self->echo_buffer_write_pos >= echo_buf_len) {
317-
self->echo_buffer_write_pos = 0;
318-
}
310+
if (self->echo_buffer_read_pos >= echo_buf_len) {
311+
self->echo_buffer_read_pos = 0;
312+
}
313+
if (self->echo_buffer_write_pos >= echo_buf_len) {
314+
self->echo_buffer_write_pos = 0;
319315
}
320-
*/
316+
}
321317
}
322318

323319
length = 0;
@@ -328,62 +324,74 @@ audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *
328324
uint32_t n = MIN(self->sample_buffer_length, length);
329325

330326
int16_t *sample_src = (int16_t *)self->sample_remaining_buffer;
327+
int8_t *sample_hsrc = (int8_t *)self->sample_remaining_buffer;
331328

332-
if (MP_LIKELY(self->bits_per_sample == 16)) {
333-
if (mix <= 0.01) { // if mix is zero pure sample only
334-
for (uint32_t i = 0; i < n; i++) {
329+
if (mix <= 0.01) { // if mix is zero pure sample only
330+
for (uint32_t i = 0; i < n; i++) {
331+
if (MP_LIKELY(self->bits_per_sample == 16)) {
335332
word_buffer[i] = sample_src[i];
333+
} else {
334+
hword_buffer[i] = sample_hsrc[i];
336335
}
337-
} else {
338-
for (uint32_t i = 0; i < n; i++) {
339-
int32_t sample_word = sample_src[i];
340-
if (!self->samples_signed) {
341-
sample_word = tosigned16(sample_word);
336+
}
337+
} else {
338+
for (uint32_t i = 0; i < n; i++) {
339+
int32_t sample_word = 0;
340+
if (MP_LIKELY(self->bits_per_sample == 16)) {
341+
sample_word = sample_src[i];
342+
} else {
343+
if (self->samples_signed) {
344+
sample_word = sample_hsrc[i];
345+
} else {
346+
// uint8_t s1 = sample_hsrc[i];
347+
// int8_t s2 = s1^0x80;
348+
// sample_word = s2;
349+
350+
sample_word = (int8_t)(((uint8_t)sample_hsrc[i]) ^ 0x80);
342351
}
352+
}
343353

344-
int32_t word = (echo_buffer[self->echo_buffer_read_pos++] * decay) + sample_word;
345-
word_buffer[i] = mix_down_sample(word);
346-
347-
echo_buffer[self->echo_buffer_write_pos++] = word_buffer[i];
348-
349-
if (self->echo_buffer_read_pos >= echo_buf_len) {
350-
self->echo_buffer_read_pos = 0;
354+
int32_t echo = echo_buffer[self->echo_buffer_read_pos++] * decay;
355+
int32_t word = echo + sample_word;
356+
if (MP_LIKELY(self->bits_per_sample == 16)) {
357+
word = mix_down_sample(word);
358+
echo_buffer[self->echo_buffer_write_pos++] = (int16_t)word;
359+
} else {
360+
if (word > 127) {
361+
word = 127;
362+
} else if (word < -128) {
363+
word = -128;
351364
}
352-
if (self->echo_buffer_write_pos >= echo_buf_len) {
353-
self->echo_buffer_write_pos = 0;
354-
}
355-
356-
word_buffer[i] = (sample_word * (1.0 - mix)) + (word_buffer[i] * mix);
365+
echo_buffer[self->echo_buffer_write_pos++] = (int8_t)word;
357366
}
358-
}
359-
} else { // bits per sample is 8
360-
/* to be updated
361-
uint16_t *hword_buffer = (uint16_t *)word_buffer;
362-
uint16_t *sample_hsrc = (uint16_t *)sample_src;
363-
uint16_t *echo_hsrc = (uint16_t *)self->echo_buffer;
364-
for (uint32_t i = 0; i < n * 2; i++) {
365-
uint32_t sample_word = unpack8(sample_hsrc[i]);
366-
uint32_t echo_word = unpack8(echo_hsrc[i]);
367-
if (MP_LIKELY(!self->samples_signed)) {
368-
sample_word = tosigned16(sample_word);
369-
}
370-
echo_word = echo_word * decay;
371-
sample_word = sample_word + echo_word;
372-
hword_buffer[i] = pack8(sample_word);
373367

374-
echo_hsrc[self->echo_buffer_write_pos++] = pack8(sample_word + unpack8(hword_buffer[i]));
375-
if (self->echo_buffer_read_pos >= echo_buf_len) {
376-
self->echo_buffer_read_pos = 0;
368+
if (MP_LIKELY(self->bits_per_sample == 16)) {
369+
word_buffer[i] = (sample_word * (1.0 - mix)) + (word * mix);
370+
if (!self->samples_signed) {
371+
word_buffer[i] ^= 0x8000;
377372
}
378-
if (self->echo_buffer_write_pos >= echo_buf_len) {
379-
self->echo_buffer_write_pos = 0;
373+
} else {
374+
int8_t mixed = (sample_word * (1.0 - mix)) + (word * mix);
375+
;
376+
if (self->samples_signed) {
377+
hword_buffer[i] = mixed;
378+
} else {
379+
hword_buffer[i] = (uint8_t)mixed ^ 0x80;
380380
}
381381
}
382-
*/
382+
383+
if (self->echo_buffer_read_pos >= echo_buf_len) {
384+
self->echo_buffer_read_pos = 0;
385+
}
386+
if (self->echo_buffer_write_pos >= echo_buf_len) {
387+
self->echo_buffer_write_pos = 0;
388+
}
389+
}
383390
}
384391

385392
length -= n;
386393
word_buffer += n;
394+
hword_buffer += n;
387395
self->sample_remaining_buffer += n;
388396
self->sample_buffer_length -= n;
389397
}
@@ -398,7 +406,7 @@ void audiodelays_echo_get_buffer_structure(audiodelays_echo_obj_t *self, bool si
398406
bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing) {
399407

400408
*single_buffer = false;
401-
*samples_signed = true;
409+
*samples_signed = self->samples_signed;
402410
*max_buffer_length = self->buffer_len;
403411
if (single_channel_output) {
404412
*spacing = self->channel_count;

0 commit comments

Comments
 (0)