Skip to content

Commit 1e4d766

Browse files
authored
Merge pull request #10288 from gamblor21/synthio_fixedpoint_fix
Fix for fixed point overflow in synthio
2 parents a1e2b0b + 5fcf8ae commit 1e4d766

13 files changed

+115112
-115109
lines changed

shared-module/audiofreeverb/Freeverb.c

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// Fixed point ideas from - Paul Stoffregen in the Teensy audio library https://github.com/PaulStoffregen/Audio/blob/master/effect_freeverb.cpp
99
//
1010
#include "shared-bindings/audiofreeverb/Freeverb.h"
11+
#include "shared-module/synthio/__init__.h"
1112

1213
#include <stdint.h>
1314
#include "py/runtime.h"
@@ -217,27 +218,6 @@ void common_hal_audiofreeverb_freeverb_stop(audiofreeverb_freeverb_obj_t *self)
217218
return;
218219
}
219220

220-
// cleaner sat16 by http://www.moseleyinstruments.com/
221-
static int16_t sat16(int32_t n, int rshift) {
222-
// we should always round towards 0
223-
// to avoid recirculating round-off noise
224-
//
225-
// a 2s complement positive number is always
226-
// rounded down, so we only need to take
227-
// care of negative numbers
228-
if (n < 0) {
229-
n = n + (~(0xFFFFFFFFUL << rshift));
230-
}
231-
n = n >> rshift;
232-
if (n > 32767) {
233-
return 32767;
234-
}
235-
if (n < -32768) {
236-
return -32768;
237-
}
238-
return n;
239-
}
240-
241221
audioio_get_buffer_result_t audiofreeverb_freeverb_get_buffer(audiofreeverb_freeverb_obj_t *self, bool single_channel_output, uint8_t channel,
242222
uint8_t **buffer, uint32_t *buffer_length) {
243223

@@ -301,35 +281,35 @@ audioio_get_buffer_result_t audiofreeverb_freeverb_get_buffer(audiofreeverb_free
301281
int16_t input, bufout, output;
302282
uint32_t channel_comb_offset = 0, channel_allpass_offset = 0;
303283

304-
input = sat16(sample_word * 8738, 17); // Initial input scaled down so we can add reverb
284+
input = synthio_sat16(sample_word * 8738, 17); // Initial input scaled down so we can add reverb
305285
sum = 0;
306286

307287
// Calculate each of the 8 comb buffers
308288
for (uint32_t j = 0 + channel_comb_offset; j < 8 + channel_comb_offset; j++) {
309289
bufout = self->combbuffers[j][self->combbufferindex[j]];
310290
sum += bufout;
311-
self->combfitlers[j] = sat16(bufout * damp2 + self->combfitlers[j] * damp1, 15);
312-
self->combbuffers[j][self->combbufferindex[j]] = sat16(input + sat16(self->combfitlers[j] * feedback, 15), 0);
291+
self->combfitlers[j] = synthio_sat16(bufout * damp2 + self->combfitlers[j] * damp1, 15);
292+
self->combbuffers[j][self->combbufferindex[j]] = synthio_sat16(input + synthio_sat16(self->combfitlers[j] * feedback, 15), 0);
313293
if (++self->combbufferindex[j] >= self->combbuffersizes[j]) {
314294
self->combbufferindex[j] = 0;
315295
}
316296
}
317297

318-
output = sat16(sum * 31457, 17); // 31457 = 0.24f with shift of 17
298+
output = synthio_sat16(sum * 31457, 17); // 31457 = 0.24f with shift of 17
319299

320300
// Calculate each of the 4 all pass buffers
321301
for (uint32_t j = 0 + channel_allpass_offset; j < 4 + channel_allpass_offset; j++) {
322302
bufout = self->allpassbuffers[j][self->allpassbufferindex[j]];
323303
self->allpassbuffers[j][self->allpassbufferindex[j]] = output + (bufout >> 1); // bufout >> 1 same as bufout*0.5f
324-
output = sat16(bufout - output, 1);
304+
output = synthio_sat16(bufout - output, 1);
325305
if (++self->allpassbufferindex[j] >= self->allpassbuffersizes[j]) {
326306
self->allpassbufferindex[j] = 0;
327307
}
328308
}
329309

330310
word = output * 30; // Add some volume back don't have to saturate as next step will
331311

332-
word = sat16(sample_word * mix_sample, 15) + sat16(word * mix_effect, 15);
312+
word = synthio_sat16(sample_word * mix_sample, 15) + synthio_sat16(word * mix_effect, 15);
333313
word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2));
334314
word_buffer[i] = (int16_t)word;
335315

shared-module/synthio/Biquad.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "shared-bindings/synthio/Biquad.h"
1010
#include "shared-module/synthio/Biquad.h"
1111
#include "shared-module/synthio/block.h"
12+
#include "shared-bindings/synthio/__init__.h"
1213

1314
typedef struct {
1415
mp_float_t s, c;
@@ -212,7 +213,7 @@ void synthio_biquad_filter_samples(mp_obj_t self_in, biquad_filter_state *st, in
212213

213214
for (size_t n = n_samples; n; --n, ++buffer) {
214215
int32_t input = *buffer;
215-
int32_t output = (b0 * input + b1 * x0 + b2 * x1 - a1 * y0 - a2 * y1 + (1 << (BIQUAD_SHIFT - 1))) >> BIQUAD_SHIFT;
216+
int32_t output = synthio_sat16((b0 * input + b1 * x0 + b2 * x1 - a1 * y0 - a2 * y1 + (1 << (BIQUAD_SHIFT - 1))), BIQUAD_SHIFT);
216217

217218
x1 = x0;
218219
x0 = input;

shared-module/synthio/__init__.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,26 @@ static const int16_t square_wave[] = {-32768, 32767};
2424
static const uint16_t notes[] = {8372, 8870, 9397, 9956, 10548, 11175, 11840,
2525
12544, 13290, 14080, 14917, 15804}; // 9th octave
2626

27+
// cleaner sat16 by http://www.moseleyinstruments.com/
28+
int16_t synthio_sat16(int32_t n, int rshift) {
29+
// we should always round towards 0
30+
// to avoid recirculating round-off noise
31+
//
32+
// a 2s complement positive number is always
33+
// rounded down, so we only need to take
34+
// care of negative numbers
35+
if (n < 0) {
36+
n = n + (~(0xFFFFFFFFUL << rshift));
37+
}
38+
n = n >> rshift;
39+
if (n > 32767) {
40+
return 32767;
41+
}
42+
if (n < -32768) {
43+
return -32768;
44+
}
45+
return n;
46+
}
2747

2848
static int64_t round_float_to_int64(mp_float_t f) {
2949
return (int64_t)(f + MICROPY_FLOAT_CONST(0.5));
@@ -250,7 +270,7 @@ static bool synth_note_into_buffer(synthio_synth_t *synth, int chan, int32_t *ou
250270
accum = accum - lim + offset;
251271
}
252272
int16_t idx = accum >> SYNTHIO_FREQUENCY_SHIFT;
253-
int16_t wi = (ring_waveform[idx] * out_buffer32[i]) / 32768;
273+
int16_t wi = (ring_waveform[idx] * out_buffer32[i]) / 32768; // consider for synthio_sat16 but had a weird artificat
254274
out_buffer32[i] = wi;
255275
}
256276
synth->ring_accum[chan] = accum;
@@ -272,12 +292,12 @@ static mp_obj_t synthio_synth_get_note_filter(mp_obj_t note_obj) {
272292
static void sum_with_loudness(int32_t *out_buffer32, int32_t *tmp_buffer32, int16_t loudness[2], size_t dur, int synth_chan) {
273293
if (synth_chan == 1) {
274294
for (size_t i = 0; i < dur; i++) {
275-
*out_buffer32++ += (*tmp_buffer32++ *loudness[0]) >> 16;
295+
*out_buffer32++ += synthio_sat16((*tmp_buffer32++ *loudness[0]), 16);
276296
}
277297
} else {
278298
for (size_t i = 0; i < dur; i++) {
279-
*out_buffer32++ += (*tmp_buffer32 * loudness[0]) >> 16;
280-
*out_buffer32++ += (*tmp_buffer32++ *loudness[1]) >> 16;
299+
*out_buffer32++ += synthio_sat16((*tmp_buffer32 * loudness[0]), 16);
300+
*out_buffer32++ += synthio_sat16((*tmp_buffer32++ *loudness[1]), 16);
281301
}
282302
}
283303
}

shared-module/synthio/__init__.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,5 @@ int synthio_sweep_in_step(synthio_lfo_state_t *state, uint16_t dur);
9595
extern mp_float_t synthio_global_rate_scale, synthio_global_W_scale;
9696
extern uint8_t synthio_global_tick;
9797
void shared_bindings_synthio_lfo_tick(uint32_t sample_rate, uint16_t num_samples);
98+
99+
int16_t synthio_sat16(int32_t n, int rshift);

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