Nodes/ꘇ Genereti/ꘇ chop.midiin
ComfyUI Node

ꘇ chop.midiin

Your MIDI controller as a ComfyUI control source

By languel·Created about a month ago·Updated 3 days ago· 1
ꘇ chop.midiin
    • channels
    • value
    ◄device►
    ◄channel0►

    A knob on a hardware controller turning a slider inside ComfyUI is the kind of thing people keep asking for in the realtime-visuals threads - TouchDesigner users show up in r/StableDiffusion and r/comfyui threads to explain that this is routine in their world and awkward everywhere else. ꘇ chop.midiin is Genereti's answer: Web MIDI in the browser, values normalized to 0..1, exposed as named CHOP channels and a FLOAT.

    What it is

    The node turns hardware into signal. It's an input in the CHOP family, like ꘇ chop.noise or ꘇ chop.oscillator, except the values come from a physical device instead of math. Insert it where a generator would go and everything downstream - ꘇ chop.select, ꘇ chop.math, ꘇ chop.lfo-style moderation, note channels into a synth - behaves as if you'd written those values by hand.

    It's genuinely niche, and that's your warning shot: this pack is early, the author's own docs say MIDI on physical hardware needs a separate device test, and a corpus search for "genereti" finds nothing at all. Expect to be the person who finds the bug.

    How it works

    Web MIDI, requested from the browser, no SysEx. Press the node's ↔ Connect button and the page asks for MIDI access, then binds to the first available port unless you named one. Nothing at all happens before you press it - the author is explicit that opening or queueing a workflow never performs MIDI I/O, and a queued run of this node returns a zero placeholder rather than a device read.

    Incoming messages become device channels with generated names: control change is ch1.cc7, notes are ch1.note60 (velocity while held, 0 when released), pitch bend is ch1.pitch, channel pressure is ch1.pressure. The ch1 part is the MIDI channel the message arrived on. Control values, pitch bend and pressure are all normalized to 0..1 rather than raw 0..127, which is why a ꘇ chop.math ×127 is a common next step if something downstream wants real MIDI numbers.

    Live blocks run at 60 samples a second, and the node only pushes a new block when a message actually changed something - a revision counter, so an idle controller doesn't spam the graph.

    The inputs and outputs that matter

    • device - a STRING. Empty means "first available port". Anything else is matched against the port's ID or its exact name, so spelling matters; if nothing matches you get "No matching MIDI device. Available: …" in the status line, which is at least a helpful failure.
    • channel - INT, default 0, range 0..16. 0 means accept every channel; 1..16 filters to one. Note the asymmetry with ꘇ chop.midiout, where channel runs 1..16 and means the channel you send on.
    • channels out - the named device channels described above, one sample each. Only channels you've actually touched since connecting exist, so ꘇ chop.select with a pattern like cc7 finds nothing until you move the knob.
    • value out - FLOAT, the last sample of the first channel. Which channel that is depends on which message arrived first, so it is not a stable "the knob" socket. If you're driving one parameter, select the channel explicitly before you hand it to a widget.

    There are no other inputs - no samples, no sample_rate, no time. The node owns its own 60 Hz timeline.

    Install

    Everything in these pages ships in one pack. Manager → search genereti (title "ꘇ Genereti") → install → restart ComfyUI → hard-refresh the browser. 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
    

    Install with your ComfyUI's Python. The requirements file is just comfyui-frontend-package>=1.53.6 - no drivers, no Python MIDI library, because this is the browser's MIDI stack, not a server-side one. Try Workflows → Genereti → ꘇ-OpenTouch-Operators-and-Lessons, which includes user-started MIDI and OSC nodes that stay disconnected until you press Connect.

    Common issues

    "Web MIDI unavailable in this host." Some browsers and embedded webviews don't ship the Web MIDI API at all. Firefox historically needed a flag; Safari and Chromium-based browsers are the safer bet. The node reports the limitation instead of failing silently.

    MIDI works, your hardware might not. The docs are honest that physical MIDI hardware needs a separate device test and that the protocol has mostly been exercised with virtual ports. If a USB controller with a wonky driver misbehaves, that's unexplored territory, not a documented bug.

    Values are 0..1, not 0..127. Everything is normalized on the way in. Multiply or fit before you feed a parameter that expects MIDI units.

    Close the browser tab and the port goes. Disconnecting ends the MIDI session; the node clears its device channels and waits for another Connect. And a queued workflow returns zeros for this node - by design, so batch runs are reproducible.

    It's an alpha. Super alpha, early classroom testing, per the README. Back up workflows before updating.

    CategoryGenereti / CHOP

    Inputs (2)

    NameTypeDefaultDescription
    deviceSTRING—
    channelINT00–16—

    Outputs (2)

    NameTypeDescription
    channelsGENERETI_CHOP—
    valueFLOAT—