ꘇ mod.scope
An oscilloscope for the patch you just built
- input
- audio
- channels
- rms
- peak
- image
ꘇ mod.scope draws the waveform going past it as a stereo oscilloscope - and, more usefully for a ComfyUI workflow, it exposes that sound as control data and as an IMAGE you can pipe into the rest of your graph. It's the bridge node between "I have audio" and "I have visuals driven by audio".
What it is
Genereti's mod.* family is a live Web Audio patching layer that runs in your browser tab, with chop.* control signals feeding the same graph. mod.scope is one of four analysis taps that sit inline on the audio bus: they pass the bus through unchanged, so you can drop one into a working patch without rewiring anything, or hang it off the side as a parallel tap.
The four are near-identical in shape - mod.scope (waveform), mod.spectrum (frequency bins), mod.lissajous (left vs right XY) and mod.analyze (levels and bands). Same inputs, same five output sockets. Which one you pick is about which view of the sound you want to read or draw, not about different plumbing.
How it works
The scope splits the incoming bus into left and right with a channel splitter and runs an AnalyserNode per side, then reads time-domain samples. fft_size sets the analyser's buffer size (256 to 4096, default 1024); smoothing is the analyser's smoothing time constant, applied to the spectral bins, not the waveform. display_gain only scales the drawing - it never changes the sound or any of the reported measurements, which is worth repeating because it looks exactly like a volume knob.
The channels output for this node carries left and right waveform blocks at the AudioContext sample rate, delivered as a CHOP snapshot on the control timer. Not audio-rate DSP - the docs describe the analysis taps as a visual/control bridge, not a CHOP processing engine. That's fine for driving parameters; it's not the tool for sample-level processing.
The inputs and outputs that matter
Inputs: input (the bus, passed through), fft_size (256/512/1024/2048/4096, default 1024), smoothing (0–0.99, default 0.5), display_gain (0.1–20, default 2).
Outputs, all five of them:
audio- the bus again, unchanged. Keep chaining.channels- the CHOP block. Here:left,right.rmsandpeak- plain FLOAT sockets. This is the shortcut API, and it's the one most people should use.image- an IMAGE drawing of the scope view, which you can feed to any image-side node (TOPs, Livecode, previews).
The bundled ꘇ-Sound-Analysis workflow wires mod.analyze → chop.select (rms) → chop.math (×12) → top.filter (amount) - sound drives opacity. For simpler jobs, take the rms or peak float straight into a converted numeric input and skip the CHOP. Use Alt+W / Alt+O (or the viewing toolbar) if you want the scope as an overlay or output-only panel.
Install
Manager → search Genereti, or:
git clone https://github.com/languel/genereti.git custom_nodes/genereti
./.venv/bin/python -m pip install -r custom_nodes/genereti/requirements.txt
Restart ComfyUI, then reload the browser. Note the pack's own instruction for the analysis nodes specifically: restart once to register the new schemas, then refresh - a cached tab won't show the updated sockets. requirements.txt is one line (comfyui-frontend-package>=1.53.6); no models, no extra packs. Comfy ≥ 0.38.2, Python ≥ 3.11.
Common issues
The scope is a flat line and the CHOP reads zeros. Two possibilities. If you queued, that's expected: queued execution of these taps returns silent channels, rms/peak at zero, and a placeholder IMAGE - they don't read live sound during a queue. If you're running live, the analyser is downstream of the bus, so check that a mod.output is actually started; the taps "never start an unrelated instrument" and read whatever flows through them.
display_gain didn't change anything. It's cosmetic by design. Use mod.gain or the output level for real loudness.
The waveform looks quantised or steppy. Check fft_size; a 256-sample time-domain window is short, and a bigger buffer shows more shape.
The image output is a placeholder. Same queue-vs-live distinction: queued runs draw a silent placeholder rather than reading your speakers. Also true after Panic - stopping clears all measurements.
Channels look like they stop updating. Analyser buffers and AudioNodes are reused and snapshots update on the control timer, not per audio sample; wave form channels use the AudioContext rate, spectrum channels are frequency bins, not sequential samples. Don't treat the frequency channel of a spectrum tap as a time series.
Standard caveat: this is a solo MIT alpha (Liuboto, v0.1.4), "super alpha - early classroom testing", so back up workflows before updating.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| input | GENERETI_AUDIO_BUS | — | |
| fft_size | COMBO | 1024 | 5 options: 256, 512, 1024, 2048, 4096 |
| smoothing | FLOAT | 0.500–0.99 | — |
| display_gain | FLOAT | 2.000.1–20 | — |
| widthopt | INT | 51264–2048 | — |
| heightopt | INT | 25664–2048 | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| audio | GENERETI_AUDIO_BUS | — |
| channels | GENERETI_CHOP | — |
| rms | FLOAT | — |
| peak | FLOAT | — |
| image | IMAGE | — |