Score Performer
Making Robot Music Sound Played by a Person
- score
- performance
- midi_url
A score is a recipe, not a meal. Played back literally, the notes come out quantized and lifeless - the MIDI-perfect piano sound that makes synth music obviously synthetic. Score Performer (ComfyTV.ScoreToMidiStage) is the node that fixes that by deciding how the notes get played: it takes a score and returns a performance - the same notes, humanized, swung, and phrased - plus a downloadable MIDI file.
Under ComfyTV/Music, it's the second stop in the composition → performance → synthesis chain (Score → Score Performer → Score Synth). Feed it the score output from Score or Score Editor and it gives back two outputs: performance (COMFYTV_TEXT - the performance data the synth stage consumes) and midi_url (COMFYTV_TEXT - a link to the rendered Standard MIDI File you can download and drop into a real DAW).
The knobs that make it sound human
These are the parameters worth understanding, because "humanize" is usually a marketing word and here it's a set of real levers:
swing_ratio(50–75, default 50) - how much swing, withswing_unitchoosing whether it applies toeighthorsixteenthnotes. 50 is straight; 65+ is where it starts to groove.humanize(0–1, default 0) - timing/velocity variation. This is the "played by a person" knob; even 0.05-0.1 of slop removes the machine-gun feel.easing-normal,ease_in,ease_out,ease_in_out,exponential. Note-level phrasing, i.e. how each note attacks and decays toward its neighbors.profile-keyboard,strings,winds,voice,percussion. Instrument-appropriate behavior; a strings profile should not phrase like a percussion one.seed- reproducible variation. Same seed, same performance, which is huge when you're iterating on a score and don't want the humanization to jump around every Run.
The internal force_run_token/project_id/parent_output_id fields are ComfyTV project plumbing - ignore them.
The honest caveat
The heavy "make it sound real" lifting happens downstream in Score Synth (a real SoundFont with actual instrument samples). Performer gives you humanized note timing and phrasing; it won't rescue a bad arrangement. Start conservative - humanize 0.1, no swing - then push the sliders until it stops sounding like a player piano.
Install
Ships with ComfyTV:
cd ComfyUI/custom_nodes
git clone https://github.com/jtydhr88/ComfyTV
Restart ComfyUI; look under ComfyTV → Music. ComfyUI Manager: search "ComfyTV". Desktop/macOS users should clone into the running instance's absolute custom_nodes path (from the startup log), watch for a nested ComfyTV/ComfyTV/ folder, and fully restart the backend. No models, no extra dependencies.
Troubleshooting
- "Score Performer needs a score - wire the Score stage." You ran it with no
scorewired. Connect Score or Score Editor first. - MIDI download is empty or missing. The
midi_urloutput only appears once the performance renders; if you changedseedand got the same file, you haven't Run since - re-run the stage.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| force_run_token | INT | 00–2147483647 | Internal — bumped on Run to invalidate ComfyUI's input cache. |
| project_id | STRING | Internal — populated by the projectStore on the frontend. | |
| parent_output_id | INT | 00–2147483647 | Internal — lineage parent set by spawn handlers on the frontend. |
| swing_ratio | FLOAT | 5050–75 | — |
| swing_unit | COMBO | eighth | 2 options: eighth, sixteenth |
| humanize | FLOAT | 0.000–1 | — |
| easing | COMBO | normal | 5 options: normal, ease_in, ease_out, ease_in_out, exponential |
| profile | COMBO | keyboard | 5 options: keyboard, strings, winds, voice, percussion |
| seed | INT | 70–99999 | — |
| scoreopt | COMFYTV_TEXT | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| performance | COMFYTV_TEXT | — |
| midi_url | COMFYTV_TEXT | — |