ꘇ mod.transport
One clock to keep every sequencer honest
- clock
- channels
- seconds
- beat
- json
ꘇ mod.transport is the node that makes the rest of the Genereti audio family play in time. It is a metronome you never hear: a BPM, a swing amount, and five outputs that tell every sequencer downstream where the beat is right now. If you're building anything with mod.sequence or mod.drumsequence in it, this is the first node you drop.
What it is
Genereti is a realtime creative-coding layer for ComfyUI - a pack of browser-side instruments, shaders, texture operators and control signals that live in the frontend rather than in the Python queue. The mod.* family is its Web Audio patching layer, and it's named like TouchDesigner on purpose: top.* for textures, chop.* for control signals, dat.* for data, mod.* for the audio graph. If you've ever wired CHOPs into a TouchDesigner audio-reactive patch, you'll recognise the whole idea.
Audio in ComfyUI is normally a bolt-on - a model that renders a waveform tensor you save to disk. This is the other thing entirely: an actual live instrument graph that runs in your browser tab, where notes fire in real time and nothing is ever written to a file.
How it works
The transport doesn't drive the Python graph at all. It hands out a clock reference to the browser, and the browser schedules notes against the AudioContext timeline - up to 120 ms ahead on a 25 ms timer, so a stutter in the UI thread doesn't smear your drum timing. Time is anchored monotonically, which means a stalled redraw doesn't eat elapsed beats.
It also does the arithmetic for you in Python when you queue: BPM, quarter notes, meter, bar index, 480 ticks per quarter note, and a fractional phase for where you are between beats. That JSON is the thing other nodes and expressions read.
swing is worth a word - it's not a delay node. It nudges the off-beats later, from 0 (straight) up to 0.45, which is enough to make a hi-hat pattern shuffle without sounding broken.
The inputs and outputs that matter
Two widgets do most of the work: bpm (20–300, default 110) and swing (0–0.45). Then one optional string, clock_name:
local(the default) keeps this controller an independent, running clock.projectlinks it to the workflow timeline, so the dock's tempo and transport controls drive your sequence instead.
There's also performance, a JSON string of clock state - leave it at {} unless something upstream is feeding you a snapshot.
Outputs, in socket order, because that ordering trips people up: clock is output 0 and that's the one mod.sequence and mod.drumsequence want wired into their clock input. Then channels (a CHOP snapshot at 25 Hz carrying seconds, quarterNotes, beat, bar, beatInBar, ticks, phase, bpm, playing, iteration), then seconds, beat (meter beats), and json.
Two separate clocks with the same label stay independent - there's no named shared-clock registry yet, so don't expect two clock_name = local transports to lock together.
Install
Manager, search Genereti - or clone it, from your ComfyUI directory:
git clone https://github.com/languel/genereti.git custom_nodes/genereti
./.venv/bin/python -m pip install -r custom_nodes/genereti/requirements.txt
Windows Portable uses its bundled interpreter instead:
python_embeded\python.exe -m pip install -r custom_nodes\genereti\requirements.txt
Restart Comfy, then hard-refresh the browser page. The schema lives in the frontend, so a stale tab means missing nodes. No model downloads, no extra packs - the entire requirements.txt is one line (comfyui-frontend-package>=1.53.6); torch, NumPy, Pillow and aiohttp come from ComfyUI itself. Comfy ≥ 0.38.2 and Python ≥ 3.11.
Common issues
The big one: queueing does nothing audible, ever. The transport returns a route description and clock maths, not sound. You need a mod.output downstream with a live Start pressed before a single note is heard - that button exists because browsers refuse to start an AudioContext without a user gesture.
Also worth knowing before you file a bug: this pack labels itself "Super alpha - early classroom testing" and says to back up workflows before updating. It's a solo MIT project (Liuboto, v0.1.4) and the interfaces really do move between releases. It's not a DAW - no sampler, no mic input, no file export, no MIDI clock sync yet.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| bpm | FLOAT | 110.0020–300 | — |
| swing | FLOAT | 0.000–0.45 | — |
| clock_nameopt | STRING | local | local preserves an independent clock; project links this controller to the workflow timeline. |
| performanceopt | STRING | {} | — |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| clock | GENERETI_AUDIO_CLOCK | — |
| channels | GENERETI_CHOP | — |
| seconds | FLOAT | — |
| beat | FLOAT | — |
| json | STRING | — |