{"id": "c7d2e4a1-8b3f-4e6d-a1c9-gmanski-voicesing", "revision": 0, "last_node_id": 6, "last_link_id": 4, "nodes": [{"id": 1, "type": "MarkdownNote", "pos": [-900, -300], "size": [460, 820], "flags": {}, "order": 0, "mode": 0, "inputs": [], "outputs": [], "properties": {"Node name for S&R": "MarkdownNote"}, "widgets_values": ["## Gmanski Voice Clone (Sing)\n\n**Any song, sung in your voice.** The lead vocal is split from the music (Demucs), re-sung in the voice of your\nsample (SoulX-Singer SVC, Apache 2.0) and mixed back. Melody, timing and the backing track stay the same.\n\n### Run it\n1. **Song**: a finished track (vocal + music) or a dry vocal. One lead singer works best; heavy harmonies blur.\n2. **Voice sample**: 5-20 s of the target voice, speaking or singing, no music.\n3. Queue. Results: the remixed song `voice_sing_*.flac` and the dry converted vocal `voice_sing_vocal_*.flac`\n   in `output/audio/Gmanski/`.\n\n### Tips\n- `song_has_music` off when the song input is already a dry vocal (skips the split, cleaner result).\n- `octave` auto moves the melody one octave when a male-range lead becomes a female voice or the reverse, always\n  whole octaves so the vocal stays in the song's key. Force `none` to keep the original range.\n- `guidance` 3 is the model default; higher pushes harder toward your voice but can sound harsh.\n- A singing sample (even a few hummed lines) carries more of the voice's character than speech.\n- Use **Gmanski Vocal Split** to turn any finished song into a voice sample, for example to keep an AI singer's\n  voice for later songs.\n\n### Setup\n- Needs **ComfyUI-Gmanski 1.4.0+**. The voice engines run in their own Python environments under `/opt/voice`;\n  the Gmanski pod image (Nov 2026 or newer) has them. Anywhere else, run\n  `bash custom_nodes/ComfyUI-Gmanski/voice_workers/install.sh` once.\n- No model pack: the first run downloads the voice models (about 3 GB) into `models/voice`.\n\n### Consent\nOnly clone a voice you have permission to use: your own, or someone who agreed to it. Do not use a cloned voice to\nimpersonate a real person, deceive anyone or get around a voice check. Chatterbox stamps an inaudible watermark\n(Perth) into every clip it speaks.\n"], "title": "Read me: Voice Clone (Sing)", "color": "#432", "bgcolor": "#653"}, {"id": 2, "type": "LoadAudio", "pos": [-400, -300], "size": [360, 160], "flags": {}, "order": 1, "mode": 0, "inputs": [{"name": "audio", "type": "COMBO", "link": null, "widget": {"name": "audio"}}], "outputs": [{"name": "AUDIO", "type": "AUDIO", "links": [1]}], "properties": {"Node name for S&R": "LoadAudio"}, "widgets_values": ["song.mp3", null, null], "title": "Song (vocal + music, or a dry vocal)"}, {"id": 3, "type": "LoadAudio", "pos": [-400, -100], "size": [360, 160], "flags": {}, "order": 2, "mode": 0, "inputs": [{"name": "audio", "type": "COMBO", "link": null, "widget": {"name": "audio"}}], "outputs": [{"name": "AUDIO", "type": "AUDIO", "links": [2]}], "properties": {"Node name for S&R": "LoadAudio"}, "widgets_values": ["voice_sample.wav", null, null], "title": "Voice sample (5-20 s, no music)"}, {"id": 4, "type": "VoiceCloneSing", "pos": [20, -300], "size": [420, 330], "flags": {}, "order": 3, "mode": 0, "inputs": [{"name": "song", "type": "AUDIO", "link": 1}, {"name": "voice_sample", "type": "AUDIO", "link": 2}, {"name": "song_has_music", "type": "BOOLEAN", "link": null, "widget": {"name": "song_has_music"}}, {"name": "octave", "type": "COMBO", "link": null, "widget": {"name": "octave"}}, {"name": "steps", "type": "INT", "link": null, "widget": {"name": "steps"}}, {"name": "guidance", "type": "FLOAT", "link": null, "widget": {"name": "guidance"}}, {"name": "seed", "type": "INT", "link": null, "widget": {"name": "seed"}}, {"name": "keep_model_loaded", "type": "BOOLEAN", "link": null, "widget": {"name": "keep_model_loaded"}}], "outputs": [{"name": "song", "type": "AUDIO", "links": [3]}, {"name": "vocal", "type": "AUDIO", "links": [4]}], "properties": {"Node name for S&R": "VoiceCloneSing"}, "widgets_values": [true, "auto", 32, 3.0, 0, "randomize", false], "title": "Voice Clone: Sing (SoulX-Singer)"}, {"id": 5, "type": "SaveAudioAdvanced", "pos": [500, -300], "size": [360, 150], "flags": {}, "order": 4, "mode": 0, "inputs": [{"name": "audio", "type": "AUDIO", "link": 3}, {"name": "filename_prefix", "type": "STRING", "link": null, "widget": {"name": "filename_prefix"}}, {"name": "format", "type": "COMFY_DYNAMICCOMBO_V3", "link": null, "widget": {"name": "format"}}, {"name": "audioUI", "type": "AUDIO_UI", "link": null, "widget": {"name": "audioUI"}}], "outputs": [{"name": "audio", "type": "AUDIO", "links": []}], "properties": {"Node name for S&R": "SaveAudioAdvanced"}, "widgets_values": ["audio/Gmanski/voice_sing", "flac"], "title": "Save song in the new voice (flac)"}, {"id": 6, "type": "SaveAudioAdvanced", "pos": [500, -110], "size": [360, 150], "flags": {}, "order": 5, "mode": 0, "inputs": [{"name": "audio", "type": "AUDIO", "link": 4}, {"name": "filename_prefix", "type": "STRING", "link": null, "widget": {"name": "filename_prefix"}}, {"name": "format", "type": "COMFY_DYNAMICCOMBO_V3", "link": null, "widget": {"name": "format"}}, {"name": "audioUI", "type": "AUDIO_UI", "link": null, "widget": {"name": "audioUI"}}], "outputs": [{"name": "audio", "type": "AUDIO", "links": []}], "properties": {"Node name for S&R": "SaveAudioAdvanced"}, "widgets_values": ["audio/Gmanski/voice_sing_vocal", "flac"], "title": "Save dry vocal (flac)"}], "links": [[1, 2, 0, 4, 0, "AUDIO"], [2, 3, 0, 4, 1, "AUDIO"], [3, 4, 0, 5, 0, "AUDIO"], [4, 4, 1, 6, 0, "AUDIO"]], "groups": [], "config": {}, "extra": {"ds": {"scale": 0.62, "offset": [1480, 420]}, "gmanski_template": "voice-clone-sing", "generator": "scripts/build_gmanski_voice_clone_workflows.py", "source": "https://gmanski.com/workflows/voice-clone-sing"}, "version": 0.4}