Harmonic (Audio Op)
Harmonic — peel the melodic layer off your audio with HPSS
- signal
- SIGNAL
OpHarmonic (display name "Harmonic (Audio Op)") runs harmonic-percussive source separation (HPSS) and hands you the harmonic half: the sustained, tonal part of the signal - vocals, strings, pads, the melody - with the drums and other transient noise stripped out. It's the first half of a two-node pair; its sibling Percussive gives you everything it removed.
Why split a signal in the first place? Because different layers of a track want different treatment in an audio-reactive workflow. A string pad's energy envelope is slow and smooth; a hi-hat's is spiky. If you drive one animation parameter off the whole mix, the layers fight each other. Split them and each can drive its own thing. This is the same idea the stem-separation crowd leans on for audio-reactive music videos - the AnimateDiff audio-reactive work builds whole pipelines on "separate the layers, drive keyframe transitions and ControlNet strength from each." HPSS is the cheap, dependency-free version: no demucs, no models to download, one librosa call.
How it works
The implementation is librosa.effects.harmonic(y=y) - HPSS via the median-filtering approach in the classic Fitzgerald 2010 paper ("Harmonic/Percussive Separation Using Median Filtering"). In plain terms: harmonic content is continuous in frequency, so it survives a median filter along the time axis; percussive content is broadband and short, so it survives a median filter along the frequency axis. Filter the spectrogram both ways, subtract, reconstruct, done.
Two things worth knowing:
- Unlike
Rms,Novelty, orPredominant_Pulse, the output here is sample-level - same length as the input waveform, not a short feature curve. It's audio, not a control signal. - HPSS is a heuristic, not a separator model. It's impressively good at separating drums from tonal content on most music, and it does not do instrument-level separation (no "just the bass"). For that you'd want a proper stem separator. If your track is heavily synthesized or just weird, the separation will be imperfect - that's the technique, not a bug.
Inputs and outputs
signal(SIGNAL) - fromARReadAudioor upstream of another operator.SIGNAL-yreplaced by the harmonic (tonal) component. From here you can run more operators on it - the natural move isRmson the harmonic layer to get a smooth melody-energy curve - or feed it toARDrawSignalto see the layer.
Installing it
Manager (search "AudioReactive") or:
cd ComfyUI/custom_nodes
git clone https://github.com/dmarx/ComfyUI-AudioReactive
Restart. First load auto-installs scipy, scikit-learn, librosa, loguru (and librosa pulls numba), so give it a few minutes. If you see ModuleNotFoundError: No module named 'keyframed', pip install keyframed - it's imported at startup but not on the auto-install list.
Common issues
- Output length matches the input - that's correct for this one; it's audio, not a feature curve. Don't be confused when it's much longer than
Rms's output. - Drums still bleeding through - HPSS isn't a stem model. Accept it or reach for a real stem separator.
ARDrawSignalplot shows a dense mess - a full-res waveform of a harmonic layer looks like noise at plot scale; that's the plot, not the node.- Early-port caveats apply - this one is a working core op, but the pack is a single-commit port with the parameterized ops left as unwired stubs. Build on the working ops, plan around the stubs.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| signal | SIGNAL | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| SIGNAL | SIGNAL | — |