|
5 | 5 | // SPDX-License-Identifier: MIT |
6 | 6 | #include "shared-bindings/audiofilters/Filter.h" |
7 | 7 |
|
| 8 | +#include "shared-module/synthio/BlockBiquad.h" |
8 | 9 | #include <stdint.h> |
9 | 10 | #include "py/runtime.h" |
10 | 11 |
|
@@ -66,65 +67,62 @@ void common_hal_audiofilters_filter_deinit(audiofilters_filter_obj_t *self) { |
66 | 67 | } |
67 | 68 | self->buffer[0] = NULL; |
68 | 69 | self->buffer[1] = NULL; |
| 70 | + self->filter = mp_const_none; |
69 | 71 | self->filter_buffer = NULL; |
70 | 72 | self->filter_states = NULL; |
71 | 73 | } |
72 | 74 |
|
73 | | -void reset_filter_states(audiofilters_filter_obj_t *self) { |
74 | | - self->filter_states_len = 0; |
75 | | - self->filter_states = NULL; |
76 | | - |
| 75 | +void common_hal_audiofilters_filter_set_filter(audiofilters_filter_obj_t *self, mp_obj_t filter_in) { |
| 76 | + size_t n_items; |
77 | 77 | mp_obj_t *items; |
78 | | - if (mp_obj_is_type(self->filter, (const mp_obj_type_t *)&synthio_biquad_type_obj)) { |
79 | | - self->filter_states_len = 1; |
80 | | - items = self->filter; |
81 | | - } else if (mp_obj_is_tuple_compatible(self->filter)) { |
82 | | - mp_obj_tuple_get(self->filter, &self->filter_states_len, &items); |
83 | | - } |
84 | | - |
85 | | - if (!self->filter_states_len) { |
86 | | - return; |
87 | | - } |
88 | | - |
89 | | - self->filter_states = m_malloc(self->filter_states_len * sizeof(biquad_filter_state)); |
90 | | - |
91 | | - if (mp_obj_is_type(items, (const mp_obj_type_t *)&synthio_biquad_type_obj)) { |
92 | | - synthio_biquad_filter_assign(&self->filter_states[0], items); |
93 | | - } else { |
94 | | - for (size_t i = 0; i < self->filter_states_len; i++) { |
95 | | - synthio_biquad_filter_assign(&self->filter_states[i], items[i]); |
| 78 | + mp_obj_t *filter_objs; |
| 79 | + |
| 80 | + if (filter_in == mp_const_none) { |
| 81 | + n_items = 0; |
| 82 | + filter_objs = NULL; |
| 83 | + } else if (MP_OBJ_TYPE_HAS_SLOT(mp_obj_get_type(filter_in), iter)) { |
| 84 | + // convert object to tuple if it wasn't before |
| 85 | + filter_in = MP_OBJ_TYPE_GET_SLOT(&mp_type_tuple, make_new)( |
| 86 | + &mp_type_tuple, 1, 0, &filter_in); |
| 87 | + mp_obj_tuple_get(filter_in, &n_items, &items); |
| 88 | + for (size_t i = 0; i < n_items; i++) { |
| 89 | + if (!synthio_is_any_biquad(items[i])) { |
| 90 | + mp_raise_TypeError_varg( |
| 91 | + MP_ERROR_TEXT("%q in %q must be of type %q, not %q"), |
| 92 | + MP_QSTR_object, |
| 93 | + MP_QSTR_filter, |
| 94 | + MP_QSTR_AnyBiquad, |
| 95 | + mp_obj_get_type(items[i])->name); |
| 96 | + } |
96 | 97 | } |
97 | | - } |
98 | | -} |
99 | | - |
100 | | -mp_obj_t common_hal_audiofilters_filter_get_filter(audiofilters_filter_obj_t *self) { |
101 | | - if (mp_obj_is_type(self->filter, (const mp_obj_type_t *)&synthio_biquad_type_obj) || mp_obj_is_tuple_compatible(self->filter)) { |
102 | | - return self->filter; |
| 98 | + filter_objs = items; |
103 | 99 | } else { |
104 | | - return mp_const_none; |
| 100 | + n_items = 1; |
| 101 | + if (!synthio_is_any_biquad(filter_in)) { |
| 102 | + mp_raise_TypeError_varg( |
| 103 | + MP_ERROR_TEXT("%q must be of type %q or %q, not %q"), |
| 104 | + MP_QSTR_filter, MP_QSTR_AnyBiquad, MP_QSTR_iterable, mp_obj_get_type(filter_in)->name); |
| 105 | + } |
| 106 | + filter_objs = &self->filter; |
105 | 107 | } |
106 | | -} |
107 | | - |
108 | | -void common_hal_audiofilters_filter_set_filter(audiofilters_filter_obj_t *self, mp_obj_t arg) { |
109 | | - if (arg == mp_const_none || mp_obj_is_type(arg, (const mp_obj_type_t *)&synthio_biquad_type_obj)) { |
110 | | - self->filter = arg; |
111 | | - } else if (mp_obj_is_tuple_compatible(arg) || mp_obj_is_type(arg, &mp_type_list)) { |
112 | | - size_t tuple_len; |
113 | | - mp_obj_t *tuple_items = NULL; |
114 | 108 |
|
115 | | - mp_obj_get_array(arg, &tuple_len, &tuple_items); |
| 109 | + // everything has been checked, so we can do the following without fear |
116 | 110 |
|
117 | | - mp_obj_t *biquad_objects[tuple_len]; |
118 | | - for (size_t i = 0; i < tuple_len; i++) { |
119 | | - biquad_objects[i] = mp_arg_validate_type_in(tuple_items[i], (const mp_obj_type_t *)&synthio_biquad_type_obj, MP_QSTR_filter); |
120 | | - } |
| 111 | + self->filter = filter_in; |
| 112 | + self->filter_objs = filter_objs; |
| 113 | + self->filter_states = m_renew(biquad_filter_state, |
| 114 | + self->filter_states, |
| 115 | + self->filter_states_len, |
| 116 | + n_items); |
| 117 | + self->filter_states_len = n_items; |
121 | 118 |
|
122 | | - self->filter = mp_obj_new_tuple(tuple_len, (const mp_obj_t *)biquad_objects); |
123 | | - } else { |
124 | | - 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); |
| 119 | + for (size_t i = 0; i < n_items; i++) { |
| 120 | + synthio_biquad_filter_assign(&self->filter_states[i], items[i]); |
125 | 121 | } |
| 122 | +} |
126 | 123 |
|
127 | | - reset_filter_states(self); |
| 124 | +mp_obj_t common_hal_audiofilters_filter_get_filter(audiofilters_filter_obj_t *self) { |
| 125 | + return self->filter; |
128 | 126 | } |
129 | 127 |
|
130 | 128 | mp_obj_t common_hal_audiofilters_filter_get_mix(audiofilters_filter_obj_t *self) { |
@@ -243,6 +241,8 @@ audioio_get_buffer_result_t audiofilters_filter_get_buffer(audiofilters_filter_o |
243 | 241 | channel = 0; |
244 | 242 | } |
245 | 243 |
|
| 244 | + shared_bindings_synthio_lfo_tick(self->sample_rate); |
| 245 | + |
246 | 246 | // get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required |
247 | 247 | mp_float_t mix = MIN(1.0, MAX(synthio_block_slot_get(&self->mix), 0.0)); |
248 | 248 |
|
@@ -327,6 +327,10 @@ audioio_get_buffer_result_t audiofilters_filter_get_buffer(audiofilters_filter_o |
327 | 327 |
|
328 | 328 | // Process biquad filters |
329 | 329 | for (uint8_t j = 0; j < self->filter_states_len; j++) { |
| 330 | + mp_obj_t filter_obj = self->filter_objs[j]; |
| 331 | + if (mp_obj_is_type(filter_obj, &synthio_block_biquad_type_obj)) { |
| 332 | + common_hal_synthio_block_biquad_tick(filter_obj, &self->filter_states[j]); |
| 333 | + } |
330 | 334 | synthio_biquad_filter_samples(&self->filter_states[j], self->filter_buffer, n_samples); |
331 | 335 | } |
332 | 336 |
|
|
0 commit comments