@@ -28,27 +28,15 @@ void common_hal_audiofilters_filter_construct(audiofilters_filter_obj_t *self,
2828 self -> buffer_len = buffer_size ; // in bytes
2929
3030 self -> buffer [0 ] = m_malloc (self -> buffer_len );
31- if (self -> buffer [0 ] == NULL ) {
32- common_hal_audiofilters_filter_deinit (self );
33- m_malloc_fail (self -> buffer_len );
34- }
3531 memset (self -> buffer [0 ], 0 , self -> buffer_len );
3632
3733 self -> buffer [1 ] = m_malloc (self -> buffer_len );
38- if (self -> buffer [1 ] == NULL ) {
39- common_hal_audiofilters_filter_deinit (self );
40- m_malloc_fail (self -> buffer_len );
41- }
4234 memset (self -> buffer [1 ], 0 , self -> buffer_len );
4335
4436 self -> last_buf_idx = 1 ; // Which buffer to use first, toggle between 0 and 1
4537
4638 // This buffer will be used to process samples through the biquad filter
4739 self -> filter_buffer = m_malloc (SYNTHIO_MAX_DUR * sizeof (int32_t ));
48- if (self -> filter_buffer == NULL ) {
49- common_hal_audiofilters_filter_deinit (self );
50- m_malloc_fail (SYNTHIO_MAX_DUR * sizeof (int32_t ));
51- }
5240 memset (self -> filter_buffer , 0 , SYNTHIO_MAX_DUR * sizeof (int32_t ));
5341
5442 // Initialize other values most effects will need.
@@ -63,8 +51,7 @@ void common_hal_audiofilters_filter_construct(audiofilters_filter_obj_t *self,
6351 if (filter == MP_OBJ_NULL ) {
6452 filter = mp_const_none ;
6553 }
66- synthio_biquad_filter_assign (& self -> filter_state , filter );
67- self -> filter_obj = filter ;
54+ common_hal_audiofilters_filter_set_filter (self , filter );
6855
6956 // If we did not receive a BlockInput we need to create a default float value
7057 if (mix == MP_OBJ_NULL ) {
@@ -87,15 +74,64 @@ void common_hal_audiofilters_filter_deinit(audiofilters_filter_obj_t *self) {
8774 self -> buffer [0 ] = NULL ;
8875 self -> buffer [1 ] = NULL ;
8976 self -> filter_buffer = NULL ;
77+ self -> filter_states = NULL ;
78+ }
79+
80+ void reset_filter_states (audiofilters_filter_obj_t * self ) {
81+ self -> filter_states_len = 0 ;
82+ self -> filter_states = NULL ;
83+
84+ mp_obj_t * items ;
85+ if (mp_obj_is_type (self -> filter , (const mp_obj_type_t * )& synthio_biquad_type_obj )) {
86+ self -> filter_states_len = 1 ;
87+ items = self -> filter ;
88+ } else if (mp_obj_is_tuple_compatible (self -> filter )) {
89+ mp_obj_tuple_get (self -> filter , & self -> filter_states_len , & items );
90+ }
91+
92+ if (!self -> filter_states_len ) {
93+ return ;
94+ }
95+
96+ self -> filter_states = m_malloc (self -> filter_states_len * sizeof (biquad_filter_state ));
97+
98+ if (mp_obj_is_type (items , (const mp_obj_type_t * )& synthio_biquad_type_obj )) {
99+ synthio_biquad_filter_assign (& self -> filter_states [0 ], items );
100+ } else {
101+ for (size_t i = 0 ; i < self -> filter_states_len ; i ++ ) {
102+ synthio_biquad_filter_assign (& self -> filter_states [i ], items [i ]);
103+ }
104+ }
90105}
91106
92107mp_obj_t common_hal_audiofilters_filter_get_filter (audiofilters_filter_obj_t * self ) {
93- return self -> filter_obj ;
108+ if (mp_obj_is_type (self -> filter , (const mp_obj_type_t * )& synthio_biquad_type_obj ) || mp_obj_is_tuple_compatible (self -> filter )) {
109+ return self -> filter ;
110+ } else {
111+ return mp_const_none ;
112+ }
94113}
95114
96115void common_hal_audiofilters_filter_set_filter (audiofilters_filter_obj_t * self , mp_obj_t arg ) {
97- synthio_biquad_filter_assign (& self -> filter_state , arg );
98- self -> filter_obj = arg ;
116+ if (arg == mp_const_none || mp_obj_is_type (arg , (const mp_obj_type_t * )& synthio_biquad_type_obj )) {
117+ self -> filter = arg ;
118+ } else if (mp_obj_is_tuple_compatible (arg ) || mp_obj_is_type (arg , & mp_type_list )) {
119+ size_t tuple_len ;
120+ mp_obj_t * tuple_items = NULL ;
121+
122+ mp_obj_get_array (arg , & tuple_len , & tuple_items );
123+
124+ mp_obj_t * biquad_objects [tuple_len ];
125+ for (size_t i = 0 ; i < tuple_len ; i ++ ) {
126+ biquad_objects [i ] = mp_arg_validate_type_in (tuple_items [i ], (const mp_obj_type_t * )& synthio_biquad_type_obj , MP_QSTR_filter );
127+ }
128+
129+ self -> filter = mp_obj_new_tuple (tuple_len , (const mp_obj_t * )biquad_objects );
130+ } else {
131+ mp_raise_ValueError_varg (MP_ERROR_TEXT ("%q must be a %q object, %q, or %q" ), MP_QSTR_filter , MP_QSTR_Biquad , MP_QSTR_tuple , MP_QSTR_None );
132+ }
133+
134+ reset_filter_states (self );
99135}
100136
101137mp_obj_t common_hal_audiofilters_filter_get_mix (audiofilters_filter_obj_t * self ) {
@@ -126,7 +162,11 @@ void audiofilters_filter_reset_buffer(audiofilters_filter_obj_t *self,
126162 memset (self -> buffer [1 ], 0 , self -> buffer_len );
127163 memset (self -> filter_buffer , 0 , SYNTHIO_MAX_DUR * sizeof (int32_t ));
128164
129- synthio_biquad_filter_reset (& self -> filter_state );
165+ if (self -> filter_states ) {
166+ for (uint8_t i = 0 ; i < self -> filter_states_len ; i ++ ) {
167+ synthio_biquad_filter_reset (& self -> filter_states [i ]);
168+ }
169+ }
130170}
131171
132172bool common_hal_audiofilters_filter_get_playing (audiofilters_filter_obj_t * self ) {
@@ -265,7 +305,7 @@ audioio_get_buffer_result_t audiofilters_filter_get_buffer(audiofilters_filter_o
265305 int16_t * sample_src = (int16_t * )self -> sample_remaining_buffer ; // for 16-bit samples
266306 int8_t * sample_hsrc = (int8_t * )self -> sample_remaining_buffer ; // for 8-bit samples
267307
268- if (mix <= 0.01 || self -> filter_obj == mp_const_none ) { // if mix is zero pure sample only or no biquad filter object is provided
308+ if (mix <= 0.01 || ! self -> filter_states ) { // if mix is zero pure sample only or no biquad filter objects are provided
269309 for (uint32_t i = 0 ; i < n ; i ++ ) {
270310 if (MP_LIKELY (self -> bits_per_sample == 16 )) {
271311 word_buffer [i ] = sample_src [i ];
@@ -292,8 +332,10 @@ audioio_get_buffer_result_t audiofilters_filter_get_buffer(audiofilters_filter_o
292332 }
293333 }
294334
295- // Process biquad filter
296- synthio_biquad_filter_samples (& self -> filter_state , self -> filter_buffer , n_samples );
335+ // Process biquad filters
336+ for (uint8_t j = 0 ; j < self -> filter_states_len ; j ++ ) {
337+ synthio_biquad_filter_samples (& self -> filter_states [j ], self -> filter_buffer , n_samples );
338+ }
297339
298340 // Mix processed signal with original sample and transfer to output buffer
299341 for (uint32_t j = 0 ; j < n_samples ; j ++ ) {
0 commit comments