Expand description
Normalize arbitrary device frames (any sample rate/channel count, interleaved f32) in two stages, then convert them back to the requested output format.
Input (any sample rate/channel count)
│ Stage 1 (internal normalization; fixed)
│ - Channel mix (→stereo)
│ - Sample-rate conversion (rubato, →48000)
▼
Internal canonical form: f32 / 48000 Hz / stereo / 20ms = 960 frames
│ Stage 2 (output; per tap)
│ - Channel conversion (stereo→mono average / mono→stereo duplicate / unchanged)
│ - Sample-rate conversion (rubato, 48000→output.sample_rate; passthrough if equal)
▼
Output: f32 / output.sample_rate / output.channels / fixed 20ms duration
(48k=960 / 16k=320 / 8k=160 frames)With the default output {48000, 2}, stage 2 is entirely passthrough (the internal
canonical form is emitted as-is). Stage 1 sample-rate conversion is bypassed when
in_sample_rate == 48000; stage 2 conversion is bypassed when output.sample_rate == 48000.
Both rubato resamplers use FixedAsync::Input (fixed input chunks). Variable-length output
is collected in an internal accumulator and split at 20ms boundaries. The resampler and
accumulator carry any remainder forward.
PTS is assigned by tracking the input-to-output sample-offset ratio from device_pts
corresponding to the first sample of each output chunk. The stream layer assigns seq.
Structs§
- Normalizer
- Stateful two-stage converter that normalizes input device frames to the internal canonical form (48k/stereo/960 frames), then converts them to one or more output taps (primary and optional secondary).
Constants§
- CHUNK_
FRAMES - Frames per internal canonical-form chunk (20ms @ 48kHz). Stage 1 split boundary.
Traits§
- Inner
Processor - A processor applied to the internal normalized form (48kHz / stereo / interleaved f32) before it is split into the output taps.