Nodes/ComfyUI-AudioSuiteAdvanced/Character Vocal Extractor (Multi-Track) (ASA)
ComfyUI Node

Character Vocal Extractor (Multi-Track) (ASA)

The Voice Slicer, Now With Gain, Stereo, and Resample Knobs Per Track

By whmc76·Created about a year ago·Updated 16 days ago· 29
Character Vocal Extractor (Multi-Track) (ASA)
  • audio
  • narrator_audio
  • character1_audio
  • character2_audio
  • character3_audio
  • character4_audio
  • character5_audio
  • extraction_info
subtitle_json
gain_db0.00
offset_seconds0.00
duration_seconds0.00
resample_to_hz0.00
make_stereotrue
fill_silencetrue

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 / Character1Character5, 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. 0 is unity (no change), -100 to +100 are the range. This is your per-character loudness trim.
  • resample_to_hz - resamples the segment with torchaudio.functional.resample when 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 Character1Character5 / Narrator roles, or every track comes out silent).
  • gain_db - your level trim per run. 0 to start.
  • resample_to_hz - 0 to keep the native rate, otherwise the target rate.
  • make_stereo - true (default) for stereo output, false to 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_audiocharacter5_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.

CategoryAudioSuiteAdvanced

Inputs (8)

NameTypeDefaultDescription
audioAUDIO
subtitle_jsonSTRING
gain_dbFLOAT0.00-100–100
offset_secondsFLOAT0.000–100000000000000000
duration_secondsFLOAT0.000–100000000000000000
resample_to_hzFLOAT0.000–100000000000000000
make_stereoBOOLEANtrue
fill_silenceBOOLEANtrue

Outputs (7)

NameTypeDescription
narrator_audioAUDIO
character1_audioAUDIO
character2_audioAUDIO
character3_audioAUDIO
character4_audioAUDIO
character5_audioAUDIO
extraction_infoSTRING