Add an Oberheim-SEM morph law to the SVF filter: HP->notch->LP alongside HP->BP->LP, selected at prepare() time, free on the per-sample path

This commit is contained in:
2026-07-30 10:22:49 -04:00
parent f12700c997
commit d2364eb5ac
10 changed files with 971 additions and 483 deletions
+25 -5
View File
@@ -995,7 +995,8 @@ target_link_libraries(curve_popup PUBLIC editor_geometry)
add_library(master_gain STATIC src/core/instrument/engine/master_gain.cpp)
target_include_directories(master_gain PUBLIC src)
# filter — the per-voice TPT/SVF with a continuous HP->BP->LP morph and an in-loop drive stage.
# filter — the per-voice TPT/SVF with a continuous morph (HP->BP->LP or HP->notch->LP, selected
# at prepare() time) and an in-loop drive stage.
# The Cortex-M4 source's virtual FilterBase/Filter/Biquad hierarchy dispatched per channel per
# sample, which the per-voice per-sample path forbids, so none of it came across. Control
# mapping, SVF coefficients, morph weights, and the filter type each get their own file;
@@ -1108,10 +1109,29 @@ add_executable(master_gain_tests tests/test_master_gain.cpp)
target_link_libraries(master_gain_tests PRIVATE master_gain)
add_test(NAME master_gain_tests COMMAND master_gain_tests)
# filter: the per-voice resonant filter. Pins the SVF coefficients against an independent
# derivation, asserts the cutoff/Q control mappings at their anchors, holds the morph endpoints
# to the analytic 2-pole targets, and measures rate/level invariance and drive stability by
# driving real sines. NEITHER SDK.
# filter: four targets along the module's own seams, so each asserts one domain.
# filter_params_tests the rate-free control mappings (cutoff/Q/drive) and their inverses.
# filter_morph_tests — the pure morph-weight algebra under both morph laws; no DSP is run.
# filter_state_tests — numerical stability, the denormal flush, and the state lifecycle.
# filter_tests — the frequency response: pins the SVF coefficients against an independent
# derivation, holds the morph endpoints to the analytic 2-pole targets, and measures the
# HP-BP-LP corner flatness, the HP-notch-LP null, and rate/level invariance and drive
# stability by driving real sines. The seams above were chosen so this file alone owns the
# analytic reference and the steady-state gain measurement — a forked copy of a measurement
# reference is a worse defect than a long file, which is why it sits over the ~600-line bar.
# NEITHER SDK.
add_executable(filter_params_tests tests/test_filter_params.cpp)
target_link_libraries(filter_params_tests PRIVATE filter)
add_test(NAME filter_params_tests COMMAND filter_params_tests)
add_executable(filter_morph_tests tests/test_filter_morph.cpp)
target_link_libraries(filter_morph_tests PRIVATE filter)
add_test(NAME filter_morph_tests COMMAND filter_morph_tests)
add_executable(filter_state_tests tests/test_filter_state.cpp)
target_link_libraries(filter_state_tests PRIVATE filter)
add_test(NAME filter_state_tests COMMAND filter_state_tests)
add_executable(filter_tests tests/test_filter.cpp)
target_link_libraries(filter_tests PRIVATE filter)
add_test(NAME filter_tests COMMAND filter_tests)