Expand description
DSP foundation for the mic chain: a float audio bus, a stage contract, and a metered chain runner.
The original mic chain passed Vec<i16> from stage to stage — every hop
re-quantized (adding noise floor) and every boundary was a hidden clip
point. This module is the engineer’s version: samples are converted to
f32 once on entry, every stage processes in float with headroom,
and one saturating conversion happens at the exit — where clipping is
counted, not silent.
// `ignore`: the resampler/STFT stages need the `dsp` feature and the
// denoiser the `denoise` feature; `live` is a `Live` builder.
let chain = DspChain::new(16_000)
.stage(HighPass::speech_default(16_000)) // DC / rumble removal
.stage(IntStage::new(Denoiser::new(16_000))) // legacy i16 stage, one boundary
.stage(Agc::default_speech())
.stage(Limiter::default_ceiling());
let metrics = chain.metrics(); // live per-stage meters
live.mic_processor(chain); // drop into the existing seam§Design rules
- Allocation-free steady state: scratch buffers are owned by the chain and stages; the hot path only does arithmetic. (A stage may resize its output — resamplers legitimately change length — but must not allocate per call once warmed.)
- Uniform measurement: the chain, not the stages, meters peak/RMS in and out of every stage plus exit clipping, so every stage is observed identically and stages stay pure.
- Latency is declared: every stage reports its group delay via
DspStage::latency_samples;DspChain::total_latency_samplessums the chain’s causal budget so turn-commit timestamps can cite it.
§Canonical stage order
HPF → AEC → denoise → AGC → gate → limiter — each stage assumes what
the previous one guarantees: echo cancellation needs the linear signal
(before the nonlinear denoiser breaks the echo-path model), gain control
wants denoised speech so it does not amplify noise, and the limiter is
last so nothing after it can clip.
Re-exports§
pub use aec::Aec;pub use aec::AecConfig;pub use aec::AecFarEnd;pub use resample::SincResampler;pub use stages::Agc;pub use stages::HighPass;pub use stages::Limiter;pub use stft::Identity;pub use stft::SpectralFloor;pub use stft::SpectralStage;pub use stft::Stft;
Modules§
- aec
- Acoustic echo cancellation: subtract the bot’s own voice from the mic before anything else touches it.
- resample
- Windowed-sinc resampling as a chain stage (feature
dsp). - stages
- Time-domain stage library: high-pass, AGC, and limiter.
- stft
- STFT engine with WOLA (weighted overlap-add) processing.
Structs§
- Audio
Bus - One block of audio moving through the chain:
f32samples in[-1.0, 1.0]nominal range (headroom above is legal between stages) plus the sample rate a stage may change (resamplers). - Chain
Metrics - Shared metrics handle — clone freely; reading never blocks the chain.
- Chain
Snapshot - Point-in-time view of the whole chain.
- DspChain
- The metered float chain. Build with
stage, hand to the existingmic_processor(..)seam — it implementsInputAudioProcessor. - IntStage
- Wrap a legacy integer-domain
InputAudioProcessor(e.g. the RNNoiseDenoiserorNoiseGate) as aDspStage. This is the one deliberate int boundary in a float chain — the cost of reusing a proven stage unchanged. - Stage
Snapshot - Point-in-time view of one stage’s meters.
Traits§
- DspStage
- A single processing stage on the float bus.