Audio Feature Calculator
How the Feature Calculator turns audio into numbers ComfyUI can use
- audio
- FEAT_MODS
- FEAT_SECONDS
- FPS
- CHARTS
This is the brain of MBM's Music Visualizer. The Audio Loader just hands you a waveform; the Audio Feature Calculator is what actually listens to it. It chews through the loaded audio with librosa, extracts a handful of musical features, and condenses them into one number per frame - the "feature modifier" that tells every node downstream how energetic that moment in the song is. No audio analysis, no music video; everything that makes the renderer react to the beat starts here.
How it actually works. The node computes four features from the audio: tempo (via onset strength), the mean power of a mel spectrogram (128 mel bands, capped at 8 kHz), the rate of change of that power, and chroma (which pitch classes are prominent, per hop). Each is normalized, then everything gets resampled to a target frame count - round(fps_target × duration). Each frame then gets a single modifier from the formula:
modifier = ((tempo + 1) × (spectroMean + 1) × (chromaMean + 1)) × (intensity + spectroMeanDelta)
clamped to feat_mod_min/feat_mod_max. So loud, beat-heavy, pitch-moving moments produce big modifiers; quiet stretches produce small ones. That per-frame array is the FEAT_MODS output.
The inputs that matter. You'll realistically touch three of these:
intensity- a multiplier on the whole thing. Crank it up if the renderer feels sluggish; the default1.0is a reasonable start.fps_target- default6, i.e. six frames per second of audio. Set it to0or less and the node derives the frame rate from the audio itself, which is what a lot of people end up on because it's one less number to pick.feat_mod_normalize- when on, the modifier array is normalized between0and its own max. Handy, but the README-level caveat is that the min/max values you set become meaningless against the normalized output.
hop_length (default 512) controls the analysis window - leave it alone unless you know you need to. feat_mod_max/feat_mod_min (default ±10000) are just clamps; the defaults are described in the source as "unattainable through normal usage," which makes them more of a safety net than a dial.
The four outputs, and where they go. FEAT_MODS (the per-frame modifiers) feeds the Prompt Sequence Interpolator's feat_mods input and the Prompt Sequence Renderer's latent_mods input. FPS is what you plug into SaveAnimatedWEBP or a video node - the renderer's example workflow uses exactly that wiring. FEAT_SECONDS (the duration each frame represents) is needed by the interpolator when you use timecode-based splitting. CHARTS is a stack of matplotlib charts - tempo, spectrogram mean, delta, chroma, and the feature modifiers - which are gold for debugging without committing to a full render.
The trick the README wants you to know: when you're tuning the flow, bypass the Prompt Sequence Renderer (or set its image_limit). The calculator, interpolator, and renderer all emit CHARTS images, so you can still see the full data story - feature curve, prompt distribution, latent means - without burning a single diffusion pass. Test the numbers first, render once.
One honest caveat: this pack is a small hobby project (last touched mid-2024) and the formula above is a hand-rolled blend, not a published algorithm. Treat the modifiers as a vibe, not a ground truth - if the output feels over- or under-reactive, intensity is the first knob, not a feature flag somewhere.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | — | |
| intensity | FLOAT | 1.00 | — |
| hop_length | INT | 512 | — |
| fps_target | FLOAT | 6.00-1–10000 | — |
| feat_mod_max | FLOAT | 10000.00-10000–10000 | — |
| feat_mod_min | FLOAT | -10000.00-10000–10000 | — |
| feat_mod_normalize | COMBO | 2 options: false, true |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| FEAT_MODS | TENSOR_1D | — |
| FEAT_SECONDS | FLOAT | — |
| FPS | FLOAT | — |
| CHARTS | IMAGE | — |