Nodes/RyanOnTheInside/MIDI Feature Extractor βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜
ComfyUI Node

MIDI Feature Extractor βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜

Turn a MIDI track into a reactive signal

By ryanontheinsideΒ·Created 2 years agoΒ·Updated 5 months agoΒ· 852
MIDI Feature Extractor βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜
  • midi
  • midi
  • feature
  • frame_count
β—„extraction_methodβ–Ύβ–Ί
β—„frame_rate30.0β–Ί
β—„frame_count0β–Ί
β—„width512β–Ί
β—„height512β–Ί
β—„chord_onlyfalseβ–Ί
β—„notesβ–Ί

RyanOnTheInside's whole pitch is "everything-reactivity" - audio, MIDI, motion, proximity, whatever you've got, turned into a signal something else can react to. This is the MIDI half of that: it takes a loaded MIDI file (from this pack's MIDILoader, not a raw audio file - MIDI and audio are different worlds here) and extracts one specific dimension of it into a per-frame FEATURE you can wire into any of the pack's Flex targets.

Why MIDI instead of just analyzing the audio

Audio-reactive effects have to infer things - was that a beat, how loud was it, roughly what pitch. MIDI already knows. It's the actual performance data: exact note timings, exact velocities, exact pitch-wheel and modulation-wheel movements, recorded at the source rather than reverse-engineered from a waveform. If you have the MIDI file behind your music (or you're generating visuals to sync with a MIDI performance directly), this node gets you a cleaner, more precise signal than audio analysis ever could.

How it works

extraction_method is a long dropdown - 16 options - grouped into a few families. Note-level data: Velocity (how hard a note was hit, great for impact effects), Pitch, Note On/Off (precise timing triggers), Note Duration, Note Density (how many notes are active - a proxy for musical complexity). Expression data: Pitchbend, Aftertouch, Poly Pressure. And a full set of MIDI CC channels - Modulation (CC1), Breath (CC2), Foot Controller (CC4), Volume (CC7), Balance (CC8), Pan (CC10), Expression (CC11), Sustain (CC64) - for whenever the source performance was recorded with a controller riding one of those. chord_only narrows extraction to moments where a full chord is present rather than any single note, and notes lets you filter to a comma-separated list of specific MIDI note numbers if you only care about, say, the bassline.

Like the pack's other feature extractors, frame_count at 0 auto-calculates the frame count from the MIDI and your frame_rate; set it explicitly and the extracted feature gets interpolated to that target length instead.

The inputs and outputs that matter

  • midi (required, MIDI) - from MIDILoader or another node in the pack that outputs MIDI.
  • extraction_method - which dimension of the performance to extract (see above).
  • frame_rate (default 30) and frame_count (default 0, auto) - how the note-event timeline maps onto video frames.
  • chord_only / notes - narrow which notes count.
  • width/height - sizes the internal feature tensor; match your pipeline's resolution.

Outputs: midi (passthrough, so you can keep chaining without re-loading), feature (FEATURE, wire into any Flex target's reactive input, or into FeatureToMask if you just want a plain mask), and frame_count (INT) for reuse downstream.

How to install it

ComfyUI Manager: search "RyanOnTheInside", install, restart. Manually:

cd ComfyUI/custom_nodes
git clone https://github.com/ryanontheinside/ComfyUI_RyanOnTheInside
cd ComfyUI_RyanOnTheInside
pip install -r requirements.txt

then restart. MIDI parsing in this pack runs on mido, pinned in requirements.txt - a real, lightweight dependency, not a heavy ML model, so there's nothing to download here.

Common issues & troubleshooting

Feature is flat/empty. The most common cause is picking a CC-based method (say, Sustain (CC64)) for a MIDI file that never actually uses that controller - not every recorded performance touches every CC. Check your source MIDI in a piano-roll editor first if a channel you picked looks suspiciously flat.

Wired in audio instead of MIDI. This node's midi input is strictly the MIDI type - a raw AUDIO waveform won't connect. If you don't have a MIDI file, you want AudioFeatureExtractor or RhythmFeatureExtractor instead, which work directly off audio.

notes filter seems to do nothing. It expects literal MIDI note numbers (comma-separated), not note names like "C4" - double check you're passing numbers, not letters.

CategoryRyanOnTheInside/Audio/Features

Inputs (8)

NameTypeDefaultDescription
extraction_methodCOMBOChoose what MIDI information to analyze: - Velocity: How hard notes are played - great for impact-based effects - Pitch: Which notes are being played - good for melody-following effects - Note On/Off: When notes start/stop - perfect for precise timing - Note Duration: How long notes are held - use for sustained effects - Note Density: How many notes are playing - good for complexity-based effects - Pitchbend: Pitch wheel movements - great for smooth transitions - Aftertouch: Key pressure changes - useful for pressure-sensitive effects - Poly Pressure: Per-note pressure - detailed expression control - Modulation (CC1): Mod wheel - typically used for vibrato/intensity - Breath (CC2): Breath controller - good for wind instrument effects - Foot Controller (CC4): Foot pedal - useful for gradual changes - Volume (CC7): Channel volume - overall level control - Balance (CC8): Stereo balance - left/right positioning - Pan (CC10): Stereo panning - spatial movement - Expression (CC11): Expression control - dynamic volume changes - Sustain (CC64): Sustain pedal - on/off state
frame_rateFLOAT30.01–120Frame rate of the video (1.0 to 120.0 fps)
frame_countINT0Total number of frames (minimum: 1)
widthINT51264–4096Width of the output feature (64 to 4096)
heightINT51264–4096Height of the output feature (64 to 4096)
midiMIDIβ€”
chord_onlyBOOLEANfalseWhen true, only considers full chords (default: false)
notesSTRINGComma-separated list of MIDI note numbers (default: empty)

Outputs (3)

NameTypeDescription
midiMIDIβ€”
featureFEATUREβ€”
frame_countINTβ€”