Audio Null Test
Subtract two files and see exactly what the processor changed
- audio_ref
- audio_proc_aligned_matched
- audio_null
- metrics
The null test is the most honest tool in audio, and it's absurdly simple: take your reference, invert the processed version, add them together, and whatever's left is exactly what the processor changed. If the result is silence, the processor was transparent. If it's a noise floor, that's your added noise. If it's a mess of signal, the processor is doing more than you thought. This node is the subtraction-and-measure step of the Egregora null-test suite.
Crucially, it expects its second input to be already aligned and gain-matched - that's why the input is named audio_proc_aligned_matched. Feed it raw, misaligned audio and the null result will be dominated by timing and level errors rather than actual processor changes. The suite's Full node does all three stages for you; this node is the measurement stage in isolation, which is exactly what you want when you're iterating on settings and already have alignment solved.
How it works
The node subtracts the (inverted) processed audio from the reference - invert_b defaults on, meaning "A minus B" - and then computes whatever metrics you've enabled. The interesting bit is the metric selection, because each one tells you something different:
corr_coef- waveform correlation. 1.0 is perfect transparency.null_rms_dbfs- how much residual energy the subtraction left, in dB. Lower is more transparent.null_lufs- the same residual measured as loudness, which is a more perceptual view.lsd_mean_db/lsd_p95_db- spectral distance of the residual; catches frequency-shaped differences.hf_residual_db- energy in a high band (default 8 kHz and up) of the null. This is the one that catches "the processor shaved off the top end," a change that's easy to miss in a full-band number.
There's also a least_squares_scale option that fits a best-scale factor before subtracting - useful if your gain matching was imperfect and you want the null to reflect only the non-linear changes.
The inputs that matter
audio_ref- the original.audio_proc_aligned_matched- processed, aligned, and gain-matched audio.invert_b(default on) - leave it, unless you've already inverted the signal yourself.compute_*toggles - keepcompute_null_rmsandcompute_lsdon; enablecompute_hf_residualif you suspect top-end damage.n_fft/hop- STFT settings for the LSD calculation (defaults 2048/512 are fine).
Outputs: audio_null (the residual - you can listen to it!) and a metrics DICT.
The take
Listening to the audio_null output is the pro move: a transparent processor should sound like near-silence or faint room tone, while a lossy codec sounds like the codec's characteristic shimmer. It's the difference between reading a number and hearing exactly what your chain did. No extra install beyond the pack - pure NumPy. Use it as the final verdict on any FlashSR, Fat Llama, or codec experiment.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| audio_ref | AUDIO | — | |
| audio_proc_aligned_matched | AUDIO | — | |
| invert_bopt | BOOLEAN | true | — |
| least_squares_scaleopt | BOOLEAN | false | — |
| compute_corropt | BOOLEAN | true | — |
| compute_null_rmsopt | BOOLEAN | true | — |
| compute_null_lufsopt | BOOLEAN | true | — |
| compute_lsdopt | BOOLEAN | true | — |
| compute_hf_residualopt | BOOLEAN | false | — |
| n_fftopt | INT | 2048512–8192 | — |
| hopopt | INT | 51264–4096 | — |
| hf_band_hzopt | INT | 80001000–20000 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| audio_null | AUDIO | — |
| metrics | DICT | — |