Rms (Audio Op)
RMS — the energy envelope that's doing half the work in audio-reactive work
- signal
- SIGNAL
OpRms (display name "Rms (Audio Op)") is the most useful node in the ComfyUI-AudioReactive pack, and it's also the most ignorable-looking: one SIGNAL in, one SIGNAL out. What it computes is the root-mean-square amplitude of the audio over time - basically a smooth "how loud is it right now" curve. It's the classic audio-reactive driver: louder music, bigger pulse.
The pack is dmarx's port of his video-killed-the-radio-star notebook, and RMS was the feature that notebook leaned on hardest for driving animation parameters. In the wider ecosystem this is the same trick the audio-reactive AnimateDiff crowd uses to make ControlNet strength and motion amount breathe with the track - you just need the energy curve to exist first. That's this node's job.
How it works
Under the hood it's normalize(librosa.feature.rms(y=y).ravel(), sr). Two things to internalize:
librosa.feature.rmscomputes RMS over short windows (frames), so the output is not per-sample - it's a per-frame energy curve, a few hundred values for a whole track, not the hundreds of thousands of samples in the waveform. That's a control signal, not a waveform.normalizedivides by the peak value, so the curve lands in 0..1. A value of 1 = loudest moment in the file, 0 = silence. Nothing ever exceeds 1, which is exactly what you want when you're about to map it onto a strength or scale parameter.
Because it's normalized, it's robust across tracks - you don't have to re-tune your animation chain for every song's loudness.
Inputs and outputs
signal(SIGNAL) - normally straight fromARReadAudio, or from another operator upstream.SIGNAL- the same dict withyreplaced by the normalized RMS envelope. Wire it intoARDrawSignalto see it, orSignalToCurveto turn it into aKEYFRAMED_CURVEthat drives whatever scheduler you're using.
That's the whole interface. This is a deliberately thin node - the thinking happens in what you attach to it.
A honest warning about the pack's state
The natural next step after RMS is smoothing the envelope so it doesn't jitter, and the pack ships OpSmooth for exactly that. But as of this writing, Smooth (like Sustain, Bandpass, Modulo, Quantize, Pow, and Clamp) is a parameterized operator whose node wrapper doesn't expose its parameter yet - it emits a Python function object instead of a filtered signal, and anything downstream will choke. So don't wire RMS → Smooth and expect a curve; you'll get an error. Either feed RMS straight into SignalToCurve or smooth it yourself elsewhere. Rms itself works fine.
Installing it
Manager (search "AudioReactive") or:
cd ComfyUI/custom_nodes
git clone https://github.com/dmarx/ComfyUI-AudioReactive
restart, and wait through the first-start auto-install of scipy, scikit-learn, librosa, loguru (librosa brings numba). If ComfyUI refuses to load the pack with ModuleNotFoundError: No module named 'keyframed', run pip install keyframed - that one's imported but missing from the auto-install list.
Common issues
- Output is much shorter than the input. That's normal - it's per-frame, not per-sample. Don't treat it as a waveform.
- The plot from Draw Audio Signal has a wrong-looking time axis. Known cosmetic bug with frame-based features (the
is_rawflag staysTrue). The curve shape is right. - The whole pack is a work-in-progress port - single commit, one-line README. It works for the core feature ops (this one included), but don't expect polish or a huge community behind it yet. The author (dmarx / DigThatData) is a well-known figure from the keyframed / music-video-automation world, which is the lineage to blame for how good this one node's output is.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| signal | SIGNAL | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| SIGNAL | SIGNAL | — |