A text-to-speech response. Layer A serializable data.
iex> resp = ALLM.SpeechResponse.new(audio: ALLM.Audio.from_binary(<<1, 2>>, "audio/mpeg"), format: :mp3)
iex> ALLM.Audio.size(resp.audio)
{:ok, 2}Fields
:audio: the synthesized audio, as%ALLM.Audio{source: {:binary, bytes}}.:format: the format that arrived, derived from the response's content type throughmime_to_format/1. It is not an echo of the request's:format, and the two differ whenever the request left:formatasnil. It isnilwhen the content type is not in the table.:sample_rate: the sample rate in Hz of the audio that arrived, as the adapter reports it, ornilwhen the adapter cannot tell. For:pcmthis is the rate to play the bytes at.:id,:request_id,:model,:provider: provider correlation.:usage: anALLM.Usage.t/0, nevernil. A provider that reports no counters for speech leaves every fieldnil.:raw: the provider's non-audio body, ornil. Audio bytes are never stored in:raw: they live once, in:audio, so a persisted response does not hold the audio twice. An adapter whose body carries encoded audio replaces it in:rawwith a"<N bytes>"placeholder.:metadata: caller-owned.
Format tables
format_to_mime/1 and mime_to_format/1 are the only MIME-to-format
tables in the library. They are separate functions so that a provider's
extra content type can extend the reverse table without changing the
forward one.
:ulaw maps to audio/basic, the registered type for 8 kHz µ-law
(RFC 2046), and :alaw to audio/alaw, which has no registered
equivalent. ElevenLabs answers ulaw_8000 with audio/ulaw and
alaw_8000 with audio/alaw (observed 2026-09-27), so the reverse table
also reads audio/ulaw as :ulaw.
Summary
Functions
Map a format atom to its content type.
Map a response content type to a format atom.
Build a %SpeechResponse{} from keyword opts.
Types
@type t() :: %ALLM.SpeechResponse{ audio: ALLM.Audio.t() | nil, format: ALLM.SpeechRequest.format() | nil, id: String.t() | nil, metadata: map(), model: String.t() | nil, provider: atom() | nil, raw: term(), request_id: String.t() | nil, sample_rate: pos_integer() | nil, usage: ALLM.Usage.t() }
Functions
@spec format_to_mime(ALLM.SpeechRequest.format()) :: String.t()
Map a format atom to its content type.
Examples
iex> ALLM.SpeechResponse.format_to_mime(:mp3)
"audio/mpeg"
iex> ALLM.SpeechResponse.format_to_mime(:ulaw)
"audio/basic"
@spec mime_to_format(String.t() | nil) :: ALLM.SpeechRequest.format() | nil
Map a response content type to a format atom.
Media-type parameters after ; are stripped and the type is compared
case-insensitively. A content type not in the table, or nil, returns
nil.
Examples
iex> ALLM.SpeechResponse.mime_to_format("audio/mpeg")
:mp3
iex> ALLM.SpeechResponse.mime_to_format("audio/wav; codecs=1")
:wav
iex> ALLM.SpeechResponse.mime_to_format("audio/ulaw")
:ulaw
iex> ALLM.SpeechResponse.mime_to_format("video/mp4")
nil
Build a %SpeechResponse{} from keyword opts.
Unknown keys raise KeyError via struct!/2.
Examples
iex> resp = ALLM.SpeechResponse.new(model: "tts-1")
iex> resp.usage
%ALLM.Usage{}