APNext H3 Song Analysis (BPM / intensity)
BPM and aggression, right on the canvas
- audio
- audio
- profile
- bpm
- intensity
- label
What it is
Wire a song in and H3 Song Analysis prints something like ~124 BPM | driving (intensity 68/100) | moderate dynamics (9 dB) | 2.7 onset spikes/s right on the node. It's a readout of the two numbers that decide how a music video gets staged: how fast the song is and how hard it hits.
Here's the honest framing: the same pack's Music Video Writer measures all of this itself, internally, to steer its staging - which pieces are quiet enough for long intimate shots, which peaks get the cuts and the chorus look. This node doesn't add any of that behavior. It's the visible version, dropped between Load Audio and a writer so you can sanity-check a song before committing to a long render, or calibrate wildness and performance_mode on real numbers instead of vibes.
How it works
All pure torch and numpy - the source is explicit that no librosa is needed. It runs an STFT with a Hann window, then pulls three feature envelopes: spectral flux (onset strength, i.e. how suddenly notes and hits appear), RMS loudness, and novelty (long-window energy change, which flags section boundaries). From those:
- BPM comes from the autocorrelated onset envelope. It returns
0.0when there's no steady pulse to lock onto - a spoken-word intro or pure ambient will report nothing rather than guess. - Intensity (0–100) blends three things: transient density (onset spikes per second), sustained loudness (how close the typical level sits to the loud peaks - the wall-of-sound factor), and punch (how hard the hits hit), weighted 0.45 / 0.35 / 0.20.
- Label buckets the score:
gentle< 20,laid-back< 40,mid-energy< 60,driving< 80, thenaggressive. Dynamics get their own label -compressed(< 6 dB spread),moderate, orwide.
It runs on CPU and finishes in a blink. This is not a heavy-analysis node.
The one input and the five outputs
One input, and it's not even worth explaining - audio, straight from Load Audio. The outputs:
audio- the same audio, passed through untouched. Wire the writer from here, which is the neat bit: the node sits in the path without breaking it.profile- the one-liner string above, wireable into any STRING or context input (filenames, a note node, whatever).bpm(float),intensity(int 0–100),label(the bucket name) - the three numbers as separate wireable outputs.
Note it's an output node, so it shows its text on the canvas - but because the audio passes through, it doesn't terminate the chain. It's a display that happens to be in the middle.
Installing it
It ships in dagthomas/comfyui_dagthomas. ComfyUI Manager → search comfyui_dagthomas → Install, then restart. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/dagthomas/comfyui_dagthomas
cd comfyui_dagthomas
pip install -r requirements.txt
No extra dependencies, no model downloads. If you want to render a music video off the back of it you'll need ComfyUI's MiniMax H3 node and weights (mind the H3 license's territory restrictions), but this node's own footprint is zero.
Common gotchas
- It changes nothing. This is a monitor, not a processor - the audio comes out identical. If you were hoping it would fix a song's levels, that's not the node.
bpmof 0.0 is information, not a bug. It means the song has no steady pulse. A track like that is exactly the case where you'd lean onperformance_modeinstead of beat-timing.- Don't over-read a single number.
drivingat 68/100 tells you about aggression, not quality - a gentle ballad and a brickwalled pop track can both be right for their video, just differently staged.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | The song (Load Audio). Passed through unchanged on the audio output. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | The same audio, passed through - wire the writer from here. |
| profile | STRING | One line: BPM | label (intensity /100) | dynamics | onset spikes/s. |
| bpm | FLOAT | Estimated tempo; 0.0 = no steady pulse detected. |
| intensity | INT | Aggression 0-100 from transient density, sustained loudness and punch. |
| label | STRING | gentle / laid-back / mid-energy / driving / aggressive. |