feat: adjustable filter slopes (12/24/48 dB/oct)#33
Merged
Conversation
Shelves + HP/LP bands gain a selectable slope. 12 dB/oct is the original single biquad (bit-exact regression); 24/48 dB/oct cascade Butterworth sections using the exact per-section pole-Q tables, keeping the -3 dB point at Fc and splitting shelf gain across sections. Peaking/Notch/BandPass/ AllPass are single-biquad and ignore the slope. - ApoFilter keeps its head biquad + an 'extra' section cascade (empty at 12 dB/oct, so the common path is byte-identical). New builder .slope_db_oct + ApoFilter::set_slope. - Wired through IPC (BandState.slope_db_oct + Command::SetBandSlope), the daemon (AudioCommand::SetBandSlope, handler, snapshot, Profile toml persistence) and the Windows APO FilterSnapshot. - Tests: 12 dB bit-exact vs single biquad; LP/HP rejection ~12/24/48 dB one octave past Fc; -3 dB at Fc for all orders; shelf reaches full gain; slope ignored for peaking.
add BandType::uses_slope() (true for shelves + HP/LP) and next_slope_db_oct() (12->24->48->12) so the front-ends gate and cycle the per-band filter slope consistently.
add `resonance band-slope <index> <12|24|48>` -> SetBandSlope (1-based index, value validated). status now prints the slope for shelf/HP/LP bands (e.g. `24 dB/oct`); single-biquad types omit it.
add a 12/24/48 db/oct slope dropdown in the bands table next to the type badge. shown only for shelf/hp/lp bands (single-biquad types get a dim placeholder); sends SetBandSlope on change. new Slope column collapses one width tier before the Type combo.
add `S` to cycle the selected band's filter slope 12->24->48 (shelf/ hp/lp only; single-biquad types get a status hint). the Type column now shows the slope for those bands (e.g. `LS 24`); help overlay + footer document the key.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adjustable filter slopes (12/24/48 dB/oct)
Shelf + high/low-pass bands gain a selectable slope (roadmap "Adjustable filter slopes"). Peaking/Notch/BandPass/AllPass stay single-biquad and ignore it.
DSP
ApoFilterkeeps its head biquad + anextra: Vec<BiquadFilter>cascade (empty at 12 dB/oct, so the common path is byte-identical to before). 24/48 dB/oct cascade Butterworth sections using the exact per-section pole-Q tables — the −3 dB point stays exactly at Fc, and shelves split their gain across sections so the pass-band gain is unchanged. New.slope_db_oct()builder +ApoFilter::set_slope.Reach
BandState.slope_db_oct+Command::SetBandSlope+BandType::uses_slope()+next_slope_db_oct().AudioCommand::SetBandSlope, handler, snapshot, Profile toml persistence.FilterSnapshot.slope_db_oct.band-slope <index> <12|24|48>+ slope instatus; GUI per-band Slope dropdown (gated to shelf/HP/LP); TUISkey cycles slope + Type column shows it.Tests
12 dB bit-exact vs the single biquad (regression); LP/HP rejection ≈ −12/−24/−48 dB one octave past Fc; −3 dB at Fc for all orders; shelf reaches full gain; slope ignored for peaking. Native profile round-trips the slope through TOML; APO
.txthas no portable slope token (documented — native-profile only).Verification (all three surfaces)
make check(fmt + clippy-D warnings+test --all) EXIT=0. Live daemon smoke on real PipeWire: loaded a 3-band APO,band-slope 1 24→ shelf shows "24 dB/oct",band-slope 2 48→ "48 dB/oct", peaking band shows no slope (gated).cargo test --all+cargo clippy --all-targetsclean.resonance-apoFFI harness passes single-threaded (22/22, as designed).12 dB/oct is the default, so existing presets/profiles are unchanged.