Add Biquad Filters to audiodelays.Echo and audiofreeverb.Freeverb - #11196
Add Biquad Filters to audiodelays.Echo and audiofreeverb.Freeverb#11196relic-se wants to merge 4 commits into
audiodelays.Echo and audiofreeverb.Freeverb#11196Conversation
tannewt
left a comment
There was a problem hiding this comment.
A couple suggestions. Overall I'm excited for more synth improvements!
| } else if (MP_OBJ_TYPE_HAS_SLOT(mp_obj_get_type(filter_in), iter)) { | ||
| // convert object to tuple if it wasn't before | ||
| filter_in = MP_OBJ_TYPE_GET_SLOT(&mp_type_tuple, make_new)( | ||
| &mp_type_tuple, 1, 0, &filter_in); | ||
| mp_obj_tuple_get(filter_in, &n_items, &items); | ||
| for (size_t i = 0; i < n_items; i++) { | ||
| if (!mp_obj_is_type(items[i], &synthio_biquad_type_obj)) { | ||
| mp_raise_TypeError_varg( | ||
| MP_ERROR_TEXT("%q in %q must be of type %q, not %q"), | ||
| MP_QSTR_object, | ||
| MP_QSTR_filter, | ||
| MP_QSTR_Biquad, | ||
| mp_obj_get_type(items[i])->name); | ||
| } | ||
| } | ||
| *filter_objs = items; | ||
| } else { |
There was a problem hiding this comment.
I'd just be stricter here. The docs say it's a tuple or single Biquad. Don't support any sequence to save yourself the allocation.
There was a problem hiding this comment.
Do you mean to get rid of:
// convert object to tuple if it wasn't before
filter_in = MP_OBJ_TYPE_GET_SLOT(&mp_type_tuple, make_new)(
&mp_type_tuple, 1, 0, &filter_in);
mp_obj_tuple_get(filter_in, &n_items, &items);And replace it with a strict tuple type check? I could see some users providing a list without thinking about it which is why this code is here.
| } | ||
| } | ||
|
|
||
| int32_t audiofilters_process_filters(mp_obj_t *filter_objs, size_t filter_objs_len, biquad_filter_state *filter_states, uint8_t channel_count, uint8_t channel, int32_t word) { |
There was a problem hiding this comment.
I wonder if it's worth having a "filter chain" struct that holds the objs, len and states. That may make it easier to manage and clearer what can be shared.
There was a problem hiding this comment.
I totally thinking of this earlier. That'll definitely clear up those function calls.
This update expands the capabilities of
audiodelays.Echoandaudiofreeverb.Freeverbby addingsynthio.Biquadfilter support internally to their audio processing chain.Echo
The
audiodelays.Echo.filterproperty filters samples before they are stored in the echo buffer to be recalled later. This can produce a "tape-like" effect when repeated echos are processed through the filter on each iteration.Freeverb
The
audiofreeverb.Freeverb.pre_filterandaudiofreeverb.Freeverb.post_filterproperties allow the incoming sample to be filtered going into and out of the reverb algorithm. These new "Pre-EQ" and "Post-EQ" allow deeper control and shaping of the reverb effect while maintaining the integrity of the original sample.Demonstration
Results
This above program was recorded using Audacity over USB Audio under 4 conditions: dry echo, filtered echo, dry reverb, and filtered reverb. filter-tests.zip
All tests were run by a Waveshare RP2040 Zero. In some tests, audible popping can be heard. This is likely due to buffer underflows caused by the slower processor and the computational requirements of these effects or the experimental nature of
usb_audioin its current state.Notes
audiofreeverb.Freeverb. After using the effect under each circumstance, I determined that it would be useful to have both options. "Pre-EQ" does a good job of "taming" the reverb by reducing the effect of sudden pops which can cause the reverb to act abruptly. "Post-EQ" is more artistic in the way that it shapes the reverb output.audio-module/audiofilters/__init__.c). This has definitely helped simplify implementation and reduce flash usage, but there is likely room for improvement with performance. I'd appreciate direction on how best to share these methods.