Nodes/ꘇ Genereti/ꘇ chop.midiout
ComfyUI Node

ꘇ chop.midiout

Send a signal back out to your synth or DAW

By languel·Created about a month ago·Updated 3 days ago· 1
ꘇ chop.midiout
  • input
  • channels
  • value
◄device►
◄message▾►
◄channel1►
◄number1►

ꘇ chop.midiout is the only node in the CHOP family whose job is to leave ComfyUI. Point it at a MIDI port, choose CC, note or pitch bend, and it turns the last value of your signal into bytes on the wire. Everything upstream stays the same - an LFO drives a knob on a hardware synth, a sequencer drives notes, a band level drives a filter sweep.

What it is

The modular-audio KB entry makes the general point that audio in ComfyUI is "a layer that got bolted on" once silent clips needed soundtracks: real models, bespoke node packs, and a lot of head-scratching about what a wire is even supposed to carry. Genereti's answer is deliberately unglamorous - CHOP channels carry control values, and MIDI Out is one of the exits. It isn't a DAW clock, it isn't MPE, and it doesn't move audio samples. It sends the latest control values at up to 30 Hz, which is the right frame for knobs and notes and the wrong frame for anything sample-accurate.

For the record on how obscure this is: searching the reddit corpus for "genereti" returns zero threads. There's no crowd-sourced troubleshooting for this node. The docs and the source are all you get.

How it works

input passes straight through to the outputs - the node is a tap, not a transformer, so you can chain it mid-signal without breaking anything downstream. It's also registered as an output node, meaning it executes even if nothing consumes it, which is what you want for a device endpoint.

The sending logic then depends on message. In cc mode it takes the last sample of the first channel, clamps it to 0..1, and sends [0xB0 | (channel-1), number, round(value*127)]. In pitch mode the same normalized value becomes a 14-bit bend. In note mode it looks for musical data first: if the block has a note channel (or anything named like note60), it uses that pitch, and gate-above-0.5 becomes the note-on velocity, with 0 sending a note-off. Only if there's no note channel does it fall back to the normalized first sample plus the number widget.

Two pieces of hygiene built in: identical byte sequences are suppressed (so a held value doesn't machine-gun the port), and when the pitch changes, when you pause the node, or when the port disconnects, the previously held note gets an explicit note-off. Half the reason people fear MIDI-out nodes in a live tool is stuck notes, so that matters.

Connecting is manual, always. Press ↔ Connect on the node, pick an output port; empty device name means the first one available. Opening or queueing a workflow never touches a device, and a queued run passes the block through without sending anything at all.

The inputs and outputs that matter

  • input - the GENERETI_CHOP you're transmitting.
  • device - STRING; empty selects the first output port, otherwise matched by port id or exact name.
  • message - cc, note, or pitch.
  • channel - INT 1..16, the channel you send on (note the flip from MIDI In, where channel = 0 means "any").
  • number - INT 0..127. This is the CC controller number or the fallback MIDI note; it's ignored in note mode when the block carries real note channels.
  • channels / value out - the untouched input block and its first channel's last sample. Wire them onwards if you're also driving visuals from the same signal.

Install

One pack covers every operator in these pages. Manager → search genereti (title "ꘇ Genereti") → install → restart ComfyUI → hard-refresh the browser tab. Manual:

cd ComfyUI
git clone https://github.com/languel/genereti.git custom_nodes/genereti
./.venv/bin/python -m pip install -r custom_nodes/genereti/requirements.txt

Use your ComfyUI's own Python for that pip step. Requirements are a single frontend pin (comfyui-frontend-package>=1.53.6) - Web MIDI comes from the browser, so there's no Python MIDI library and nothing to download. Related workflows to open: ꘇ-OpenTouch-Operators-and-Lessons, ꘇ-Modular-Audio, ꘇ-Sound-Analysis.

Common issues

Nothing is transmitted until you Connect. The button is the whole permission model. A queued graph prints no error and sends no bytes - that's the documented contract, not a bug, so don't debug your signal chain when you've simply not connected.

No SysEx, ever. The request is made with SysEx disabled and nothing in the node builds SysEx messages. Devices that need a SysEx "live mode" handshake won't cooperate.

Note mode needs note channels, not a pitch number. If your block carries only a scalar, note mode falls back to the first sample mapped 0..1 against the number widget - which produces one repeated pitch and a very confused-looking MIDI monitor. Feed it chop.sequencer, chop.arpeggiator or chop.note output instead.

30 Hz with one request in flight. Sends are throttled and skipped while a previous request is outstanding, so fast automation arrives as the latest value rather than a dense stream. Browser background throttling can stretch that further; put the tab in the background and your rhythm will suffer.

Alpha, and honest about it. The README labels the whole pack super alpha with early classroom testing, and the docs say physical MIDI hardware still needs a separate device test. Back up your workflows before updating the pack.

CategoryGenereti / CHOP

Inputs (5)

NameTypeDefaultDescription
inputGENERETI_CHOP—
deviceSTRING—
messageCOMBO3 options: cc, note, pitch
channelINT11–16—
numberINT10–127—

Outputs (2)

NameTypeDescription
channelsGENERETI_CHOP—
valueFLOAT—