Nodes/ComfyUI-AudioReactive/Draw Audio Signal
ComfyUI Node

Draw Audio Signal

Draw a waveform as an IMAGE

By dmarx·Created 3 years ago·Updated 2 years ago· 11
Draw Audio Signal
  • signal
  • IMAGE

ARDrawSignal (display name "Draw Audio Signal") is the eyeball node of the ComfyUI-AudioReactive pack. Feed it any SIGNAL and it renders a matplotlib plot of that signal and hands you back a normal ComfyUI IMAGE you can preview or save. It exists because audio features are invisible - you can't tell whether your RMS envelope or onset-strength curve actually has the shape you think it does until you look at it.

This pack is dmarx's port of his old video-killed-the-radio-star notebook, and in that notebook "display the signal" was the step you did constantly while tuning a music-video pipeline. You'd extract a feature, squint at the plot, adjust, repeat. This node is that feedback loop, moved into the graph. It's a debug/verification tool, not a destination - you use it to check what your feature chain is producing before you wire it into SignalToCurve (the node that turns a SIGNAL into a KEYFRAMED_CURVE for driving animation).

How it works

The node calls the pack's draw_signal(y, sr, raw=...) helper. The raw flag comes straight from the signal dict - a SIGNAL carries is_raw=True when it's a raw waveform (as emitted by ARReadAudio) and False for feature-level signals. The flag only changes the x-axis:

  • raw → librosa.samples_to_time(...) - x-axis is seconds, sample-accurate.
  • not raw → librosa.frames_to_time(...) - x-axis assumes you're plotting frame-based features.

Then it plots with matplotlib, saves the figure to a PNG in memory, converts it to a torch tensor, and returns it in ComfyUI's [B, H, W, 3] layout so PreviewImage/SaveImage just work. No file output, no interactive widget - it's a plot-as-image.

Inputs and outputs

  • signal (SIGNAL, marked forceInput) - any signal from the pack: ARReadAudio's raw waveform, or the output of any Op* operator.
  • IMAGE - wire to a PreviewImage node to see it inline, or SaveImage to keep it.

Installing it

Same as every node in the pack - Manager (search "AudioReactive") or:

cd ComfyUI/custom_nodes
git clone https://github.com/dmarx/ComfyUI-AudioReactive

then restart. First start is slow: the pack auto-installs scipy, scikit-learn, librosa, loguru, and librosa pulls in numba - budget a couple of minutes.

Common issues

  • Blank or missing x-axis meaning. If you plot a frame-based feature - Rms, Novelty, Predominant_Pulse all emit per-frame curves - the pack keeps is_raw=True on them, so this node labels the axis as if each value were a sample. The shape of the curve is right; the time scale may be way off (a 10-second track's ~430 RMS frames will render as if it were a fraction of a second). Treat the plot as "what does the curve look like," not "what's the exact timestamp." Annoying, but it won't hurt your downstream animation.
  • Everything downstream explodes. If you feed this node the output of one of the pack's parameterized-but-unwired operators (Bandpass, Smooth, Sustain, Modulo, Quantize, Pow, Clamp), its y is actually a Python function object, and matplotlib will throw a TypeError. That's a known half-finished bit of the pack - see those nodes' pages.
  • The pack won't load - nodes/__init__.py imports keyframed at startup and it isn't auto-installed. ModuleNotFoundError: No module named 'keyframed'pip install keyframed (or install ComfyUI-Keyframed via Manager).

Where people get burned: they treat Draw Audio Signal as an output node that finishes the pipeline. It doesn't. It's a scope for your feature engineering. Use it to confirm the curve you're about to hand to SignalToCurve is spiky in the right places, then get it out of the way.

CategoryAudioReactive

Inputs (1)

NameTypeDefaultDescription
signalSIGNAL

Outputs (1)

NameTypeDescription
IMAGEIMAGE