kubakub sound
Find the tempo once, so every node steps on the same beat
- audio
- sound
- audio
- bpm
- report
Audio-reactive setups fail in a specific, annoying way: you wire the same track into four different nodes, each one does its own loudness and beat detection with its own settings, and nothing lands together. The shader flashes a beat late, the mask swap a beat early, and you spend an evening nudging offsets. Whole genres of music video have been lost to this.
kubakub sound exists to make that impossible. It holds your sound and how it's heard, and hands the whole thing to every node that listens over one sound cable. The tempo is detected once, here, so nothing on the bus can disagree about where the beat is.
What listens to it
Connect sound to the sound input of kubakub shader, mask animate, kubakub height animate, kubakub motion guide, kubakub shader mix or kubakub sound mask swap. Once the cable is in, those nodes hide their own sound settings and stop using their own audio input - those settings belong to this node now. What stays local is what belongs to each node: which beat it acts on, and what it does then. Pull the cable and the old per-node behaviour comes back, so adopting it loses nothing.
How the hearing works
It's pure numpy - no librosa, no extra dependency. Tempo comes from the jumps in energy of a pre-emphasised signal (the pre-emphasis is what makes kick and snare edges pop), turned into an onset strength curve and a beat grid. Loudness is split into three bands: low 30–150 Hz (kick, bass), mid 150–2500 Hz, high 4000–16000 Hz (hats, clicks), and listen picks which band the loudness follows - or everything.
Hits are separately detected, and they're the part worth tuning: threshold (default 0.3) is how strong a hit must be to count, and gap (default 0.1 s) is the minimum spacing between counted hits so a drum roll doesn't strobe. release (0.15 s) is how fast the loudness falls after a peak - low is nervous and twitchy, high is round and slow. gain is just how loud the sound is heard, and you raise it above 1 for a quiet recording; if your reactive effect is barely moving on a phone recording, this is the first dial, not threshold.
bpm is there for when you know the tempo - type it and the detection is skipped. Leave it at 0 and the tempo is found in the sound; the report and the bpm output tell you which happened (0 on the output means none was found, which is your cue to type it in by hand). start and seconds trim which stretch of the sound is used.
Outputs, and what the picture means
sound is the cable - the sound plus all of the above, for every node that listens. audio is the same stretch of sound as a plain audio stream, for Create Video, so your exported clip carries the music. bpm is the tempo. report gives length, tempo, first beat, and how many hits counted in each band - genuinely useful, because "the shader isn't reacting" is usually "that band had zero hits above the threshold", and the report says so in numbers instead of leaving you guessing.
After a run the node also draws the analysis: the loudness as a line, the beats as bars (every fourth one brighter, so you can see the bar structure), and the hits in the high, mid and low bands as three rows of dots. That picture is the fastest way to check whether your threshold is sane - you want the bright dots to be the hits you'd actually count, not all of them and not none.
With nothing connected to audio, everything still works: you get a built-in 120 bpm beat, which is the standard pack trick for building and timing a whole sequence before the music arrives. Every sound-curve node in the pack does this too, so a graph with no audio at all still animates on a steady grid.
Install
Nothing. It ships in kubakubkub/ComfyUI_KubaNodes, needs no AI model, no ffmpeg and no extra package beyond the pack's OpenCV:
cd ComfyUI/custom_nodes
git clone https://github.com/kubakubkub/ComfyUI_KubaNodes
python -m pip install -r ComfyUI_KubaNodes/requirements.txt
Restart afterwards; the pack wants ComfyUI 0.37.0 or newer (V3 node API). Or install through ComfyUI Manager by searching kubakub nodes. There's a sound.json example workflow that wires one sound node into several listeners, which is the quickest way to see the shared-beat behaviour for yourself.
Where it goes wrong
The most common confusion is expecting this node to make a node react differently - it doesn't, it makes them react together. Want the mask swap on the downbeat and the shader on every hit? That's per-node settings on those nodes, with the shared sound underneath. Second: hit-detection settings tuned for one track are wrong for the next; the grid is real, but threshold and gap are genre-dependent, so re-glance at the drawn dots after you swap songs. Third: if nothing moves at all, check whether the node you're feeding still thinks it has no sound - an unhooked cable quietly restores that node's own settings and its own analysis path.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| bpm | FLOAT | 0.00–400 | The tempo, when you know it. 0 = found in the sound (the report says which). |
| gain | FLOAT | 1.000–10 | How loud the sound is heard: the orange line. Above 1 for a quiet recording. |
| release | FLOAT | 0.150–5 | Seconds the loudness takes to fall after a peak: low = nervous, high = slow and round. |
| listen | COMBO | everything | Which part of the sound the loudness follows: everything, or only the low (kick, bass), mid or high (hats, clicks) frequencies. |
| threshold | FLOAT | 0.300–1 | How strong a hit has to be to count (0 = every hit, 1 = only the strongest): the bright dots count, the dim ones do not. |
| gap | FLOAT | 0.100–10 | The shortest time between two hits that count, so a roll does not flicker. |
| start | FLOAT | 0.00–36000 | Seconds into the sound where it starts. |
| seconds | FLOAT | 0.00–36000 | How much of the sound is used. 0 = to its end. |
| audioopt | AUDIO | Your sound (Load Audio). Empty = a built-in beat (120 bpm). |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| sound | KUBA_SOUND | The sound with these settings: into 'sound' of every node that listens. |
| audio | AUDIO | The same stretch of the sound, for Create Video. |
| bpm | FLOAT | The tempo: yours, or the one found (0 = none found). |
| report | STRING | Length, tempo and first beat, and how many hits count in each band. |