Text to Speech
Convert text into spoken audio
After reading this guide, you will know:
- How to generate speech from text.
- How to save generated audio files.
- How to stream audio as it is generated.
- How to choose models, voices, and formats.
- How to access raw audio bytes.
Basic Speech Generation
Give your application a voice. Generate speech and save the audio:
RubyLLM.speak("Hello, welcome to RubyLLM!").save("welcome.mp3")
The return value is a RubyLLM::Speech object:
speech = RubyLLM.speak "Hello, welcome to RubyLLM!"
speech.model
# => "gpt-4o-mini-tts-2025-12-15"
speech.voice
# => "alloy"
speech.format
# => "mp3"
speech.mime_type
# => "audio/mpeg"
speech.to_blob
# => raw audio bytes
Streaming Speech
Pass a block to receive audio before the complete recording is ready:
speech = RubyLLM.speak("Hello, welcome to RubyLLM!") do |chunk|
player.write(chunk.data)
end
speech.save "welcome.mp3"
Here, player is your application’s audio player or output stream. Each RubyLLM::SpeechChunk has data, format, mime_type, and to_blob. Chunks are consecutive bytes of one recording. The call returns a complete RubyLLM::Speech, so you can save the recording after playing its chunks.
Chunks are not retried once delivered to your block.
Choosing Models
Pass model: to choose a speech model:
RubyLLM.speak("Ship it.", model: "eleven_flash_v2_5")
Set default_speech_model in Configuration to change the default. For Azure, pass the deployment name with provider: :azure.
Voices
RubyLLM picks a provider default voice for the simple case. Pass voice: when you want a specific one.
RubyLLM.speak("Welcome back.", voice: "nova")
RubyLLM.speak(
"Say warmly: Welcome back.",
model: "gemini-3.1-flash-tts-preview",
voice: "Kore"
)
ElevenLabs identifies voices by id rather than by name, so pass the voice id from your ElevenLabs voice library:
RubyLLM.speak(
"Welcome back.",
model: "eleven_flash_v2_5",
voice: "JBFqnCBsd6RMkjVDRZzb"
)
Deepgram Aura models include a voice in their model name. Override it with voice::
RubyLLM.speak(
"Welcome back.",
model: "aura-2-thalia-en",
voice: "zeus"
)
Choose a model in the language you want to speak.
Formats
Choose an output format with format::
speech = RubyLLM.speak("Save this as a WAV file.", format: "wav")
speech.save("voiceover.wav")
Available formats depend on the model. speech.format and speech.mime_type describe the returned audio.
Gemini’s speech endpoint returns raw PCM audio:
speech = RubyLLM.speak(
"Say cheerfully: Have a wonderful day!",
model: "gemini-3.1-flash-tts-preview"
)
speech.format
# => "pcm"
speech.save "out.pcm"
Convert PCM with a tool like ffmpeg when you need a container format:
ffmpeg -f s16le -ar 24000 -ac 1 -i out.pcm out.wav
ElevenLabs also accepts formats with an explicit sample rate:
RubyLLM.speak("Ship it.", model: "eleven_flash_v2_5",
format: "pcm_24000")
Style
Use provider_options: for controls specific to a provider. OpenAI accepts delivery instructions and speed:
RubyLLM.speak(
"The build is green.",
provider_options: {
instructions: "Speak with calm confidence.",
speed: 1.1
}
)
ElevenLabs takes voice_settings and a language_code:
RubyLLM.speak(
"The build is green.",
model: "eleven_flash_v2_5",
provider_options: {
voice_settings: { stability: 0.4, similarity_boost: 0.8, speed: 1.1 },
language_code: "en"
}
)
Gemini handles style through the prompt:
RubyLLM.speak(
"Say in a bright, encouraging voice: The build is green.",
model: "gemini-3.1-flash-tts-preview",
voice: "Puck"
)
For retries and provider errors, see Error Handling.
Next Steps
- Audio Transcription: Convert speech back to text.
- Model Resolution: Learn how
model:andprovider:are resolved. - Instrumentation and Observability: Track speech generation events in production.