π COF Voice
The character's voice sample as an AUDIO tensor, ready for TTS and lip-sync
- cof
- audio
- transcript
- labels
Why a voice sample, of all things
Because zero-shot voice cloning ate the problem. Two years ago a specific voice meant training; now you feed a TTS model ten seconds of reference audio and it talks like that. Chatterbox and F5-TTS both do it locally, and the whole quality tier that used to require ElevenLabs sits in the 2β8GB VRAM range.
Which moves the bottleneck to the obvious place: where's the reference audio. If your character is a bundle, the voice reference belongs in the bundle - and COF Voice gets it out of the .cof as a proper ComfyUI AUDIO, plus the transcript, plus the sample list.
How it works
The reader collects the preset's voice variants and their sample ids; each sample is labelled with its name and language (Clara reading Β· fr-style, English half of the bilingual label kept). The chosen sample is extracted to ComfyUI/temp/cof/<file-stem>/ and then decoded, in this order:
- ComfyUI's own audio loader (
comfy_extras.nodes_audio.load) - almost always what happens; torchaudio.load- fallback;- PyAV - last resort.
That cascade is why the pack needs no dependencies. pyproject.toml declares an empty dependency list, and there's no requirements.txt: if you have a working ComfyUI with audio support (or torchaudio, which most installs carry anyway), decoding works. You only discover the PyAV branch exists if both of the other two are missing, at which point import av fails and you finally get an error worth reading.
The output is the standard ComfyUI AUDIO dict - {"waveform": [1, channels, samples], "sample_rate": β¦} - batch dimension included. It behaves like anything else that makes audio.
Two design decisions worth flagging. First, a preset with no voice returns one second of silence at 44.1kHz rather than raising. Deliberate, and it keeps a batch run from dying on the one character whose file has no sample. Second, the transcript output: if the file carries a text transcript for that sample, you get its contents. That's the piece most people forget to record - the words spoken in a reference clip - and it's exactly what a cloning pipeline wants to compare against.
Inputs and outputs
Required: cof, sample (sample_001β¦sample_016, default sample_001; in the UI the list is filled with the preset's real samples and their languages).
audio- AUDIO. Wire into your TTS node's reference-audio input, into a lip-sync node, into Save Audio, or into Preview Audio to listen before committing to a generation run.transcript- STRING, the words in the sample, empty if the file doesn't have one.labels- one line per sample with name and language, or(this preset has no voice sample).
labels is the odd one out here: a plain string listing everything available, whether or not you picked it. It's the tour guide, not the payload. Preview Any it once and you know what a file offers.
Note the name/language pairing in the labels when you have several samples. A character file can ship multiple takes, and picking the wrong language for your TTS model is the difference between cloning and cacophony.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/yannsouetre/ComfyUI-COF
mkdir -p ComfyUI/models/cof
cp your-character.cof ComfyUI/models/cof/
Restart, press R for new files, nodes under COF. Manager search: "ComfyUI-COF". No models to download; you will need an audio-capable ComfyUI, which current releases are.
The preview workflow (workflows/cof_preview.json) wires this node to Preview Audio with no model at all - genuinely the fastest confidence check on a new .cof.
Common issues
One second of silence. The preset has no voice sample, and this is the documented behaviour, not a bug. Check labels for the honest string.
transcript is empty but audio plays. The file has the sample without a transcript. Nothing to fix in ComfyUI; the .cof author didn't include it.
Cloned voice sounds nothing like the sample. Sample length and cleanliness matter more than anything on this node. Short, clean, single-speaker, no music bed. If the file's sample is noisy, extract it (Preview Audio β Save Audio), clean it outside ComfyUI, and feed the clean file instead.
Wrong language out of the TTS. Check the label. English TTS on a French reference gives you an accent-shaped mess that people blame on the node.
Exotic sample rates or multi-channel files behaving oddly. The decode cascade returns whatever the file is; some downstream audio nodes assume mono 44.1k. Drop a resample/mono node in between if your pipeline complains.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| cof | COF | β | |
| sample | COMBO | sample_001 | the list shows the preset's voice samples by name and language |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | β |
| transcript | STRING | β |
| labels | STRING | β |