Music · Lyrics-Prosodie messen
Measure the song text before an LLM tries to imitate it
- prosody_json
- prosody_brief
- report_md
- language
Ask a language model to count syllables and watch it embarrass itself. It's a token machine, not a phonetician - "fire" is one syllable to you and two to half the English-speaking world, and the model will pick whichever keeps the sentence tidy. So if you want a newly written lyric that actually fits the melody of an existing recording, you don't ask it. You measure, and hand it the numbers.
That's this node. It is a pure-text measuring instrument: no audio in, no model, no API. Its obvious job is the front half of a YuE2 cover workflow (measure the original, let an LLM rewrite to the same form, render), but it's quietly useful any time you want a song text as data - section structure, line lengths, which lines rhyme.
What comes out
Four outputs, and the two that matter are the middle ones.
prosody_json- the full measurement as JSON, for a Show Text node or a downstream script.prosody_brief- the compact form target thatFVM_CoverLyricsPromptBuilderexpects. This is the one you wire.report_md- a readable markdown breakdown. This is the one you actually read before trusting the brief.language- the detected language code, handy for feeding the cover node'slanguageinput.
The node reports sections, syllables per line and a rhyme scheme. It deliberately does not report BPM, bars or note values - the module docstring is blunt about this: those come from the audio, not the text. Rhythm lives in the ABC score that the transcription side produces; the syllable profile per line is the text-side counterpart to it.
The prose problem, and the fix
Here's the failure the author documented by hand and it's worth repeating, because it is what you will hit. Both transcribers commonly used in these workflows hand back a paragraph: HeartMuLa returns result["text"], and the Whisper path in comfy_mtb gives you flowing text if you take its string output. Measure a paragraph and you get one line with 239 syllables, which is useless. Measured on a real Toto transcript, that's exactly what happened.
So struktur has three settings:
auto- only segments if the text has no line breaks at all.wie eingegeben- measure only, never guess. Lines are your job.fliesstext segmentieren- let the node break the paragraph up.
The segmentation is clever rather than naive. It looks for recurring word phrases of 3–7 words and uses their occurrences as line anchors - the most frequent long phrase in a song text is the chorus, and its repeats are more reliable line starts than punctuation that transcripts don't have anyway. Then it breaks between anchors on a syllable budget (ziel_silben, default 8, hard stop around 12, because sung lines rarely run longer). Lines that repeat identically get marked [Chorus], the rest [Verse]. The report says plainly that this is an estimate.
The inputs
lyrics is the text. language offers auto, plus de, en, es, fr, it, nl, pt, sv. ziel_silben only applies when segmenting. The one you'll fuss over is struktur, and the honest answer is: if you care about the rhyme scheme, fix the line breaks by hand first and use wie eingegeben. Garbage in, confidently-numeric garbage out.
Install
ComfyUI Manager, search comfyui-fvmtools. Or from a terminal:
cd ComfyUI/custom_nodes
git clone https://github.com/ping1979ping/comfyui-FVMtools
pip install pyphen # optional, but please do it
Restart ComfyUI. The node lives under Add Node → FVMtools/music.
The detail is worth explaining. The node ships two syllable counters: pyphen with real hyphenation dictionaries for German, English, Spanish, French, Italian and Dutch, and a language-agnostic fallback that counts vowel groups and hacks a trailing silent "e". The fallback is decent for a lot of German and English and ragged elsewhere. pyphen isn't in requirements.txt - the pack's only listed deps are the face-tool stack - so if you want honest numbers, install it yourself. Nothing errors if it's missing; you just quietly get the worse counter.
Common issues
language: auto guesses wrong. Auto is a small keyword vote between German and English stopwords. It is not a language detector. Spanish or Swedish text will come back as English. Set language yourself; it matters, because it selects the hyphenation dictionary.
The rhyme scheme looks like nonsense. Either the lines are wrong (see above), or the words are in a language the orthographic rhymer doesn't handle. Rhymes here are matched on spelling from the last vowel group, with y→i, diacritics stripped and silent final e trimmed (time and rhyme both reduce to im). Phoneme-based would be better, and the docstring says why it isn't: the accurate route needs NLTK data or an espeak binary, neither of which ships with ComfyUI.
Every line is one long line. Your transcript is a paragraph. Switch struktur, or fix it upstream - see FVM_WhisperChunksToLyricLines, which uses actual timestamps instead of text heuristics.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| lyrics | STRING | Originaltext, z. B. aus einem Transcriber. | |
| language | COMBO | auto | 9 options: auto, de, en, es, fr, it, +3 |
| struktur | COMBO | auto | auto: segmentiert nur, wenn der Text keine Zeilen hat. |
| ziel_silben | INT | 84–20 | Angestrebte Silben pro Zeile beim Segmentieren. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| prosody_json | STRING | — |
| prosody_brief | STRING | — |
| report_md | STRING | — |
| language | STRING | — |