@@ -28,27 +28,15 @@ void common_hal_audiofilters_filter_construct(audiofilters_filter_obj_t *self,
28
28
self -> buffer_len = buffer_size ; // in bytes
29
29
30
30
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
- }
35
31
memset (self -> buffer [0 ], 0 , self -> buffer_len );
36
32
37
33
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
- }
42
34
memset (self -> buffer [1 ], 0 , self -> buffer_len );
43
35
44
36
self -> last_buf_idx = 1 ; // Which buffer to use first, toggle between 0 and 1
45
37
46
38
// This buffer will be used to process samples through the biquad filter
47
39
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
- }
52
40
memset (self -> filter_buffer , 0 , SYNTHIO_MAX_DUR * sizeof (int32_t ));
53
41
54
42
// Initialize other values most effects will need.
@@ -63,8 +51,7 @@ void common_hal_audiofilters_filter_construct(audiofilters_filter_obj_t *self,
63
51
if (filter == MP_OBJ_NULL ) {
64
52
filter = mp_const_none ;
65
53
}
66
- synthio_biquad_filter_assign (& self -> filter_state , filter );
67
- self -> filter_obj = filter ;
54
+ common_hal_audiofilters_filter_set_filter (self , filter );
68
55
69
56
// If we did not receive a BlockInput we need to create a default float value
70
57
if (mix == MP_OBJ_NULL ) {
@@ -87,15 +74,64 @@ void common_hal_audiofilters_filter_deinit(audiofilters_filter_obj_t *self) {
87
74
self -> buffer [0 ] = NULL ;
88
75
self -> buffer [1 ] = NULL ;
89
76
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
+ }
90
105
}
91
106
92
107
mp_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
+ }
94
113
}
95
114
96
115
void 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 );
99
135
}
100
136
101
137
mp_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,
126
162
memset (self -> buffer [1 ], 0 , self -> buffer_len );
127
163
memset (self -> filter_buffer , 0 , SYNTHIO_MAX_DUR * sizeof (int32_t ));
128
164
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
+ }
130
170
}
131
171
132
172
bool 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
265
305
int16_t * sample_src = (int16_t * )self -> sample_remaining_buffer ; // for 16-bit samples
266
306
int8_t * sample_hsrc = (int8_t * )self -> sample_remaining_buffer ; // for 8-bit samples
267
307
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
269
309
for (uint32_t i = 0 ; i < n ; i ++ ) {
270
310
if (MP_LIKELY (self -> bits_per_sample == 16 )) {
271
311
word_buffer [i ] = sample_src [i ];
@@ -292,8 +332,10 @@ audioio_get_buffer_result_t audiofilters_filter_get_buffer(audiofilters_filter_o
292
332
}
293
333
}
294
334
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
+ }
297
339
298
340
// Mix processed signal with original sample and transfer to output buffer
299
341
for (uint32_t j = 0 ; j < n_samples ; j ++ ) {
0 commit comments