ComfyUI Node

Fit Lyrics

The syllable bouncer between your words and the melody

By jplenio·Created about a month ago·Updated about 17 hours ago· 96
Fit Lyrics
  • brief
  • state
  • lyrics
  • prompt
  • schema
  • state
  • report
◄lyrics—►
◄lastfalse►
◄score—►
◄reference_lyrics—►
◄answer—►

Making a cover with new lyrics has one job that the music model can't do for you: the new words have to be singable on the notes that already exist. A writer model will happily hand you a lovely line with eleven syllables that has to land on four notes, and then everything downstream is a mess. Fit Lyrics is the node that measures the line against its phrase and sends it back.

You only need it on the new-lyrics cover path. A new song, a cover that keeps the original words, and an instrumental all pass through this node untouched - so if you see it in a template and you're not covering anything with fresh words, it's doing nothing, on purpose.

How it works

The node reads the score's Vocal phrases and treats each phrase's notes as a syllable budget: roughly one syllable per note, with one or two fewer than the notes being fine, since those get sung as a melisma (one syllable stretched across several notes - normal singing, not an error). Every line is checked against the notes of the phrase it sits on.

Lines that don't fit go back to the writer with their targets spelled out, and only those lines - the ones that already work aren't touched. That's capped at two rounds, which is why the pack chains three of these nodes with a writer between them: the first checks and complains, a writer answers, the second merges and re-checks, the third has last on and asks nobody anything - it just shortens what's still one or two syllables too long, mechanically (I am → I'm).

The lazy wiring is the part that earns its keep. When the lyrics already fit, the answer input is never resolved, so no writer call happens at all. Same story for reference_lyrics: it's only requested when the brief tells the cover to stay close to the original words, because meaning-matching is pointless otherwise.

Inputs and outputs

  • lyrics - the words to fit: Parse Song Draft's output, or the previous Fit Lyrics round's.
  • brief - Song Brief or Cover Brief. Only new cover lyrics get fitted; everything else skips.
  • last - the switch that makes this node the final round: no more writer, just shorten.
  • score - optional but essential in practice; its Vocal phrases are the targets.
  • reference_lyrics - the source's transcribed words, when the brief keeps close to them.
  • state and answer - the round-to-round handoff: what the previous node asked the writer, and the writer's reply.

Outputs: lyrics into the next round (or into the Song Sheet), prompt as the repair request for the writer - empty when the lyrics fit or when it's the last round - and schema to hold a Local LLM to the answer's exact format. state carries forward, and report gives you the honest ledger: which lines fit, what was asked, what changed.

Installing it

Same pack, same nothing-else-to-install. Plenio's requirements.txt is empty by design; the only optional pip line anywhere in it is faster-whisper, and that's for transcribing a cover's source vocals, not for this node.

cd ComfyUI/custom_nodes
git clone https://github.com/jplenio/Plenio-Music-Production-System

Or ComfyUI Manager → Custom Nodes Manager → Plenio Music Production System, or comfy node install comfyui-plenio-music. Restart ComfyUI and run 0 · System Check once. ComfyUI 0.37.0 or newer is required - this pack is built on the native YuE2, SheetSage2 and MiniMax nodes rather than reimplementing them.

When it misbehaves

If nothing gets fitted, check the cheap things first: it's a Cover Brief, it writes new lyrics, it isn't marked instrumental, and a score is connected. Any of those missing is a clean pass-through, not a failure.

The answer was cut off class of problem in a covering workflow usually comes from the transcription side rather than here - if the source's words weren't found, the brief's lyrics closeness and phrasing reference are asking for something that doesn't exist. Set lyrics closeness to 0 and the phrasing reference off, or trim the source to its sung part.

And don't expect this node to fail loudly. If the fitting code itself throws, the lyrics are used exactly as written - you'd get a melisma or a squeezed syllable where a line doesn't fit - with the reason in the report and the traceback in the console. The run keeps going, which is the right call for a graph that's already half an hour into rendering a song.

CategoryPlenio/Writing

Inputs (7)

NameTypeDefaultDescription
lyricsSTRINGThe lyrics: Parse Song Draft's, or the previous Fit Lyrics'.
briefPLENIO_BRIEFSong Brief or Cover Brief: only new cover lyrics are fitted.
lastBOOLEANfalseThe last round: asks the writer nothing more; shortens lines one or two syllables too long.
scoreoptSTRINGThe final score: its Vocal phrases are the targets.
reference_lyricsoptSTRINGThe source's lyrics (Transcribe Lyrics), for the meaning when the brief keeps close to them; requested only then.
stateoptPLENIO_LYRICS_FITThe previous Fit Lyrics' state: what it asked the writer.
answeroptSTRINGThe writer's answer to the previous Fit Lyrics' prompt; requested only when it asked.

Outputs (5)

NameTypeDescription
lyricsSTRINGThe lyrics after this round.
promptSTRINGThe repair request for the writer (empty when the lyrics fit or in the last round).
schemaSTRINGThe answer's JSON schema, for Local LLM (the format is then exact).
statePLENIO_LYRICS_FITFor the next Fit Lyrics.
reportPLENIO_REPORTLines that fit, what was asked and changed.