Skip to main content
The chain at a glance (ComfyTV / Music + ComfyTV / Audio):
Three words, each owning one part of the chain:

Stop 1: Where scores come from — MusicXML

MusicXML is the universal interchange format for sheet music — MuseScore, Finale, and Sibelius all export it. It describes “which notes in which measure, what duration, what articulation” as text. A minimal usable score:
Three fields are enough to read it:
  • divisions — how many ticks one quarter note is split into; every duration is counted in those ticks (above, divisions=2, so duration=2 is a quarter note);
  • step + octave (+ optional alter) — note name + octave + accidental (alter=1 sharp, -1 flat);
  • measure — a bar; multiple staves (left/right hand) are multiple <part> elements.

Route one: ask an LLM

The Score node is forgiving: paste the LLM’s entire answer as-is — it extracts the <score-partwise>…</score-partwise> block out of the surrounding prose automatically. Prompt template:
Write an 8-bar C-major piano solo in MusicXML (score-partwise 4.0), 4/4 time, tempo 100, right-hand melody plus left-hand block chords, two parts. Only correctness of the notes matters; no layout information needed.
Two voices, a specific chord progression, dynamics (<dynamics>), hairpins (<wedge>), staccato (<articulations>) — just ask for them in the prompt. The parser reads those markings, and the performance stage actually plays them.

Route two: draw it yourself — Score Editor

The Score Editor node is a piano roll on the canvas — no XML required:
  • Three input styles: draw (press and drag out a note), select (marquee, move, resize both edges), and step input (MuseScore-style: A–G enters pitches, 7–2 picks durations, . dots, 0/space rests, the cursor advances automatically — typing a melody is an order of magnitude faster than clicking)
  • Up to 4 parts, each with its own instrument (a GM program written into the score — Score Synth picks it up automatically) or flagged as a drum part (the sidebar switches to GM drum names; paint Kick/Snare/HH directly)
  • Velocity lane: paint per-note loudness under the grid, DAW-style — it carries through to the final performance
  • Playback: ▶ auditions the draft right in the editor (per-part waveforms, synthesized drums); the real timbres come from the proper chain once you Run
  • Outputs standard MusicXML — wire to Score for engraving or Score Performer → Score Synth for the finished audio; an upstream score (LLM-written or downloaded) can also be imported into the roll for editing

Route three: public downloads

Note: download the uncompressed .musicxml / .xml variant; .mxl is a zip archive — extract the XML from it first.

Stop 2: Score

Paste MusicXML into the node (or wire an upstream LLM text node into text). It does three things:
  1. Validates and cleans — parse failures raise a clear error instead of letting a broken score flow downstream;
  2. Engraves the score — the node card renders the full multi-stave score (percussion staff included), zoomable, with an editable XML panel that re-engraves live;
  3. Outputs the cleaned score text for the rest of the chain.
There are no performance parameters — the score is the “facts”; everything after this changes how it’s played, never what’s written.

Stop 3: Score Performer

A score says which notes; MIDI events say when and how loudly they’re struck. Playing the score back mechanically is what people call “robotic MIDI”; a human performance differs in articulation (actual note lengths), dynamic curves (how crescendos travel), and tiny timing deviations. This node ports MuseScore’s performance rules and applies every staccato / tenuto / accent / dynamic / hairpin / trill / grace-note marking in the score. Two outputs: performance (performance JSON — tempo map + event stream, wire to Score Synth) and midi_url (a standard .mid file you can download straight into any DAW).
💡 Changing Performer parameters does not change the engraved score downstream — the engraving shows the score, not the performance. To hear the difference, re-Run the Score Synth.

Stop 4: Score Synth

Performance events need a sound. That’s a SoundFont (.sf2 / .sf3) — a sampled instrument library organized by the General MIDI standard’s 128 programs. The free FluidR3_GM covers all of GM; import the file via the sidebar under Resources → soundfont. The card engraves the full score and, during playback, the cursor follows the music note by note — including repeats and first/second endings. The output is standard audio: chain any Audio node after it, or feed it into a Video Stage’s audio input to drive audio-to-video generation.

Stop 5: Mixing — Muse Reverb (FDN)

Dry synthesized audio sits “right in your face”; reverb puts it in a room. Physically there are three layers: direct sound (dry) → early reflections (the first bounces off the walls — your instinct for “how big is this room”) → late reverb (the dense tail — “how wet”). This node is the same FDN (feedback delay network) algorithm as MuseScore’s reverb. Three starting points:

Stop 6: Beyond — the rest of the audio toolbox

The synth output is a standard audio track; the whole ComfyTV / Audio toolbox chains after it:

Full example 1: playing Für Elise

  1. Download a public-domain MusicXML (e.g. Für Elise on abcnotation) and paste it into Score;
  2. Score Performer: profile = keyboard, humanize = 0.25, rest default;
  3. Score Synth: pick FluidR3 as the soundfont, program = piano, hit Run, watch the cursor follow the score during playback;
  4. Muse Reverb: use the “concert hall” preset above. Done.

Full example 2: an LLM-written jazz sketch

  1. Use the Stop-1 prompt template, asking explicitly for two parts: “D minor, swung, 8 bars; Part 1 is the right-hand melody, Part 2 is left-hand accompaniment chords (one or two per bar)”. Paste into Score;
  2. Score Performer: swing_ratio = 63, profile = keyboard, humanize = 0.3;
  3. Score Synth: give the two parts different instruments in channel_programs — ch 0 = piano (melody), ch 1 = e_piano or jazz_guitar (comping);
  4. Muse Reverb (“room” preset) → done.