AuraEngine
What actually happens to your audio — every stage, every parameter, and why.
FIR [KAISER] 64-BIT · 30.0M TAPS · FS8 (352.8K/384K) · FLAC 24-BIT · VERIFIED
An offline upsampler is only worth trusting if its signal path is fully documented.
This page is that documentation. Source: github.com/ToxaDev/aura-engine

00Why offline, why million-tap

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.

A real batch conversion, 4× speed — Hybrid-Phase + Adaptive Apodizer + GPU, every file verified.

Nothing is hidden

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.

Nothing is louder or quieter

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.

01The signature: Hybrid-Phase

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.

Slow motion ×20 — the HPSS detector sees the hit coming, the engine switches at a zero crossing, the attack lands with no pre-ringing while the sustain keeps linear-phase imaging.

Stereo-linked by construction

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.

Engineered to be inaudible

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.

02The signal path

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.

1
Decode converter/decode.rs · Symphonia

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.

lossless i32 → f64gapless trimno ffmpeg on input
2
DC block pipeline/prepare.rs

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.

static meanor 2 Hz IIR HPF
3
Headroom pipeline/prepare.rs

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.

pre-DSP by design
4
Adaptive Apodizer v3 — source forensics converter/apodize.rs optional · any source rate

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.

AA tagmeasured ring cutofffake-hi-res unmaskingmirror-alias probemin-phase · zero pre-ring
5
Upsampling — two paths converter/process.rs

The engine has two resampling architectures, selected by the Polyphase FIR Resampling toggle. Both end at the same output stage.

Standard path any ratio · Rubato + FIR post-filter
  • Rubato SincFixedIn<f64> upsamples first: 512-tap sinc, 512× oversampling, cubic interpolation, ≈−180 dB stopband.
  • The million-tap FIR then runs at the output rate as a spectral-shaping post-filter — partitioned overlap-save, block 32768, Kahan-compensated frequency-domain MAC, parallelized with Rayon.
  • Filter blob missing? The post-filter is skipped with a logged warning — Rubato alone is still a first-class resampler.
Polyphase FIR path integer ratios · the filter IS the resampler
  • The same million-tap filter is decomposed into L sub-filters (h_k[m] = h[m·L+k]) that run at the source rate, in parallel on all CPU cores.
  • Anti-imaging cutoff sits exactly at source Nyquist: fc = src_rate / (2·out_rate).
  • Output length is exactly input × L — no resampler padding at all. Non-integer targets snap down (44.1 kHz × FS8 → 352.8 kHz).
  • Filter blob missing? Hard error — this path refuses to degrade silently.
6
Hybrid-Phase engine hybrid_phase.rs · hpss_native.rs · pipeline/hybrid_mixer.rs optional · ~2× time

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.

HP tagstereo-linked switchzero-crossing + micro-fadeHPSS onset envelope
7
True-peak limiter converter/dsp/true_peak.rs

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.

ITU-R BS.1770-style−0.5 dBTP ceilingbit-exact when quiet
8
Dither & noise shaping converter/dsp/dither.rs

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.

TPDF 24-bitper-channel RNGWannamaker-9 ≤48 kHz
9
FLAC encode converter/encode.rs · ffmpeg

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.

24-bit FLACoutput next to source
Bit-perfect verification converter/utils/verify.rs

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.

every file, every time±2 LSB

03Choosing a path

Both paths share every preparation and output stage. The difference is who does the sample-rate conversion.

Standard (default)Polyphase FIR
ResamplerRubato 512-tap sinc, then FIR post-filter at output rateThe FIR itself, split into L sub-filters at source rate
RatiosAny (44.1 → 384 kHz works directly)Integer only; snaps down otherwise (44.1×FS8 → 352.8 kHz)
Output length~0.4 s trailing resampler padExactly input × L, zero padding
ComputeOne big convolution at output rateL convolutions at source rate, parallel on all cores
Missing filter blobPost-filter skipped, loggedHard error — no silent downgrade

04GPU acceleration without precision loss

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.

Double-single, enforced at the SPIR-V level

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 convolverGPU convolver
Precisionf64 + Kahan-compensated MACDS f32 pairs (~48-bit mantissa)
AlgorithmPartitioned overlap-save, FFT 65536Partitioned OLA, radix-2 FFT in DS
Block size32768 samples256k–2M samples (scales with filter)
Latency (trimmed exactly)2 × block1 × block
RequirementVulkan + SPIRV_SHADER_PASSTHROUGH

05Filter design: 128-bit offline, f64 at runtime

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.

A filter per ratio — never rescaled

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.

Minimum-phase, done right

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.

Measured, not promised

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.

06The laws of the DSP core

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.

§1.1

Unity DC gain

No filter may change the track's loudness. sum(h) == 1.0, verified in unit tests for every filter mode.

§1.2

Headroom before convolution

User headroom is applied to PCM strictly before the convolution engine — never after.

§1.3

True-peak at the very end

The intersample scanner sits immediately before quantization, after every processing stage.

§2.1

No time-aliasing

Cepstral minimum-phase conversion uses ≥16× zero-padded FFTs so computation tails never wrap around.

§3.1

Zero pre-ringing

Minimum-phase impulses peak at sample [0] with mathematical zeros before it.

§3.2

Stopband ≥ −140 dB, no ripple

Kaiser β=14 or better. Measured: ≈−196 dB at 1M+ taps.

§4.1

f64 end to end

Any f32 truncation in the sample path is a blocker-class bug. GPU DS arithmetic exists to satisfy this law on f32 hardware.

§4.2

FFT convolution only

Overlap-add/save partitioned convolution, block sizes tuned to cache and VRAM.

07Verification & the audit trail

Per-file proof

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.

Per-build proof

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.

The console is the product

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.