Every DAC upsamples. It has to — reconstructing an analog waveform from 44,100 samples per second requires an interpolation filter. But a DAC chip does it in real time with a filter of a few hundred to a few thousand taps. AuraEngine removes the real-time constraint entirely: it renders the track offline through FIR filters of 1 to 30 million taps, designed in 128-bit arithmetic, applied in end-to-end 64-bit float. The DAC then receives a 352.8/384/705.6/768 kHz waveform that is already reconstructed — its own filter has almost nothing left to do.
The engine logs every decision — which filter file it resolved, how many
hybrid-phase switches it made, whether true-peak protection acted — and
re-decodes every output file to prove it matches the internal math within
±2 LSB. Files that fail are renamed _UNVERIFIED.
Every filter is normalized to exactly unity DC gain
(sum(h) == 1.0). The only two gain changes possible are the
headroom you choose and the −0.5 dBTP true-peak ceiling — both
documented, both visible in the log.
Invented for this project. Every FIR filter forces a trade: linear phase keeps the stereo image coherent but pre-rings before every attack; minimum phase hits clean but warps inter-channel timing. Fixed "intermediate-phase" compromise filters carry a little of both flaws, everywhere, all the time. AuraEngine refuses the trade — it renders the track twice in full and switches between the two renders per-transient.
One switch plan is computed from the mid signal and applied to both channels at the same sample. The channels can never de-phase against each other — the image stays put while the attacks stay clean.
Switches fire only at zero crossings, through a 32-sample raised-cosine micro-fade (~0.09 ms at 352.8 kHz), with a 20 ms anti-chatter hold. The two renders are aligned sample-exact via band-weighted group delay (200–6000 Hz) before blending. Verification: doc 06.
One file, start to finish. Stages marked optional are user toggles; everything else always runs. The entire CPU sample path is 64-bit float — there is no f32 truncation anywhere between decode and dither.
FLAC, WAV, MP3, OGG, AAC/M4A are decoded by the pure-Rust
Symphonia library. Integer PCM is extracted into i32 buffers —
not f32, whose 23-bit mantissa would silently destroy the 24th bit
of studio masters — then promoted losslessly to f64 (÷2³¹).
MP3/AAC encoder padding is trimmed using gapless metadata.
Why it matters: the chain starts bit-exact. A 24-bit FLAC enters the engine with all 24 bits intact.
Per-channel mean removal (default) or an optional 2 Hz
single-pole IIR high-pass with the exact closed-form pole
r = e^(−2π·2/fs).
Why it matters: a fraction of a millivolt of DC offset would make a 30M-tap filter ring at infrasonic frequencies and poison the true-peak measurement.
Optional pre-DSP attenuation: 0 / −0.5 / −1.0 / −3.0 dB, applied as a single linear gain before any convolution.
Why it matters: minimum-phase filtering concentrates energy in time. Giving the convolution stage headroom before it runs prevents intersample overshoot from ever needing correction later.
Masters carry the fingerprints of every filter that ever touched them. The v3 analyzer reads those fingerprints instead of guessing: a time-domain detector isolates the near-Nyquist band, finds the strongest attacks across the track and looks for high-frequency energy rising before them — the signature of a linear-phase brick wall — then measures the ring's exact frequency (per-burst FFT, median across attacks) and places a corrective minimum-phase Kaiser lowpass just below the measured edge, with depth chosen by severity (β=24 strong / β=14 mild). A Welch spectral-cliff detector unmasks fake hi-res — upsampled 44.1/48 kHz masters inside 88.2k+ containers are treated against their original Nyquist — and a mirror-image alias probe catches bad upstream resamplers whose spectral images defeat every other test. A cliff with no pre-ring means the source filter was minimum-phase or already apodized: diagnosed in the log, audio untouched. Static presets (Gentle 20 kHz / Moderate 19 kHz / Strong 18 kHz) are available too.
Why it matters: upsampling scales flaws along with music. Healing the source's pre-ring first gives the big FIR a clean canvas — and tracks that don't need it pass through untouched.
The engine has two resampling architectures, selected by the Polyphase FIR Resampling toggle. Both end at the same output stage.
SincFixedIn<f64> upsamples first: 512-tap sinc,
512× oversampling, cubic interpolation, ≈−180 dB stopband.h_k[m] = h[m·L+k]) that run at the source rate, in
parallel on all CPU cores.fc = src_rate / (2·out_rate).input × L — no resampler padding at
all. Non-integer targets snap down (44.1 kHz × FS8 → 352.8 kHz).Linear-phase filters preserve the stereo field but pre-ring before transients; minimum-phase filters hit hard but smear inter-channel phase. AuraEngine runs both convolutions in full, then a native-Rust HPSS (harmonic/percussive separation) onset detector builds a transient envelope: STFT with time/frequency median masks, 8-band spectral flux, adaptive gate, envelope follower with lookahead. During sustained material you hear the linear-phase branch; a split second before each detected attack the engine switches to the minimum-phase branch — at a zero crossing, with a ~0.08 ms raised-cosine micro-fade and a 20 ms anti-chatter hold.
Why it matters: the switch is stereo-linked — one switching plan computed from the mid signal, applied to both channels at the same sample. Channels never de-phase against each other, so the image stays rock solid while attacks stay clean. The minimum-phase branch is aligned using band-weighted group delay (200–6000 Hz) so both branches sit sample-exact at the perceptual core of the music.
4× oversampled intersample-peak scan using an 8-tap Lanczos-4 polyphase sinc interpolator (reflective edge padding, every sample inspected). If the reconstructed waveform would exceed −0.5 dBTP, one single linear gain brings the whole file under the ceiling. Quieter material is left bit-exact — no gain is applied at all.
Why it matters: loudness-war masters routinely hide +1…+3 dB intersample peaks. Without this stage they would clip in the DAC's reconstruction filter — as harshness on every loud passage.
24-bit TPDF dither with two independent random streams — one per channel, so the dither floor cannot correlate between L and R. At output rates ≤48 kHz a 9th-order Wannamaker psychoacoustic noise shaper pushes the quantization noise where hearing is least sensitive; at hi-res rates pure TPDF is used (the noise floor already sits far above audibility limits in frequency). Samples are clamped to ±(1−LSB) after quantization.
Why it matters: proper dither converts quantization distortion into benign noise — reverb tails and room decay stay intact instead of dissolving into correlated grit.
The f64 buffer is streamed to ffmpeg over a pipe and encoded
as 24-bit FLAC (-sample_fmt s32 -bits_per_raw_sample 24,
compression level 8). Cancelled or failed encodes delete the partial file.
The file just written is decoded back and compared
sample-by-sample against the DSP buffer, with a ±2 LSB tolerance at 24-bit.
Pass → ✓ VERIFIED badge. Fail → the file is
renamed _UNVERIFIED.flac and flagged in the UI.
Why it matters: this closes the loop. You don't have to trust the pipeline — the pipeline checks itself, on every single file.
Both paths share every preparation and output stage. The difference is who does the sample-rate conversion.
| Standard (default) | Polyphase FIR | |
|---|---|---|
| Resampler | Rubato 512-tap sinc, then FIR post-filter at output rate | The FIR itself, split into L sub-filters at source rate |
| Ratios | Any (44.1 → 384 kHz works directly) | Integer only; snaps down otherwise (44.1×FS8 → 352.8 kHz) |
| Output length | ~0.4 s trailing resampler pad | Exactly input × L, zero padding |
| Compute | One big convolution at output rate | L convolutions at source rate, parallel on all cores |
| Missing filter blob | Post-filter skipped, logged | Hard error — no silent downgrade |
The standard objection to GPU audio is that consumer GPUs compute in f32 — a ~−150 dB noise floor that a 30M-tap convolution would happily amplify. AuraEngine's answer is double-single (DS) arithmetic.
Every complex value on the GPU is a pair of f32s — a high word and an
error-correction low word — giving ≈48 effective mantissa bits. The catch:
DS math only works if the compiler doesn't "optimize" the correction terms
away. WGSL has no way to forbid that, so the compute shaders are written in
GLSL with the precise qualifier, compiled to SPIR-V with
NoContraction decorations (which Vulkan drivers are required to
honour), and loaded through wgpu's SPIRV_SHADER_PASSTHROUGH so no
shader translator can touch the operation tree.
Measured result: the GPU pipeline nulls against the f64 CPU reference at
≈−260 dB — about 110 dB below the 24-bit noise floor. A
dedicated preflight test (ds_preflight.rs) can prove on any given
driver that the two-sum survives compilation.
Adapters without SPIR-V passthrough (e.g. DX12-only) automatically fall back to the CPU convolver — the f64 reference implementation, always available.
| CPU convolver | GPU convolver | |
|---|---|---|
| Precision | f64 + Kahan-compensated MAC | DS f32 pairs (~48-bit mantissa) |
| Algorithm | Partitioned overlap-save, FFT 65536 | Partitioned OLA, radix-2 FFT in DS |
| Block size | 32768 samples | 256k–2M samples (scales with filter) |
| Latency (trimmed exactly) | 2 × block | 1 × block |
| Requirement | — | Vulkan + SPIRV_SHADER_PASSTHROUGH |
The converter deliberately cannot generate filters at runtime. Coefficients
come from fir-optimizer, a Python design suite that builds each
Kaiser-windowed (β=14) sinc prototype in 128-bit arithmetic
(mpmath, 38 significant digits), normalizes DC gain with
extended-precision summation, and ships the result as f64 .npy
blobs.
The matrix covers every conversion the app can perform: 4 tap sizes (1M/5M/10M/30M) × 8 output rates × 2 phase variants = 64 blobs (≈10 GB). Each is designed for its exact ratio — passband to source-Nyquist−2 kHz, stopband from source Nyquist — so the runtime never stretches a filter to a rate it wasn't designed for.
The minimum-phase variants are derived by cepstral folding with ≥16× zero-padded FFTs (no time-aliasing), tail-faded with a Hann window, and re-normalized to unity DC gain afterwards. Impulse peak lands at sample zero: mathematically zero pre-ringing.
The production 30M-tap blob measures: stopband ≤ −220.9 dB (manifesto requirement: −140 dB), passband ripple ±0.09 nano-dB, unity-gain error 1.1×10⁻¹⁵, transition width 0.05 Hz. Full plots, methodology and the reproduction script: docs/15-measurements.md. Every blob ships with a JSON metadata sidecar, and the runtime logs exactly which file it resolved for each conversion.
From DSP_MANIFESTO.md — the axioms every commit is audited against. Violating one degrades the device class; that is the review bar for this codebase.
No filter may change the track's loudness. sum(h) == 1.0, verified in unit tests for every filter mode.
User headroom is applied to PCM strictly before the convolution engine — never after.
The intersample scanner sits immediately before quantization, after every processing stage.
Cepstral minimum-phase conversion uses ≥16× zero-padded FFTs so computation tails never wrap around.
Minimum-phase impulses peak at sample [0] with mathematical zeros before it.
Kaiser β=14 or better. Measured: ≈−196 dB at 1M+ taps.
Any f32 truncation in the sample path is a blocker-class bug. GPU DS arithmetic exists to satisfy this law on f32 hardware.
Overlap-add/save partitioned convolution, block sizes tuned to cache and VRAM.
Every output FLAC is re-decoded and compared against the internal f64 buffer (±2 LSB at 24-bit). The UI shows ✓ VERIFIED only when the file on disk provably contains the math the log describes.
25 unit tests pin the invariants: convolver latency is exactly 2 blocks (CPU) / 1 block (GPU), unity gain through the OLA engine, bit-exact polyphase reconstruction, stereo-linked switching, true-peak and dither behaviour. CI runs them on every push.
AuraEngine keeps a console window open next to the UI on purpose. It
prints the full DSP trace: which .npy was resolved, ADC-ringing
analysis verdicts, hybrid-phase coverage statistics, true-peak decisions,
verification results. If you audit audio software for a living, start
there — then read the
auditor's guide.