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

Novelty (Audio Op)

Novelty — an onset-strength curve that spikes exactly when the beat hits

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

OpNovelty (display name "Novelty (Audio Op)") computes what librosa calls onset strength: a per-frame curve that jumps whenever something new happens in the audio - a drum hit, a chord change, a vocal entrance. It's the "things are happening right now" signal, and it's the go-to driver when you want animation to react to events rather than to loudness.

Why "novelty"? It comes from the original video-killed-the-radio-star notebook this pack ports - dmarx (DigThatData) needed a name for the "how surprising is this moment" feature and novelty stuck. Same name survives in the port. It's the sibling of Rms: RMS tells you how loud, novelty tells you how suddenly different. Loud but sustained sections barely register; a single snare hit lights it up.

How it works

The implementation is a one-liner: librosa.onset.onset_strength(y, sr). Internally librosa computes a spectral flux-ish measure - it tracks how much the frequency content changes frame to frame and returns a curve where sudden spectral change produces a peak. It's a well-trodden, dependency-free bit of DSP; no machine learning, no models to download. The output is a per-frame curve (a few hundred values for a typical track), and - same as Rms and Predominant_Pulse - it's meant to be a control signal, not a waveform.

One thing worth knowing: onset strength is drum-agnostic in the good way. It doesn't need separated stems. If your track is a dense wall of sound and onset strength comes out mushy, that's the audio, not the node - the feature genuinely is "how much changed in this instant," and heavily saturated mixes change less per frame.

Inputs and outputs

  • signal (SIGNAL) - straight from ARReadAudio, or downstream of another op.
  • SIGNAL - the same dict with y replaced by the normalized onset-strength curve. Take it to ARDrawSignal to confirm the spikes line up with the hits, then to SignalToCurve to turn it into a KEYFRAMED_CURVE for driving keyframe transitions, ControlNet strength, or motion amount on the beat.

If you want every beat and not just the downbeats, novelty is usually the better driver than RMS - RMS smears hits together, novelty keeps them discrete.

Installing it

Manager (search "AudioReactive") or:

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

Restart and let the first-start auto-install do its thing: scipy, scikit-learn, librosa, loguru (librosa pulls numba, so the first load takes a couple of minutes). If the pack fails to load with ModuleNotFoundError: No module named 'keyframed', pip install keyframed - it's imported at startup but missing from the auto-install list.

Common issues

  • The curve is much shorter than the waveform - expected; it's per-frame, not per-sample.
  • Sparse or flat output on quiet/simple tracks - onset strength measures change, and if there's little change, there's little novelty. Try Rms for a loudness-based driver instead.
  • Plot time axis looks wrong in Draw Audio Signal - known cosmetic quirk: frame-based features inherit the is_raw flag, so the x-axis is mislabeled even though the curve shape is correct.
  • Pack is a fresh, single-commit port - the core feature ops (this one, Rms, Predominant_Pulse, Harmonic, Percussive) work as described, but the parameterized ops are unwired stubs and the README is one line. Expect rough edges, not a polished release.
CategoryAudioReactive/Operators

Inputs (1)

NameTypeDefaultDescription
signalSIGNAL

Outputs (1)

NameTypeDescription
SIGNALSIGNAL