Music · Verlaengern 3 · Plan
The LLM picks notes, the song picks everything else
- system_prompt
- user_prompt
- plan_json
- needs_llm
Step 3 of 6 (Plan), and it's where the interesting decision lives. This node decides what gets appended - new material, a variation, or a straight repeat - and builds the prompts that make an LLM do it.
The design bet is worth spelling out, because it's why this works at all. A language model is bad at rhythm. Ask it for bars and note lengths and you get something that composes fine on paper and lands nowhere near the beat. So this node does the opposite: it reads the rhythm out of the song - the bar structure, how many notes per bar in each voice, the vocal's range, the chords in use - and asks the LLM for pitches and chords only, as one strict JSON object. Notes in scientific pitch notation (Ab4, C#5), one list per bar, exactly as many as the template says. The rhythm template enforces the shape; the model just chooses the notes.
The system prompt tells it to stay in the song's key and range, prefer stepwise motion with a few leaps, land on chord tones on strong beats, and give the melody a hook. If the song has no vocal line - the vocal voice is silent, it's an instrumental - it says so and names which voice actually carries the melody, so the model doesn't write a lead part for a singer who isn't there.
The three modes
- LLM: neuer Abschnitt - new melody and chords, riding the rhythm of the last section with the same label. Section labels auto-progress if you leave
section_labelonauto: intro→verse, verse→chorus, pre-chorus→chorus, chorus→verse, bridge/solo→chorus, breakdown→build-up, build-up→chorus. Set a label explicitly to force it. - LLM: Variation - takes the sections named in
source_sections(last,last2,chorus,3,2-4- 1-based) and varies them: keep the chords, keep the outline recognisable, change the pitches clearly. - Loop: Abschnitte wiederholen - no LLM at all. Repeat
source_sections, re-rendered by YuE2. This is the mode for a second chorus you want played identically.
needs_llm comes out as a boolean precisely for the third case. Wire it to a switch or a condition and the LLM node never runs in Loop mode - the Apply node below knows to skip it too.
sections_to_add is 1–4 sections per run. bars_per_section at 0 means "as long as the last section with this label", which is almost always what you want. instructions is free direction for the model - "build it up, hook in the high register" - and it's the cheapest quality lever in the chain.
The overlap, which is the actual trick
overlap_sections decides how many sections from the end of the existing song get re-rendered along with the new material. Leave it at 0 and the node computes it: as many sections as it takes to reach at least 22 seconds.
That's not a fudge factor. YuE2 ramps up at the start of a render - the source comments describe it opening like an intro - and lands like an ending at the close. So the overlap is not padding, it's the anchor: the commit step finds the best matching point inside the overlap and cuts there, and both the render's fake intro and the faked ending get thrown away. Short overlaps make that impossible, which is why the minimum is enforced.
Inputs, outputs, install
Required: session_json and full_abc (both forced inputs from the Session node), plus the seven widgets above. Outputs: system_prompt, user_prompt, plan_json, needs_llm - the first two go into your LLM chat node, plan_json goes into FVM_SongExtendApply, needs_llm to whatever gates the LLM.
Install via ComfyUI Manager (search comfyui-fvmtools) or:
cd ComfyUI/custom_nodes
git clone https://github.com/ping1979ping/comfyui-FVMtools
Restart, look under Add Node → FVMtools/music/extend. No extra dependencies; the LLM is whatever local chat node you already run.
Common issues
The LLM padded every bar with the wrong number of notes. It didn't - Apply repairs bars that don't match the template and reports how many it fixed. If it's repairing a lot, your model is ignoring the structure instruction; try a more obedient small model rather than a reasoning one, which tends to leak its deliberations into the JSON.
source_sections did nothing. It only applies in Variation and Loop mode. In "neuer Abschnitt" the template comes from the last section with the chosen label.
The instructions field is being ignored. Check the model's actual reply in the console. Vague direction from a 3B model produces vague pitches regardless of what the prompt asked for.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| session_json | STRING | — | |
| full_abc | STRING | — | |
| mode | COMBO | LLM: neuer Abschnitt | LLM neu: neue Melodie/Akkorde ueber den Rhythmus des letzten Abschnitts mit gleichem Label. LLM Variation: variiert source_sections. Loop: wiederholt source_sections ohne LLM (wird neu eingespielt). Rhythmus und Taktlaengen kommen immer aus dem Song - das LLM waehlt nur Toene. |
| sections_to_add | INT | 11–4 | Abschnitte pro Queue-Lauf (bei Loop: Wiederholungen). |
| section_label | COMBO | auto | 9 options: auto, verse, chorus, pre-chorus, bridge, solo, +3 |
| bars_per_section | INT | 00–32 | 0 = wie der letzte Abschnitt mit diesem Label. |
| source_sections | STRING | last | Fuer Loop/Variation: last, last2, chorus, 3, 2-4 (1-basiert). |
| instructions | STRING | Freie Regie fuer das LLM, z. B. 'steigern, Hook im hohen Register'. | |
| overlap_sections | INT | 00–3 | So viele Abschnitte des bisherigen Endes werden mitgerendert (Anker fuer die Ausrichtung). 0 = automatisch, mindestens 22 s - YuE2 braucht am Render-Anfang Anlauf. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| system_prompt | STRING | — |
| user_prompt | STRING | — |
| plan_json | STRING | — |
| needs_llm | BOOLEAN | — |