Character Vocal Extractor (Multi-Track) (ASA)
The Voice Slicer, Now With Gain, Stereo, and Resample Knobs Per Track
- audio
- narrator_audio
- character1_audio
- character2_audio
- character3_audio
- character4_audio
- character5_audio
- extraction_info
Character Vocal Extractor (Multi-Track) (ASA) is the same idea as the plain Character Vocal Extractor - take a full recording plus a speaker-tagged transcript and output each person's voice on its own track with everything else silenced - but it adds the audio-processing knobs you actually want when the split tracks are going somewhere real. Gain, resampling, and a forced stereo output, applied per extracted segment. The author calls it "UTK Audio Crop Process" logic, which is the Chinese TTS workflow convention this pack borrows the crop semantics from; whatever you call it, the practical difference is that the tracks come out mix-ready instead of raw.
Pick this one over the plain extractor when your downstream needs are specific: the TTS model you're feeding wants 22.05 kHz, or the mixer wants stereo, or one character's take is noticeably quieter than another's and you want to normalize it as you pull it out. The plain node is for "just separate them"; this one is for "separate them properly."
How it works
Mechanically it's the sibling logic: parse subtitle_json, match ids against Narrator / Character1–Character5, build a per-role silence buffer, and copy each matching segment back into place. The difference is what happens to each segment before it's placed:
- gain_db - an amplitude multiplier applied as
10^(gain_db/20)to the segment.0is unity (no change),-100to+100are the range. This is your per-character loudness trim. - resample_to_hz - resamples the segment with
torchaudio.functional.resamplewhen set to a non-zero rate different from the input's.0(default) means "leave the rate alone." - make_stereo - if on (default), mono segments are duplicated into a true stereo pair so every output track has two channels.
Segments are cropped with the same offset/duration convention as the plain node: duration_seconds of 0 means no crop, offset_seconds trims the start, and both zero uses the full clip. And it carries an IS_CHANGED hash, so it re-runs whenever the audio or any parameter actually changes rather than serving a cached result.
The inputs you'll actually set
- audio and subtitle_json - same as the plain extractor: original recording, and the transcript from Multi-Speaker Speech To Text (with speaker IDs mapped to the
Character1–Character5/Narratorroles, or every track comes out silent). - gain_db - your level trim per run.
0to start. - resample_to_hz -
0to keep the native rate, otherwise the target rate. - make_stereo -
true(default) for stereo output,falseto keep mono. - offset_seconds / duration_seconds - crop window,
0= no crop. - fill_silence -
true(default) gives every character a full-length track.
Outputs: narrator_audio, character1_audio–character5_audio, plus extraction_info (the per-character segment summary as text).
Installing it
Same pack as everything else here: whmc76/ComfyUI-AudioSuiteAdvanced (display "AudioSuiteAdvanced"). ComfyUI Manager → search "AudioSuiteAdvanced", or:
cd ComfyUI/custom_nodes
git clone https://github.com/whmc76/ComfyUI-AudioSuiteAdvanced
cd ComfyUI-AudioSuiteAdvanced
pip install -r requirements.txt
Restart ComfyUI. No extra model downloads for this node itself.
Where people get burned
The stereo knob is the one with teeth. make_stereo duplicates a mono input happily, but the code raises an error if your input has more than two channels and you ask for stereo - it can't downmix. Feed it the same mono 16 kHz audio the pack recommends everywhere and you'll never hit it, but a multi-channel source will.
Second, resampling changes the sample-rate bookkeeping on the output, and the code has to re-derive segment placement when the rate changes. It handles the math, but the safe move is to keep resample_to_hz at 0 unless a specific downstream model demands a rate - normalizing per-track rates is a separate concern from extracting voices, and doing both at once is how you end up debugging placement drift.
And the same warning as the plain node: this is a gate, not a source separator. Overlapping speakers both get the shared audio. If your recording has cross-talk, no amount of gain and stereo knobs fixes it - that's a job for a demucs-style separation model, not this.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | — | |
| subtitle_json | STRING | — | |
| gain_db | FLOAT | 0.00-100–100 | — |
| offset_seconds | FLOAT | 0.000–100000000000000000 | — |
| duration_seconds | FLOAT | 0.000–100000000000000000 | — |
| resample_to_hz | FLOAT | 0.000–100000000000000000 | — |
| make_stereo | BOOLEAN | true | — |
| fill_silence | BOOLEAN | true | — |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| narrator_audio | AUDIO | — |
| character1_audio | AUDIO | — |
| character2_audio | AUDIO | — |
| character3_audio | AUDIO | — |
| character4_audio | AUDIO | — |
| character5_audio | AUDIO | — |
| extraction_info | STRING | — |