an.audio.voices#
Which voice speaks a dialogue line: the character → voice binding (an#194).
A line resolves its voice — a key of the project’s voices store — in this
order, first hit wins:
the line’s own
voice_ref(set from Python orir/scene.json);the speaking character’s
voice_ref: the shot entity whoseidis the line’sspeaker, read from its descriptor in thecharactersstore with the entity’soverridesmerged over it (sooverrides: {voice_ref: x}on the entity re-voices it for one shot);
A voice document may name the TTS provider’s own voice with voice_id (a
say -v name for mac_say, a voice id for ElevenLabs); the provider is
handed that, and otherwise the store key itself. A document that declares
provider scopes its provider-specific keys (voice_id, and the
model_id / voice_settings / seed ElevenLabs reads — an#209) to that
provider: rendered with another one, the line is handed "default", so an
ElevenLabs-voiced project previews with mac_say or offline instead of
failing on a foreign voice id. Nothing declared anywhere
resolves every line to "default" handed to the provider as "default" —
exactly what the pipeline did before this module, so no cache key moves.
The document’s provider also DECIDES who speaks the line when the render
names no provider (an#305): declared_provider() reads it, and
an.audio.pipeline.tts_chooser() turns it into the provider — so a voice
written for ElevenLabs is spoken by ElevenLabs by a plain an render, and
--tts is an override for every line.
>>> from an.ir.schema import AssetRef, Dialogue, Shot
>>> shot = Shot(id="s", entities=[
... AssetRef(kind="character", id="carl", store="characters", ref="carl"),
... AssetRef(kind="character", id="ned", store="characters", ref="ned",
... overrides={"voice_ref": "ned_sad"})])
>>> mall = {"characters": {"carl": {"voice_ref": "carl_kid"}, "ned": {"voice_ref": "ned_kid"}},
... "voices": {"carl_kid": {"voice_id": "Junior"}}}
>>> [line_voice_id(Dialogue(speaker=s, text="hi"), shot, mall) for s in ("carl", "ned", "narrator")]
['carl_kid', 'ned_sad', 'default']
>>> line_voice_id(Dialogue(speaker="carl", text="hi", voice_ref="own"), shot, mall)
'own'
>>> provider_voice(mall, "carl_kid"), provider_voice(mall, "default")
('Junior', None)
>>> mall["voices"]["bob"] = {"provider": "elevenlabs", "voice_id": "abc123"}
>>> provider_voice(mall, "bob", tts_name="elevenlabs"), provider_voice(mall, "bob", tts_name="mac_say")
('abc123', 'default')
>>> declared_provider(mall, "bob"), declared_provider(mall, "carl_kid")
('elevenlabs', None)
Module Attributes
The voice a line gets when neither it nor its speaker names one. |
|
The key, in a voice document, naming the TTS provider's own voice. |
|
The key, in a voice document, naming the TTS provider it is written for. |
|
The key, in a character descriptor (or an entity's |
Functions
|
The TTS provider |
|
The |
|
The provider voice |
|
The voice the speaking character is bound to in |
|
Whether |
|
|
- an.audio.voices.CHARACTER_VOICE_KEY: str = 'voice_ref'#
The key, in a character descriptor (or an entity’s
overrides), naming the character’s voice in thevoicesstore.
- an.audio.voices.DEFAULT_VOICE: str = 'default'#
The voice a line gets when neither it nor its speaker names one.
- an.audio.voices.PROVIDER_KEY: str = 'provider'#
The key, in a voice document, naming the TTS provider it is written for.
- an.audio.voices.PROVIDER_VOICE_KEY: str = 'voice_id'#
The key, in a voice document, naming the TTS provider’s own voice.
- an.audio.voices.declared_provider(mall, voice_id)[source]#
The TTS provider
mall["voices"][voice_id]is written for, lower-cased, orNonewhen the voice declares none (or has no document).>>> declared_provider({"voices": {"v": {"provider": " ElevenLabs "}}}, "v") 'elevenlabs' >>> declared_provider({"voices": {"v": {"provider": ""}}}, "v") is None True
- an.audio.voices.line_voice_id(line, shot, mall, *, default='default')[source]#
The
voices-store keylineis spoken with (see the module doc).- Return type:
- an.audio.voices.provider_voice(mall, voice_id, *, tts_name=None)[source]#
The provider voice
mall["voices"][voice_id]names, orNone.Nonemeans “hand the providervoice_iditself” — a voice that is not in the store, a document withoutvoice_id, or one whosevoice_idis its own key (which changes nothing, so it must not move a cache key). Giventts_name, a document written for ANOTHER provider givesDEFAULT_VOICE— never a foreign voice id (an#209).
- an.audio.voices.speaker_voice_ref(speaker, shot, mall)[source]#
The voice the speaking character is bound to in
shot, orNone.Nonewhen no character entity of the shot has the speaker’s id (an off-screen narrator), or when neither its descriptor nor itsoverridesname a voice. A store that is absent, or that does not hold the ref, still lets the entity’soverridesspeak.
- an.audio.voices.voice_applies(doc, tts_name)[source]#
Whether
doc’s provider-specific keys apply under the TTStts_name.True when the document names no
provider, or names this one (case ignored), or when the caller does not say which provider is speaking.- Return type:
>>> voice_applies({}, "offline"), voice_applies({"provider": "ElevenLabs"}, "elevenlabs") (True, True) >>> voice_applies({"provider": "elevenlabs"}, "offline") False