Denormals: rely on NIH-plug's FTZ, drop redundant in-code flush

Investigated the planned global FTZ for the IIR filters and found NIH-plug already
handles it: process_wrapper wraps process()/reset() in a ScopedFtz guard that
enables CPU Flush-To-Zero (x86 MXCSR bit 15 / AArch64 FPCR bit 24, via inline asm,
restored on drop) on the vst3, clap, and standalone paths. SSE is baseline on
x86_64 so FTZ is always active for our build.

So adding our own guard would just duplicate the framework. Instead, removed the
now-redundant flush_denormal() from compressor.rs (the biquads and envelope/RMS
tails already relied on this FTZ) for a single consistent story, and rewrote the
README 'Denormal flushing' note to document that the framework handles it (FTZ,
not DAZ — sufficient for our feed-forward IIR).

No functional change; 10 unit tests still pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Mikkeli Matlock
2026-06-18 01:34:56 +09:00
parent 1d939535be
commit d776e564fd
2 changed files with 13 additions and 22 deletions
+7 -5
View File
@@ -221,11 +221,13 @@ must be pre-allocated in `initialize()`. Use `assert_process_allocs` feature fla
development to catch violations.
### Denormal flushing
The compressor flushes its envelope/RMS state to zero in code once it decays below audibility
(`flush_denormal` in `compressor.rs`). The hardware `_MM_SET_FLUSH_ZERO_MODE` intrinsic is now
deprecated and the matching DAZ helper isn't exposed by `std::arch`, so a global hardware FTZ/DAZ
(via inline asm on the audio thread) is deferred until the IIR crossover/limiter filters land,
where it matters more.
Handled by the framework — no plugin code needed. NIH-plug wraps `process()` and `reset()` in
`process_wrapper`, which enables the CPU's **Flush-To-Zero** mode for the duration via its
`ScopedFtz` guard (x86 `MXCSR` bit 15 / AArch64 `FPCR` bit 24, set with inline asm and restored
on drop). FTZ has a fixed threshold at the normal/subnormal boundary (~759 dB for f32), so the
decaying envelope/RMS tails and all the IIR filter state are flushed to zero automatically,
far below audibility. We therefore do **not** set the register ourselves or flush values in code.
(Note: NIH-plug sets FTZ but not DAZ; for our feed-forward IIR work FTZ on results is sufficient.)
### Parameter smoothing
NIH-plug provides `Smoother` — use it for all gain/threshold params to avoid zipper noise.