Nodes/ComfyUI-AudioReactive/Normalize (Audio Op)
ComfyUI Node

Normalize (Audio Op)

Normalize — the one node that makes every other operator's output usable

By dmarx·Created 3 years ago·Updated 2 years ago· 11
Normalize (Audio Op)
  • signal
  • SIGNAL

OpNormalize (display name "Normalize (Audio Op)") is the pack's janitor, and it earns that job. It takes a signal, takes its absolute value, and divides by the peak so the loudest value lands exactly at 1. Every other curve in the pack assumes this kind of shape exists - and a couple of the operators produce output that's positively feral until you run it through this.

The implementation from nodes/audio_utils.py:

def normalize(y, sr):
    normalized_signal = np.abs(y).ravel()
    normalized_signal /= max(normalized_signal)
    return normalized_signal

Three things to notice. First, it's absolute value - a bipolar waveform gets folded positive. Second, it's peak normalization, not RMS normalization: it scales so the max is 1, which means the loudest instant of the file defines the scale (so a track with one huge transient can make everything else look quiet - peak normalization's classic flaw). Third, it flattens to 1-D via .ravel(), but for the signals in this pack that's cosmetic.

Why you'll actually reach for it: several operators do not normalize their output. OpSqrt computes y**-2 and leaves the result enormous. OpAbs on a bipolar waveform doubles the energy. Even the "working" operators can leave you in an awkward range. Slap Normalize after anything whose output looks wild and you're back to a sane 0..1 driver curve you can safely feed into SignalToCurve.

Inputs and outputs

  • signal (SIGNAL) - any signal from the pack.
  • SIGNAL - y replaced by its absolute value, scaled so the peak is 1.0, same length.

It's a parameter-free, always-works operator - one of the genuinely solid ones in a pack that's otherwise a work-in-progress port.

Installing it

Manager (search "AudioReactive") or:

cd ComfyUI/custom_nodes
git clone https://github.com/dmarx/ComfyUI-AudioReactive

Restart and wait through the first-load auto-install of scipy, scikit-learn, librosa, loguru (librosa pulls numba, so that first start is slow). If the pack won't load with ModuleNotFoundError: No module named 'keyframed', run pip install keyframed.

Common issues

  • A single loud transient makes everything else tiny - that's peak normalization doing exactly what it says. If your track has one massive hit, the rest of the envelope gets scaled down; consider re-normalizing sections or using Smoosh after to lift the quiet parts.
  • Output is fully positive - yes, abs() first. That's usually what you want for a driver curve; if you needed a signed signal, don't use Normalize.
  • It's not loudness normalization - it won't make two songs equally loud in an RMS sense. Peak vs. loudness are different things; this is the peak kind.
  • Pair it with the wild ones - Sqrt (y**-2), Abs, and (once they're wired) the parameterized ops all benefit from a Normalize downstream. Keep one around as a standard part of your chains.
CategoryAudioReactive/Operators

Inputs (1)

NameTypeDefaultDescription
signalSIGNAL

Outputs (1)

NameTypeDescription
SIGNALSIGNAL