MIDI Feature Extractor β‘π ‘π π £π
Turn a MIDI track into a reactive signal
- midi
- midi
- feature
- frame_count
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) - fromMIDILoaderor another node in the pack that outputsMIDI.extraction_method- which dimension of the performance to extract (see above).frame_rate(default 30) andframe_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.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| extraction_method | COMBO | Choose 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_rate | FLOAT | 30.01β120 | Frame rate of the video (1.0 to 120.0 fps) |
| frame_count | INT | 0 | Total number of frames (minimum: 1) |
| width | INT | 51264β4096 | Width of the output feature (64 to 4096) |
| height | INT | 51264β4096 | Height of the output feature (64 to 4096) |
| midi | MIDI | β | |
| chord_only | BOOLEAN | false | When true, only considers full chords (default: false) |
| notes | STRING | Comma-separated list of MIDI note numbers (default: empty) |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| midi | MIDI | β |
| feature | FEATURE | β |
| frame_count | INT | β |