Nodes/ComfyUI-AudioReactive/Clamp (Audio Op)
ComfyUI Node

Clamp (Audio Op)

Clamp — a ceiling for your signal that never got connected (stub warning)

By dmarx·Created 3 years ago·Updated 2 years ago· 11
Clamp (Audio Op)
  • signal
  • SIGNAL

OpClamp (display name "Clamp (Audio Op)") is supposed to be a one-directional ceiling: any value above a high threshold gets pulled down to high, and everything below passes through untouched. In the source it's two lines:

def clamp(high):
    def f(y, sr):
        y[y>high] = high
        return y
    return f

In audio-reactive terms, that's the answer to "my beat curve occasionally spiking so hard it saturates my animation" - clamp it at 0.8 and nothing exceeds 0.8. Genuinely handy.

Here's the honest part: the node doesn't work yet. Same disease as Bandpass, Modulo, Pow, Quantize, Smooth, and Sustain.

What's actually going on

clamp is written as a factory: you call clamp(high) to get a clamping function. The node wrapper in nodes/audio_operator_nodes.py calls every operator the same way - f(y, sr) - so it calls clamp(y, sr) with the signal as the high argument. That doesn't clamp anything; it returns a new closure sitting where the audio data should be. The node completes without raising an error, and the pack's SIGNAL dict blithely carries that function object downstream. When you feed the result into ARDrawSignal or SignalToCurve, you'll get a TypeError about a function object where an array was expected.

The info_schema backs this up: the node exposes only a signal input - there's no high parameter anywhere, so a user literally cannot set the ceiling. It's an unwired stub from the port.

What to do instead

  • If a workflow has "Clamp (Audio Op)" in it, expect it to break downstream and remove or bypass it. It's not your fault.
  • Need a ceiling today? The pack has no working alternative, but the math is trivial elsewhere: OpNormalize peak-scales everything to 1.0, and for "cap at 0.8" any generic ComfyUI clamp/math node on the curve output will do.
  • Watch the repo. The backend is real and correct; this just needs the wrapper to expose a high input and call the factory properly. The pattern of "backend done, wrapper stubbed" is the pack's current state, and it's the kind of thing that gets finished.

Inputs and outputs

As shipped:

  • signal (SIGNAL) - in.
  • SIGNAL - out, but containing a Python function object instead of clamped audio. Don't build on it.

Installing it

Manager (search "AudioReactive") or:

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

Restart and wait through the first-load auto-install of scipy, scikit-learn, librosa, loguru. ModuleNotFoundError: No module named 'keyframed' on load → pip install keyframed (it's imported at startup, missing from the auto-install list).

The takeaway

This pack is an in-progress port of dmarx's video-killed-the-radio-star notebook, and a chunk of the operator nodes are placeholders waiting for parameter inputs. Clamp is one of them. Before you trust any node name in the AudioReactive/Operators category, skim nodes/audio_utils.py - it's short, and it tells you in two lines whether a node is real or still a stub.

CategoryAudioReactive/Operators

Inputs (1)

NameTypeDefaultDescription
signalSIGNAL

Outputs (1)

NameTypeDescription
SIGNALSIGNAL