Skip to content

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:

from dsl.voices import ballad, onyx, nova, by_gender

A Voice carries its name + gender + casting descriptionnot 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):

brian("The Stranger", voice="onyx", instructions="Cold. Clipped. Military.")

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).