# Client-Side Text-to-Speech (TTS) Generation with Gemini Firebase AI Logic enables client-side Text-to-Speech (TTS) generation directly from your mobile and web applications without maintaining custom backend speech services. Using specialized Gemini TTS models, apps can synthesize natural, expressive audio with custom voice personas, multi-speaker dialogues, and in-flight audio streaming. ______________________________________________________________________ ## Supported Models Always specify a dedicated Gemini TTS model when generating audio: | Model ID | Description | | :----------------------------- | :--------------------------------------------------------------------------------- | | `gemini-3.1-flash-tts-preview` | Low-latency speech synthesis (preview); supports single- and multi-speaker output. | > [!WARNING] Always verify currently supported model availability in the > [Firebase AI Logic Models documentation](https://firebase.google.com/docs/ai-logic/models.md.txt). ______________________________________________________________________ ## Core Concepts & Configurations ### 1. Response Modality To instruct Gemini to synthesize and return audio, configure `responseModalities` in the generation configuration to include audio: - **Swift**: `generationConfig = GenerationConfig(responseModalities: [.audio])` - **Kotlin**: `generationConfig { responseModalities = listOf(ResponseModality.AUDIO) }` - **Web (JS/TS)**: `generationConfig: { responseModalities: ["AUDIO"] }` ### 2. Single-Speaker `SpeechConfig` Configure voice persona and optional language code (`languageCode`, e.g. `"en-US"`, `"es-ES"`, `"ja-JP"`) using `SpeechConfig`. Voice names map to Google prebuilt neural voices (for example: `Puck`, `Charon`, `Kore`, `Fenrir`, `Aoede`): - **Swift**: ```swift let speechConfig = SpeechConfig( voiceConfig: VoiceConfig( prebuiltVoiceConfig: PrebuiltVoiceConfig(voiceName: "Puck") ), languageCode: "en-US" ) ``` - **Kotlin**: ```kotlin val speechConfig = speechConfig { voiceConfig = voiceConfig { prebuiltVoiceConfig = prebuiltVoiceConfig { voiceName = "Puck" } } languageCode = "en-US" } ``` - **Web**: ```javascript speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: "Puck" } }, languageCode: "en-US" } ``` ### 3. Multi-Speaker `MultiSpeakerVoiceConfig` (2-Speaker Dialogues) For scripts with two distinct characters or roles (e.g., host and guest, narrator and character), configure `MultiSpeakerVoiceConfig` with `speakerVoiceConfigs` linking speaker names to specific voices: - **Swift**: ```swift let multiSpeakerConfig = SpeechConfig( multiSpeakerVoiceConfig: MultiSpeakerVoiceConfig( speakerVoiceConfigs: [ SpeakerVoiceConfig( speaker: "Host", voiceConfig: VoiceConfig( prebuiltVoiceConfig: PrebuiltVoiceConfig(voiceName: "Puck") ) ), SpeakerVoiceConfig( speaker: "Guest", voiceConfig: VoiceConfig( prebuiltVoiceConfig: PrebuiltVoiceConfig(voiceName: "Aoede") ) ) ] ) ) ``` - **Kotlin**: ```kotlin val multiSpeakerConfig = speechConfig { multiSpeakerVoiceConfig = multiSpeakerVoiceConfig { speakerVoiceConfigs = listOf( speakerVoiceConfig { speaker = "Host" voiceConfig = voiceConfig { prebuiltVoiceConfig = prebuiltVoiceConfig { voiceName = "Puck" } } }, speakerVoiceConfig { speaker = "Guest" voiceConfig = voiceConfig { prebuiltVoiceConfig = prebuiltVoiceConfig { voiceName = "Aoede" } } } ) } } ``` - **Web**: ```javascript speechConfig: { multiSpeakerVoiceConfig: { speakerVoiceConfigs: [ { speaker: "Host", voiceConfig: { prebuiltVoiceConfig: { voiceName: "Puck" } } }, { speaker: "Guest", voiceConfig: { prebuiltVoiceConfig: { voiceName: "Aoede" } } } ] } } ``` ______________________________________________________________________ ## Audio Directives and Emotional Tags Gemini TTS models accept natural-language directives and inline tags in prompts to control tone, cadence, pacing, and emotional expression. ### Directives Include directives at the start of your prompt to set the overall tone and scene: - `[Audio Profile: Warm, conversational podcast co-host with energetic delivery]` - `[Scene: Quiet bedtime story in a calm room]` - `[Director's Note: Speak deliberately, pausing for reflection after major questions]` ### Emotional Tags & Delivery Cues Embed delivery markers inline within dialogue or narration: - `[whispers]` — Soft, confidential whisper. - `[laughs]` / `[chuckles]` — Lighthearted laughter during delivery. - `[sighs]` — Expressive exhale. - `[slowly]` — Reduced tempo for emphasis or dramatic effect. - `[excited]` — Higher energy and faster pacing. - `[pause]` — Deliberate silence. ### Multi-Speaker Prompt Example ```text [Scene: A lively coffee-shop tech discussion] [Director's Note: Host is upbeat and curious; Guest is thoughtful and explanatory] Host: Welcome back! [excited] Today we are diving into client-side audio. Guest: [laughs] It's about time! No servers in between means virtually zero latency. Host: [whispers] Tell us the secret... how does it stream? Guest: [slowly] Pure linear PCM, chunk by chunk, directly to your device's audio engine. ``` ______________________________________________________________________ ## Audio Decoding and Playback ### Format Specifications Gemini TTS audio format depends on whether the request is unary or streaming: - **Unary Requests (`generateContent`)**: Returns complete **WAV (`audio/wav`)** audio with a standard 44-byte RIFF header included by default (24 kHz, mono, 16-bit signed little-endian PCM). These bytes can be passed directly to standard media players (`AVAudioPlayer`, `MediaPlayer`, `