Novelty (Audio Op)
Novelty — an onset-strength curve that spikes exactly when the beat hits
- 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 fromARReadAudio, or downstream of another op.SIGNAL- the same dict withyreplaced by the normalized onset-strength curve. Take it toARDrawSignalto confirm the spikes line up with the hits, then toSignalToCurveto turn it into aKEYFRAMED_CURVEfor 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
Rmsfor a loudness-based driver instead. - Plot time axis looks wrong in Draw Audio Signal - known cosmetic quirk: frame-based features inherit the
is_rawflag, 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.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| signal | SIGNAL | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| SIGNAL | SIGNAL | — |