Voice Catalogue¶
The 12 OpenAI TTS voices, each a gender-tagged singleton in dsl/voices.py. Voice is
split from the rig — you pick one when you cast a character, independent of the body. Import the
ones you need:
A Voice carries its name + gender + casting description — not tone. Tone (how a character
speaks) is the character's instructions. See Actors → Per-character voices
for the full casting API.
Male (6)¶
| Voice | Best for |
|---|---|
ash |
Bright, clear, youthful. Younger leads, optimistic protagonists, sharp professionals (doctors, lawyers), upbeat support. |
ballad |
Warm, melodic, measured — slight British lean. Grounded narration, middle-aged warmth, romantic leads, domestic-drama dads. |
echo |
Calm, smooth, neutral-pitch. Thoughtful detectives, professors, mature professionals — quiet authority. |
fable |
Warm British storyteller. Narrators, period-drama leads, literate villains, fairy-tale roles. |
onyx |
Deep, resonant, authoritative. Older men, villains, narrators with gravitas, commanders, imposing creatures. |
verse |
Versatile, expressive, theatrical. Sorcerers, knights, dramatic villains, performative delivery. |
Female (5)¶
| Voice | Best for |
|---|---|
coral |
Cheerful, warm, reassuring. Caring mothers, supportive friends, teachers — roles that put others at ease. |
marin |
Clear, professional, contemporary. Executives, journalists, doctors, modern leads. |
nova |
Energetic, friendly, higher-pitched. Enthusiastic support, younger women, warm friends. |
sage |
Calm, wise, mid-range. Matriarchs, mentors, healers — quiet depth. |
shimmer |
Warm, gentle, soft. Nurturing roles, romantic leads, dreamy / ethereal characters. |
Neutral (1)¶
| Voice | Best for |
|---|---|
alloy |
Balanced, even-tempered, gender-ambiguous (slight male lean). Stealth agents, narrators, AI characters — functional rather than gendered. |
by_gender() includes neutral
by_gender("male") and by_gender("female") each return their own voices plus alloy, so
a neutral timbre is always an available fallback.
Casting¶
Pick a voice at cast time — define once at the top, then reuse:
from dsl.actors import james, megan
from dsl.voices import echo, nova # gender-matched voices
marcus = james("Marcus", voice=echo) # male rig + male voice
nina = megan("Nina", voice=nova)
# … then in any shot: marcus.say("…", action_name="talking")
…or inline for a one-off (voice by singleton or string name, plus a delivery note):
Defaults & gender matching¶
Every character also has a curated default_voice (used when you don't pass voice=), set in
assets/character_descriptions.json. All 36 rigs are paired with a gender-matched default
(0 mismatches) — so a male character never silently gets a female voice. This closed
Issue #12. When casting a
new pairing, match the character's gender to the voice's (or use by_gender).