Nodes/ComfyUI-DialogueTTS/IrodoriTTS-v2 Dialogue TTS
ComfyUI Node

IrodoriTTS-v2 Dialogue TTS

IrodoriTTS-v2 Dialogue TTS

By kantan-kanto·Created 4 months ago·Updated 4 months ago· 0
IrodoriTTS-v2 Dialogue TTS
  • model
  • ref_audio_config_a
  • ref_audio_config_b
  • cfg_config
  • rescale_config
  • combined_audio
  • dialogue_timing_json
  • log_text
dialogue_segments_json
speaker_a_keyA
speaker_b_keyB
seed0
seed_modeincrement_per_utterance
num_steps40
cfg_guidance_modeindependent
cfg_scale_text3.0
cfg_scale_speaker5.0
context_kv_cachetrue
silence_ms300
fade_ms10
max_utterances100
skip_empty_texttrue
unknown_speaker_policyerror

This is the reason the pack exists. The other nodes are scaffolding; IrodoriTTS-v2 Dialogue TTS is the thing that turns a speaker-tagged script into one finished conversation audio file, with two different cloned voices trading lines in order. If you've ever hand-assembled multi-voice TTS by rendering each line separately and stitching them in an editor, this node exists to make you stop doing that.

The contract: dialogue_segments_json

The whole node runs off one JSON string, and the format is the thing to learn first, because everything else follows from it. Every input on the node is a knob on top of this:

{
  "schema": "kantan.dialogue.v1",
  "utterances": [
    { "index": 1, "speaker": "A", "text": "こんにちは。" },
    { "index": 2, "speaker": "B", "text": "こんにちは、調子はどう?" }
  ]
}

Required per utterance: speaker and text. index is optional (fallback is just 1, 2, 3…). The node parses this, walks each utterance in order, swaps reference voices based on the speaker, synthesizes, and concatenates. Two speakers max - the README is explicit that three or more isn't supported. If a line has an unknown speaker, unknown_speaker_policy decides: error (default), skip, or fold it into speaker A or B.

You can write this JSON by hand, but the intended flow is to let an LLM generate it. The author's reference pipeline is ComfyUI-LLM-Session producing a transcript, then ComfyUI-ScriptFlow's MultiOutputScript extracting just the 「...」 quoted lines into this JSON - so an LLM can write narration and stage direction, and only the dialogue gets spoken. A bundled sample workflow (examples/ModelChatSample.json) shows the whole chain.

What you actually set

  • ref_audio_config_a / ref_audio_config_b - from two Reference Audio nodes. Your two voices. If you leave one out, the node still runs; it's optional.
  • speaker_a_key / speaker_b_key - the string values that mean "speaker A" and "speaker B" in your JSON (defaults A and B). If your LLM emits "speaker": "Alice" and "Bob", set the keys to those.
  • seed + seed_mode - the widget seed is the per-run base seed; seed_mode decides how it's distributed across utterances. The README's recommendation is solid: keep ComfyUI's "control before generate" on fixed and use increment_per_utterance (the default), so utterance 1 gets seed 100, utterance 2 gets 101, and so on - every line is reproducible and distinct. fixed gives every line the same seed (fine, but more likely to sound samey), randomize ignores the seed entirely.
  • silence_ms (default 300) and fade_ms (default 10) - dead air between lines and a short fade at each utterance's edges. The fade exists to kill click noise when clips are stitched; if you still hear pops, the README suggests bumping fade_ms to 15–20 (or down to ~5 if the starts sound rounded).
  • num_steps, cfg_guidance_mode, cfg_scale_text, cfg_scale_speaker, context_kv_cache - the same sampler knobs the plain Sampler node exposes. cfg_scale_text (3) pushes the words, cfg_scale_speaker (5) holds the voice.
  • max_utterances (default 100) - a safety cap on how many lines it'll chew through; skip_empty_text (default on) drops blank lines.

Outputs

  • combined_audio - the full conversation as one AUDIO track at 24kHz. Feed it to a SaveAudio node.
  • dialogue_timing_json - per-utterance start/end seconds. This is the hidden gem: it's your subtitle/lyric-sync data for free, so if you're driving lip-sync or burned-in subs off this audio, you already have the timestamps.
  • log_text - a plain-text log of what was synthesized, in what order, with which seed. Nice for reproducibility post-mortems.

Installing and the usual pain

cd ComfyUI/custom_nodes
git clone https://github.com/kantan-kanto/ComfyUI-DialogueTTS
pip install -r ComfyUI-DialogueTTS/requirements.txt

then restart (or search "ComfyUI-DialogueTTS" in ComfyUI Manager). The main checkpoint won't download itself - grab Irodori-TTS-500M-v2.safetensors into models/checkpoints/ - but the codec and tokenizer auto-fetch on first load.

Issues people actually hit: malformed JSON (the node errors cleanly on invalid JSON, so check the JSON before blaming the model); "Model not found" because the checkpoint was never placed; and long scenes on low VRAM, where keeping context_kv_cache on is what stops generation from slowing to a crawl. Also worth knowing this repo started as an unofficial v2 fork of jupo-ai's ComfyUI_IrodoriTTS_Wrapper before that project caught up with v2 - so if you have both packs installed, mind which one you're actually wiring up. And yes: this is a Japanese TTS at heart, so the pipeline sings in Japanese.

CategoryDialogueTTS/IrodoriTTS-v2

Inputs (20)

NameTypeDefaultDescription
modelIRODORI_V2_MODEL
dialogue_segments_jsonSTRING
speaker_a_keySTRINGA
speaker_b_keySTRINGB
seedINT00–9223372036854776000
seed_modeCOMBOincrement_per_utterance3 options: increment_per_utterance, fixed, randomize
num_stepsINT401–120
cfg_guidance_modeCOMBOindependent3 options: independent, joint, alternating
cfg_scale_textFLOAT3.00–10
cfg_scale_speakerFLOAT5.00–10
context_kv_cacheBOOLEANtrue
silence_msINT3000–10000
fade_msINT100–200
max_utterancesINT1000–1000
skip_empty_textBOOLEANtrue
unknown_speaker_policyCOMBOerror4 options: error, skip, use_a, use_b
ref_audio_config_aoptIRODORI_V2_REF_CONFIG
ref_audio_config_boptIRODORI_V2_REF_CONFIG
cfg_configoptIRODORI_V2_CFG_CONFIG
rescale_configoptIRODORI_V2_RESCALE_CONFIG

Outputs (3)

NameTypeDescription
combined_audioAUDIO
dialogue_timing_jsonSTRING
log_textSTRING