2727
2828#include "shared-module/synthio/__init__.h"
2929#include "shared-bindings/synthio/__init__.h"
30+ #include "shared-module/synthio/Biquad.h"
3031#include "shared-module/synthio/Note.h"
3132#include "py/runtime.h"
3233#include <math.h>
@@ -309,37 +310,15 @@ static void synth_note_into_buffer(synthio_synth_t *synth, int chan, int32_t *ou
309310 }
310311}
311312
312- STATIC void run_fir (synthio_synth_t * synth , int32_t * out_buffer32 , uint16_t dur ) {
313- int16_t * coeff = (int16_t * )synth -> filter_bufinfo .buf ;
314- size_t fir_len = synth -> filter_bufinfo .len ;
315- int32_t * in_buf = synth -> filter_buffer ;
316-
317-
318- int synth_chan = synth -> channel_count ;
319- // FIR and copy values to output buffer
320- for (int16_t i = 0 ; i < dur * synth_chan ; i ++ ) {
321- int32_t acc = 0 ;
322- for (size_t j = 0 ; j < fir_len ; j ++ ) {
323- // shift 5 here is good for up to 32 filtered voices, else might wrap
324- acc = acc + (in_buf [j * synth_chan ] * (coeff [j ] >> 5 ));
325- }
326- * out_buffer32 ++ = acc >> 10 ;
327- in_buf ++ ;
328- }
329-
330- // Move values down so that they get filtered next time
331- memmove (synth -> filter_buffer , & synth -> filter_buffer [dur * synth_chan ], fir_len * sizeof (int32_t ) * synth_chan );
332- }
333-
334- STATIC bool synthio_synth_get_note_filtered (mp_obj_t note_obj ) {
313+ STATIC mp_obj_t synthio_synth_get_note_filter (mp_obj_t note_obj ) {
335314 if (note_obj == mp_const_none ) {
336- return false ;
315+ return mp_const_none ;
337316 }
338317 if (!mp_obj_is_small_int (note_obj )) {
339318 synthio_note_obj_t * note = MP_OBJ_TO_PTR (note_obj );
340- return note -> filter ;
319+ return note -> filter_obj ;
341320 }
342- return true ;
321+ return mp_const_none ;
343322}
344323
345324void synthio_synth_synthesize (synthio_synth_t * synth , uint8_t * * bufptr , uint32_t * buffer_length , uint8_t channel ) {
@@ -360,30 +339,24 @@ void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t
360339 synth -> span .dur -= dur ;
361340
362341 int32_t out_buffer32 [dur * synth -> channel_count ];
363-
364- if (synth -> filter_buffer ) {
365- int32_t * filter_start = & synth -> filter_buffer [synth -> filter_bufinfo .len * synth -> channel_count ];
366- memset (filter_start , 0 , dur * synth -> channel_count * sizeof (int32_t ));
367-
368- for (int chan = 0 ; chan < CIRCUITPY_SYNTHIO_MAX_CHANNELS ; chan ++ ) {
369- mp_obj_t note_obj = synth -> span .note_obj [chan ];
370- if (!synthio_synth_get_note_filtered (note_obj )) {
371- continue ;
372- }
373- synth_note_into_buffer (synth , chan , filter_start , dur );
374- }
375-
376- run_fir (synth , out_buffer32 , dur );
377- } else {
378- memset (out_buffer32 , 0 , sizeof (out_buffer32 ));
379- }
342+ memset (out_buffer32 , 0 , sizeof (out_buffer32 ));
380343
381344 for (int chan = 0 ; chan < CIRCUITPY_SYNTHIO_MAX_CHANNELS ; chan ++ ) {
382345 mp_obj_t note_obj = synth -> span .note_obj [chan ];
383- if (synth -> filter_buffer && synthio_synth_get_note_filtered (note_obj )) {
384- continue ;
346+ mp_obj_t filter_obj = synthio_synth_get_note_filter (note_obj );
347+ if (filter_obj == mp_const_none ) {
348+ synth_note_into_buffer (synth , chan , out_buffer32 , dur );
349+ } else {
350+ synthio_note_obj_t * note = MP_OBJ_TO_PTR (note_obj );
351+ int32_t filter_buffer32 [dur * synth -> channel_count ];
352+ memset (filter_buffer32 , 0 , sizeof (filter_buffer32 ));
353+
354+ synth_note_into_buffer (synth , chan , filter_buffer32 , dur );
355+ int synth_chan = synth -> channel_count ;
356+ for (int i = 0 ; i < synth_chan ; i ++ ) {
357+ synthio_biquad_filter_samples (& note -> filter_state , & out_buffer32 [i ], & filter_buffer32 [i ], dur , i );
358+ }
385359 }
386- synth_note_into_buffer (synth , chan , out_buffer32 , dur );
387360 }
388361
389362 int16_t * out_buffer16 = (int16_t * )(void * )synth -> buffers [synth -> buffer_index ];
0 commit comments