Nodes/Audio Quality Check/Audio Standards Fixer
ComfyUI Node

Audio Standards Fixer

Get your AI voice to streaming loudness in the graph, not in Audacity

By Khip01·Created about a month ago·Updated 25 days ago· 1
Audio Standards Fixer
  • audio
  • audio
  • report
  • is_fixed
◄target_lufs-14.0►
◄lufs_tolerance2.0►
◄max_true_peak_dbtp-1.0►
◄target_true_peak_dbtp-2.0►
◄plr_gain_only_threshold13.0►
◄max_noise_floor_dbfs-40►
◄max_lra_lu3.0►
◄max_dropout_seconds2.0►
◄fix_loudnesstrue►
◄fix_true_peaktrue►

Audio is the layer nobody designed ComfyUI for. The models are good - Chatterbox, ACE-Step, MMAudio - but the plumbing got bolted on late, and the boring parts still happen outside the graph. A VibeVoice walkthrough from May 2026 has a top reply that's basically "the better the models get, the more work I do outside ComfyUI." Mastering was one of those jobs. Audacity, normalize, hope.

Audio Standards Fixer pulls loudness compliance back inside the graph. It's the second node in Khip01's AudioQualityCheck pack, and it takes an AUDIO from a TTS or music node, measures five broadcast-style criteria, corrects the two that are correctable, and returns the audio plus a report. (The pack's other node, the evaluator, measures and changes nothing.)

What it actually fixes

Two things. Loudness, via linear gain toward target_lufs. True peak, via a lookahead limiter. That's it - and the pack is unusually honest about the rest, which is why I'd trust it over most "quality enhancer" nodes.

The mechanism is a small mastering chain in numpy. The tensor becomes a [samples, channels] float32 matrix and everything from there runs on CPU; no GPU, nothing to download. Integrated loudness and LRA come from pyloudnorm (ITU-R BS.1770-4 gated loudness), true peak from a 4x polyphase oversample, noise floor from the 10th percentile of 50 ms RMS windows, dropout from the longest run below -60 dBFS. Then gain, then limiting on 4x oversampled audio so inter-sample peaks stay under the ceiling, then re-measurement - up to three passes, correcting gain again if limiting dragged loudness outside lufs_tolerance.

The clever bit is PLR: the gap between true peak and loudness, which linear gain can't change. It tells you up front how much limiting you'll need, and the report prints a feasibility verdict - light limiting, heavy limiting, or not achievable. If the source is already a brick, it says so before you wonder why it sounds squashed.

The inputs you'll actually touch

audio is the only wire. Of the widgets, beginners touch four:

  • target_lufs - default -14.0, the Spotify/YouTube streaming target, and roughly what every "AI voice is too quiet" complaint is about.
  • target_true_peak_dbtp - default -2.0 dBTP, deliberately stricter than max_true_peak_dbtp (default -1.0) because lossy re-encoding adds inter-sample peaks. Set it above the pass limit and the stricter value wins anyway, with a note in the report.
  • fix_loudness / fix_true_peak - one toggle per correctable criterion, both on. Flip one off and that criterion is reported but left alone.

Everything else - max_noise_floor_dbfs, max_lra_lu, max_dropout_seconds, lufs_tolerance, plr_gain_only_threshold - only decides PASSED or FAILED in the report. Noise floor, LRA and dropout are report-only, full stop.

Outputs are audio (wire it to SaveAudio, or into whatever consumes it downstream - a lipsync node, say), report (a STRING), and is_fixed (a BOOLEAN).

Install

No models, no GPU, three pure-Python dependencies - about as low-risk as custom nodes get. Search comfyui-audio-quality-check in ComfyUI Manager and restart. Manually:

cd /path/to/ComfyUI/custom_nodes
git clone https://github.com/Khip01/ComfyUI-AudioQualityCheck.git
pip install -r ComfyUI-AudioQualityCheck/requirements.txt

That's numpy, scipy, pyloudnorm - install with ComfyUI's own interpreter (embedded python or your venv) or the import fails and the nodes never appear. Both land under audio/quality. The four bundled example workflows point at an example_audio.wav that isn't included, so pick your own file; the fixer chain runs LoadAudio → evaluate → fix → evaluate again → SaveAudio.

Where people get burned

The report doesn't appear on the node body. The pack ships no frontend extension, so connect report to a core Preview Any node - the standard way to read any STRING output.

is_fixed: true doesn't mean your audio passes everything. In the source that boolean is loudness settled AND peak settled, nothing else. Noise floor, LRA or dropout can still fail while it reads true and the status says FIXED WITH NOTES.

LRA ≤ 3 LU is a broadcast spec and it will fail on most music. A real song runs far wider, and this node can't compress it - the report just tells you to fix it upstream. Same trap with dropout, which counts any run below -60 dBFS: a deliberate ambient bed or long intro trips it, so raise max_dropout_seconds when the silence is meant to be there.

A few smaller ones. The conversion reads the first item of an incoming batch, so a batch of takes won't come back as a batch. If everything already passes, the status reads UNCHANGED and nothing is applied - success, not a bug. And you'll never see gain only in a report even though the README lists it; that string exists in the code but nothing returns it, so a track needing no limiting still prints light limiting with no reduction needed.

If the nodes don't show up in the Add Node menu, check the startup log for the ComfyUI-AudioQualityCheck traceback - that's a missing dependency or Python older than 3.9. On managed platforms, a curated node list means registry publication isn't availability.

Should you use it

If you do voice or music work and you've been bouncing to Audacity to hit -14 LUFS, yes - this is the in-graph version, and it's honest when the target isn't reachable. Want EQ, compression and a full mastering chain? Different pack. This is a quality gate plus a two-knob fixer, and it's better for being narrow.

Categoryaudio/quality

Inputs (11)

NameTypeDefaultDescription
audioAUDIO—
target_lufsFLOAT-14.0-70–0—
lufs_toleranceFLOAT2.00.1–10—
max_true_peak_dbtpFLOAT-1.0-20–0—
target_true_peak_dbtpFLOAT-2.0-20–0—
plr_gain_only_thresholdFLOAT13.00–30—
max_noise_floor_dbfsFLOAT-40-100–0—
max_lra_luFLOAT3.00.5–20—
max_dropout_secondsFLOAT2.00.1–10—
fix_loudnessBOOLEANtrue—
fix_true_peakBOOLEANtrue—

Outputs (3)

NameTypeDescription
audioAUDIO—
reportSTRING—
is_fixedBOOLEAN—