Satyr Import (MIDI β Plan) π
Write the melody in your DAW, make YuE2 sing it
- abc
- style
- report
- seconds
YuE2 works in two stages: it composes an ABC score - a vocal melody, an instrumental melody, chord symbols, section labels - and then performs that score. The score is an ordinary string input, tokenised verbatim and never validated, which makes it the one piece of YuE2 conditioning you can edit by hand. Satyr Import is how you write it somewhere you can actually hear it: a DAW.
Worth being clear about what this buys. Who sings is decided in the style string - the plan gets no say, and the suite's investigation failed to turn register into a working voice control. What they sing, though, is the tune, and Satyr Import is the only real control over the tune the pack has.
How it works
The node reads the MIDI with mido and turns two parts into the plan's two hardcoded voices, Vocal and Ins. Along the way it does a pile of things you'd otherwise learn about the hard way:
- A part is a channel, not a track. Most MIDI you download - every type-0 export - keeps the whole arrangement in one track and separates the parts by channel. Read that as one line and you hand the melody, the bass, the guitar and the drum kit to the singer at once, and YuE2 sings all of it, at length and with conviction. So channels are split out and named by General MIDI family, and channel 10 is flagged
[drums]and never picked automatically - its note numbers are drum sounds, not pitches. - Notes are quantised onto a grid (
L:in ABC), andautopicks the coarsest grid the music actually fits. A 1/32 grid can write any rhythm and produces a line nobody can check. - A note crossing a barline stays one syllable, spelled as a tie. Get that wrong and the singer is handed a syllable that doesn't exist and every word after it shifts.
- Accidentals hold for the bar, across octaves - after
^F, every F in that measure is sharp, so a later natural has to be written=F. - ABC voices are monophonic, so a chord keeps its top note. A melody under a held pedal tone comes out as the pedal.
- One tempo. A plan carries a single
Q:, so a tempo map collapses to its first value. Same for a metre that changes partway. - MIDI markers become
%section labels - the one place a DAW's arrangement markers carry straight through.
Nothing lossy happens quietly: the report counts what was dropped, what was moved, and how far.
Inputs and outputs you'll actually touch
midi_path- a full path, or just the filename if the file is in ComfyUI'sinputfolder.vocal_track/ins_track- a track name or its number counting from 0. Leave them empty and the node guesses (a name containing vocal, lead or melody wins; otherwise the first part with notes). The report lists every part with its note count and pitch range, so one run tells you what to type. Pointins_trackat nothing and the Ins voice is written as rests, which is perfectly valid.style_prefix- what the MIDI can't know: language, genre, vocal character, mood. The node appends the tempo and the instruments it can read, and hands back one style string. Instruments are ordered by how much each part plays and the list stops at six, because a style naming a dozen things has stopped describing anything.grid-auto/1/4/1/8/1/16/1/32. Set it by hand whenautoreads wrong.
Out comes abc (the plan), style (for the same node's style input), report, and seconds - the plan's own duration, which you wire into the latent-length node so the plan and the latent can never disagree.
MIDI file β Satyr Import β abc β Satyr Trim β Satyr Score β Satyr Music
style β Satyr Music seconds β Empty YuE2 Latent Audio
Since MIDI carries no chord symbols, use mode: melody on the music node - that's what YuE2's own docs recommend for anything built on an existing melody. And run the plan through Satyr Score with your lyrics before rendering: a tune written without the words in mind won't have the right number of notes for them.
Installing it
Search Kinburg-Nodes in ComfyUI Manager, or clone it:
cd ComfyUI/custom_nodes
git clone https://github.com/Kinburg/Kinburg-Nodes
Restart. This node needs mido, which the pack's requirements.txt lists and Manager should install with it. If yours didn't, the node tells you so itself and gives you the fix:
<ComfyUI>/python -m pip install mido
Pure Python, no compiled wheels.
Where people get burned
The headline failure is pointing vocal_track at a whole type-0 file and getting a "vocal" that recites the bass line. The report's warning for this is subtle but real: a part that sounds for almost the whole song without a break is flagged, because a sung line breathes and an arrangement doesn't. Two more things to know: a live take doesn't quantise exactly, and the report says so - 0% average movement is a transcription, 6% is an approximation. And if your track names come back as mojibake, that's MIDI declaring no text encoding.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| midi_path | STRING | A .mid file: a full path, or just the name if it sits in ComfyUI's input folder. What it needs to contain is a melody. Everything else β tempo, time signature, key, and section labels from MIDI markers β is read if present and reported if missing. | |
| vocal_track | STRING | Which track becomes the sung line. A track name, or its number counting from 0. Leave empty and the node guesses: a name containing vocal / lead / melody wins, otherwise the first track with notes. The report lists every track with its note count and pitch range, so one run tells you what to type here. | |
| ins_track | STRING | Which track becomes the instrumental line. Same rules. Leave empty for the first track the vocal did not take; leave it pointing at nothing and the Ins voice is written as rests, which is perfectly valid. | |
| style_prefix | STRING | What the MIDI cannot know, put here: language, genre, vocal character, mood. The node appends what it CAN know β the tempo and the instruments General MIDI names β and hands back one style string. YuE2 asks for 'Language + Genre + Vocal Character + Tempo + Instruments', and a MIDI answers the last two exactly. It has nothing to say about the first three, and guessing them from note data would be making things up. Leave it empty to get the tempo and the band on their own, and join them to your own text however you like. | |
| grid | COMBO | The note grid everything is quantised onto β ABC's L: value. auto picks the coarsest grid the music actually fits, which keeps the plan readable: a 1/32 grid can write any rhythm and produces a line nobody can check. Set it by hand when the guess reads wrong, and read the report either way β it says how far the notes had to move to land on it. A MIDI quantised in a DAW converts exactly. A live take does not, and the report says so rather than pretending. | |
| verbose | BOOLEAN | true | Print the report to the console. The same text is always on the 'report' output. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| abc | STRING | β |
| style | STRING | β |
| report | STRING | β |
| seconds | FLOAT | β |