Nodes/ComfyUI MIDI Edit/MIDI Edit Lyrics
ComfyUI Node

MIDI Edit Lyrics

Swap the words in a song and keep the tune — the lyric-mashup node at the heart of this pack

By ahkimkoo·Created 3 months ago·Updated about a month ago· 5
MIDI Edit Lyrics
    • midi_json
    midi_json
    new_lyrics
    force_tone4false
    high_pitch_threshold79
    fixed_pausetrue
    split_modetoken
    speed1.0

    This is the node the whole pack is named after. You've got a song as MIDI JSON - either transcribed with MIDI Transcribe Audio or handed to you - and you want it to sing different words. A 魔改歌词 job, in the project's own words. Feed it the new lyrics and it swaps them in, regenerating the phonemes so the synthesizer can actually pronounce the new text, while leaving the melody alone. It handles Mandarin (zh_ pinyin), English (en_ ARPAbet word-level phonemes), Cantonese, and mixed lyrics. Pitch, duration, and f0 stay untouched unless you ask for a speed change.

    How it works

    The matching logic is where the cleverness lives. New lyrics get split into sentences by newlines and punctuation, and each sentence maps to an original section (a <SP>-separated chunk). When the sentence count doesn't match the section count, characters get allocated by proportion - token count or duration, your call - with the CT-Transformer model suggesting AI cut points, and a hard cut if the AI cut is off by more than 15%.

    Inside a section, three modes kick in automatically:

    • Collapse - new text is shorter. Characters right-align onto the existing slots, and the ending long notes are protected.
    • Collapse+Distribute - more characters than slots but not more than tokens. Multiple characters share a slot; the classic case is the original's held-note repeats (天天把它).
    • Expand - new text is longer than the tokens. The longest-duration token gets split in half (duration halved, pitch unchanged) to make room.

    Original repeated characters like 天 天 collapse into one slot and then re-expand to however many copies your new character needs. Every replaced character gets phonemes generated for it automatically.

    Inputs

    Most of these have sane defaults, so the real workflow is "type lyrics, hit run":

    • midi_json - the track JSON string from transcription.
    • new_lyrics - your replacement text (multiline).
    • force_tone4 (default OFF) - force high notes to the fourth tone. Turn it on if a high note keeps coming out wrong.
    • high_pitch_threshold (default 79 = G5) - the MIDI pitch above which tone-4 forcing applies.
    • fixed_pause (default Fixed) - Fixed keeps <SP> pause durations untouched; Flexible lets overly long pauses donate time to crowded tokens.
    • split_mode - token or duration, deciding how characters are allocated to sections when counts mismatch.
    • speed (0.1–3.0, default 1.0) - scales durations and resamples f0 proportionally.

    The output is midi_json, ready to hand to MIDI Synthesize Audio.

    Install, and the good news about models

    This node - and the other lyrics-editing nodes - need no manual model downloads. No multi-GB bundles. A few small things auto-download on first use: g2pM to ~/.g2pM/, NLTK data to ComfyUI/models/nltk/, and the CT-Transformer punctuation model (~270 MB) to ComfyUI/models/ct-transformer-punc/ the first time smart sentence splitting runs. If you only ever edit lyrics, you can install the pack and skip the SoulX models entirely.

    Install via ComfyUI Manager (search "ComfyUI MIDI Edit") or manually:

    cd ComfyUI/custom_nodes
    git clone --recursive https://github.com/ahkimkoo/ComfyUI-MIDI-Edit.git
    pip install -r requirements.txt
    

    The --recursive matters even for the lyric nodes: the pack vendors SoulX-Singer as a git submodule, and a plain clone leaves SoulX-Singer/ empty, which breaks the pack's import. If you already cloned without it, run git submodule update --init --recursive inside the folder.

    When to pick the other node

    Edit Lyrics is the conservative path: it preserves the original phrasing and SP structure, which makes it great for edits that roughly fit the song. If your new lyric has a completely different sentence structure and you want pauses rebuilt around your text, this is where you'd switch to MIDI Lyrics Alignment instead. And if you see "Invalid MIDI JSON input" errors, you're feeding it something that isn't the pack's JSON format - check the track object shape before blaming the lyrics.

    CategoryMIDI-Edit

    Inputs (7)

    NameTypeDefaultDescription
    midi_jsonSTRING
    new_lyricsSTRING
    force_tone4BOOLEANfalse
    high_pitch_thresholdINT790–127
    fixed_pauseBOOLEANtrue
    split_modeCOMBOtoken2 options: token, duration
    speedFLOAT1.00.1–3

    Outputs (1)

    NameTypeDescription
    midi_jsonSTRING