Gemini TTS streams raw PCM; Sume returns a finished wav or raw file

Gemini 3.8 Flash TTS streams headerless audio/l16 at 24 kHz. Sume returns a hosted file from an async job. Wrap the PCM in WAV and match the formats.

5 min readSume
All posts

Gemini 3.8 Flash TTS has two output modes: a unary call that returns a WAV (audio/wav, 24 kHz, 16-bit mono), and a streaming call whose default is headerless raw PCM (audio/l16, 24 kHz, 16-bit mono) (read 2026-10-07). A raw stream will not play in most players until you add a header. Sume returns neither: you get a finished, Sume-hosted file from a job, and you choose mp3, wav or raw in output_format.

What a Gemini stream gives you

The Gemini docs also list mu-law (audio/mulaw) and A-law (audio/alaw) and configurable rates of 24000, 16000 and 8000 Hz. A raw L16 stream is just samples, with no sample rate or channel count in the bytes, so you carry those facts yourself.

Gemini 3.8 Flash TTS output defaults (read 2026-10-07)
ModeDefault formatHeader
Unaryaudio/wav, 24 kHz, 16-bit monoYes
Streamingaudio/l16, 24 kHz, 16-bit monoNo (raw PCM)
Optionalaudio/mulaw, audio/alawRates 24000, 16000, 8000 Hz

Wrap the stream in a WAV

If you collected the stream bytes, Python's standard library can add the header. This is standalone and needs no API key.

import wave

def pcm_to_wav(pcm: bytes, path: str, rate: int = 24000) -> None:
    with wave.open(path, "wb") as w:
        w.setnchannels(1)
        w.setsampwidth(2)  # 16-bit samples
        w.setframerate(rate)
        w.writeframes(pcm)

if __name__ == "__main__":
    silence = b"\x00\x00" * 24000  # one second of silence
    pcm_to_wav(silence, "out.wav")
    print("wrote out.wav")

What Sume returns

A Sume TTS 1.0 job is async. The result carries a mirrored audio artifact, so there is no stream to reassemble. output_format.container accepts mp3 (the default, 44,100 Hz at 128 kbps), wav and raw; sample_rate accepts 8000, 16000, 22050, 24000, 44100 and 48000; encoding accepts pcm_f32le, pcm_s16le, pcm_mulaw and pcm_alaw.

To match Gemini's unary shape, ask for wav, pcm_s16le at 24000. The mono layout is not a field in the Sume schema, so check the file you get back before you rely on a channel count.

Pick by what you do with the audio

Sume does not call Gemini TTS, so converting between the two is your pipeline's job, not a Sume option.

  • Play it as it is generated: Gemini streaming, plus your own header and buffering.
  • Hand a file to a video render, a CDN or an avatar clip: a Sume job, then the hosted URL.
  • Need exact sentence cuts: Sume with wav or raw and segmentation.mode: sentence; mp3 returns timings only.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume