How to Customize TTS Voice and Speaker Settings in the Hugging Face Speech‑to‑Speech Repository

The huggingface/speech-to-speech repository provides a modular handler pattern where every TTS engine exposes its own argument dataclass for voice, speaker, language, and voice-cloning configuration.

Each TTS backend inherits from the abstract BaseHandler class and declares its customization surface through a dedicated arguments dataclass. This design lets you control voice output via CLI flags when running the full pipeline or programmatically when building custom workflows.

TTS Handler Architecture

The repository isolates voice synthesis behind three core components:

  • Argument dataclasses — Define CLI/API options per engine (e.g., Qwen3TTSHandlerArguments, PocketTTSHandlerArguments, KokoroTTSHandlerArguments)
  • Handler implementations — Consume arguments, load models, resolve speakers, and stream audio blocks
  • Pipeline orchestration — Parses prefixed arguments with HfArgumentParser and injects configured objects into handlers

All TTS handlers in src/speech_to_speech/TTS/ inherit from BaseHandler in src/speech_to_speech/baseHandler.py, which enforces a unified setup() / generate() contract.

Customizing Voice and Speaker by Engine

Qwen-3-TTS: Preset Speakers and Voice Cloning

The Qwen3TTSHandler in src/speech_to_speech/TTS/qwen3_tts_handler.py supports two modes: preset speaker selection and zero-shot voice cloning.

CLI: Select a preset speaker

python -m speech_to_speech.s2s_pipeline \
  --qwen3_tts_speaker "Jordan" \
  --qwen3_tts_language "en" \
  --qwen3_tts_ref_audio ""

The qwen3_tts_speaker argument accepts any value from _supported_speakers(). When speaker is None or empty, the handler falls back to the first supported speaker (lines 575–588 in qwen3_tts_handler.py).

CLI: Voice cloning with reference audio

python -m speech_to_speech.s2s_pipeline \
  --qwen3_tts_ref_audio /path/to/my_voice.wav \
  --qwen3_tts_ref_text "Hello, I am your custom avatar." \
  --qwen3_tts_speaker ""

Explicitly emptying --qwen3_tts_speaker triggers cloning mode. The handler extracts speaker characteristics from the reference file and associated transcript (lines 92–118).

Python: Direct handler instantiation with preset speaker

from speech_to_speech.TTS.qwen3_tts_handler import Qwen3TTSHandler
from threading import Event

handler = Qwen3TTSHandler()
handler.setup(
    should_listen=Event(),
    speaker="Aiden",
    language="en",
    device="cuda"
)

for chunk in handler.generate("Hello, world!"):
    # chunk: NumPy array of audio samples

    play(chunk)

Python: Voice cloning with pre-computed embedding

from speech_to_speech.TTS.qwen3_tts_handler import Qwen3TTSHandler
from threading import Event

handler = Qwen3TTSHandler()
handler.setup(
    should_listen=Event(),
    ref_audio="/data/my_voice.wav",
    ref_text="I am a synthetic narrator.",
    speaker=None,  # triggers cloning path

    device="cuda"
)

Pocket-TTS: Lightweight Voice Selection

The PocketTTSHandler in src/speech_to_speech/TTS/pocket_tts_handler.py uses a simpler pocket_tts_voice string argument.

CLI usage:

python -m speech_to_speech.s2s_pipeline \
  --pocket_tts_voice "cosette"

Python programmatic configuration:

from speech_to_speech.arguments_classes.pocket_tts_arguments import PocketTTSHandlerArguments
from speech_to_speech.s2s_pipeline import parse_arguments

# Pre-configure before pipeline parsing

pocket_args = PocketTTSHandlerArguments(pocket_tts_voice="cosette")
args = parse_arguments()
args.pocket_tts_handler_kwargs = pocket_args

The argument dataclass is defined in src/speech_to_speech/arguments_classes/pocket_tts_arguments.py.

Kokoro TTS: Voice and Language Code Pairs

The KokoroTTSHandler in src/speech_to_speech/TTS/kokoro_handler.py requires both voice and lang_code parameters (defined in KokoroTTSHandlerArguments).

CLI example:

python -m speech_to_speech.s2s_pipeline \
  --kokoro_tts_voice "af_bella" \
  --kokoro_tts_lang_code "en-us"

Argument Parsing and Pipeline Wire-Up

The central entry point src/speech_to_speech/s2s_pipeline.py uses HfArgumentParser to collect all TTS-specific arguments. Each engine prefixes its flags to avoid collision:

Engine Prefix Example Flag
Qwen-3-TTS --qwen3_tts_* --qwen3_tts_speaker
Pocket-TTS --pocket_tts_* --pocket_tts_voice
Kokoro TTS --kokoro_tts_* --kokoro_tts_voice

After parsing, the pipeline instantiates handlers and passes the configured argument objects to each setup() method.

Key Files for Voice Customization

Path Purpose
src/speech_to_speech/arguments_classes/qwen3_tts_arguments.py Qwen3TTSHandlerArguments dataclass with all Qwen-3-TTS options
src/speech_to_speech/TTS/qwen3_tts_handler.py Speaker resolution, voice cloning, and streaming logic
src/speech_to_speech/arguments_classes/pocket_tts_arguments.py PocketTTSHandlerArguments for Pocket-TTS voice selection
src/speech_to_speech/TTS/pocket_tts_handler.py Lightweight TTS handler implementation
src/speech_to_speech/TTS/kokoro_handler.py Kokoro TTS with voice + lang_code pairing
src/speech_to_speech/s2s_pipeline.py Central parser and handler graph construction
src/speech_to_speech/baseHandler.py Abstract base class enforcing setup/generate contract

Summary

  • TTS voice customization flows through engine-specific argument dataclasses parsed by HfArgumentParser in the pipeline entry point
  • Qwen-3-TTS supports preset speakers via qwen3_tts_speaker or voice cloning via qwen3_tts_ref_audio and qwen3_tts_ref_text
  • Pocket-TTS uses a single pocket_tts_voice string for speaker selection
  • Kokoro TTS requires paired voice and lang_code arguments
  • Direct handler instantiation bypasses CLI parsing and enables programmatic control of all speaker/voice parameters

Frequently Asked Questions

How do I list available preset speakers for Qwen-3-TTS?

Call _supported_speakers() on an initialized Qwen3TTSHandler instance. The method queries the backend and returns valid speaker names. If you pass an invalid speaker name to setup(), the handler will raise a validation error before generation begins.

Can I use voice cloning with Pocket-TTS or Kokoro?

No. Voice cloning is only implemented in Qwen3TTSHandler. The cloning pipeline requires reference audio processing and speaker embedding extraction that the other engines do not support. For Pocket-TTS and Kokoro, restrict yourself to the built-in voice presets.

What happens if I omit the speaker argument entirely?

Each handler has a fallback strategy. In Qwen3TTSHandler, None triggers the first supported speaker via _resolve_speakers(). Check the specific handler's setup() implementation in the source file to understand its default behavior.

How do I change voice settings at runtime without restarting the pipeline?

Instantiate handlers directly rather than through the CLI pipeline. Call handler.setup() with new parameters, or maintain multiple handler instances with different configurations. The BaseHandler contract in baseHandler.py ensures consistent re-initialization semantics across all engines.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →