Class: RubyLLM::Speech
- Inherits:
-
Object
- Object
- RubyLLM::Speech
- Defined in:
- lib/ruby_llm/speech.rb
Overview
Constant Summary collapse
- MIME_TYPES =
Maps audio format names to their MIME types.
{ 'aac' => 'audio/aac', 'flac' => 'audio/flac', 'mp3' => 'audio/mpeg', 'opus' => 'audio/opus', 'pcm' => 'audio/pcm', 'wav' => 'audio/wav' }.freeze
Constants included from RubyLLM::Support::Inspectable
RubyLLM::Support::Inspectable::TRUNCATE_AT
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
The raw audio bytes returned by the provider.
-
#format ⇒ Object
readonly
The audio format name, such as "mp3" or "pcm".
-
#mime_type ⇒ Object
readonly
The MIME type of the audio, such as "audio/mpeg".
-
#model ⇒ Object
readonly
The id of the model that generated the audio.
-
#voice ⇒ Object
readonly
The voice used for synthesis.
Class Method Summary collapse
-
.speak(input, model: nil, provider: nil, assume_model_exists: false, voice: nil, format: nil, context: nil, provider_options: {}, metadata: nil, &block) ⇒ Object
Generates speech for
inputand returns a Speech holding the audio.
Instance Method Summary collapse
-
#cost ⇒ Object
Returns the speech cost across every provider attempt.
-
#initialize(data:, model:, voice: nil, format: 'mp3', mime_type: nil, input_tokens: nil, output_tokens: nil) ⇒ Speech
constructor
:nodoc:.
-
#inspect_attributes ⇒ Object
:nodoc:.
-
#model_info ⇒ Object
:nodoc:.
-
#save(path) ⇒ Object
Writes the audio to
pathin binary mode and returnspath. -
#to_blob ⇒ Object
Returns the raw audio bytes.
-
#tokens ⇒ Object
Returns provider-reported usage across every attempt.
Methods included from Accounting::Usage::Result
#ruby_llm_usage_entries, #ruby_llm_usage_entries=
Methods included from RubyLLM::Support::Inspectable
#full_inspect, #inspect, #pretty_print
Constructor Details
#initialize(data:, model:, voice: nil, format: 'mp3', mime_type: nil, input_tokens: nil, output_tokens: nil) ⇒ Speech
:nodoc:
40 41 42 43 44 45 46 47 48 49 |
# File 'lib/ruby_llm/speech.rb', line 40 def initialize(data:, model:, voice: nil, format: 'mp3', mime_type: nil, # :nodoc: input_tokens: nil, output_tokens: nil) @data = data @model = model @voice = voice @format = (format || 'mp3').to_s @mime_type = mime_type || MIME_TYPES.fetch(@format, "audio/#{@format}") @input_tokens = input_tokens @output_tokens = output_tokens end |
Instance Attribute Details
#data ⇒ Object (readonly)
The raw audio bytes returned by the provider.
25 26 27 |
# File 'lib/ruby_llm/speech.rb', line 25 def data @data end |
#format ⇒ Object (readonly)
The audio format name, such as "mp3" or "pcm".
35 36 37 |
# File 'lib/ruby_llm/speech.rb', line 35 def format @format end |
#mime_type ⇒ Object (readonly)
The MIME type of the audio, such as "audio/mpeg".
38 39 40 |
# File 'lib/ruby_llm/speech.rb', line 38 def mime_type @mime_type end |
#model ⇒ Object (readonly)
The id of the model that generated the audio.
28 29 30 |
# File 'lib/ruby_llm/speech.rb', line 28 def model @model end |
#voice ⇒ Object (readonly)
The voice used for synthesis. When no voice: was given, this is the
provider default.
32 33 34 |
# File 'lib/ruby_llm/speech.rb', line 32 def voice @voice end |
Class Method Details
.speak(input, model: nil, provider: nil, assume_model_exists: false, voice: nil, format: nil, context: nil, provider_options: {}, metadata: nil, &block) ⇒ Object
Generates speech for input and returns a Speech holding the audio.
Uses config.default_speech_model unless model: is given.
Pass provider: and assume_model_exists: true to use a model
that is not in the registry. provider_options: takes options in the
provider's request vocabulary, such as instructions: and speed:
for OpenAI, and merges them into the request as-is.
speech = RubyLLM.speak "Hello, welcome to RubyLLM!"
speech.save "welcome.mp3"
RubyLLM.speak "Welcome back.", voice: "nova"
RubyLLM.speak "Save this as a WAV file.", format: "wav"
RubyLLM.speak "Say cheerfully: Have a wonderful day!",
model: "gemini-3.1-flash-tts-preview", provider: :gemini
Given a block, yields SpeechChunk objects as audio arrives and still returns the complete Speech. Chunks contain consecutive bytes of the recording and are not separate audio files.
File.open("welcome.mp3", "wb") do |file|
RubyLLM.speak("Welcome back.") { |chunk| file.write(chunk.data) }
end
Raises RubyLLM::Error when the selected protocol cannot stream speech,
or RubyLLM::ModelNotFoundError if model: is not in the registry.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/ruby_llm/speech.rb', line 76 def self.speak(input, model: nil, provider: nil, assume_model_exists: false, voice: nil, format: nil, context: nil, provider_options: {}, metadata: nil, &block) config = context&.config || RubyLLM.config model ||= config.default_speech_model model, provider_instance = Models.resolve(model, provider: provider, assume_model_exists: assume_model_exists, config: config) empty_tokens = Tokens.new payload = { provider: provider_instance.slug, provider_class: provider_instance.name, model: model.id, model_info: model, input: input, voice: voice, format: format, provider_options: , metadata: , streaming: !block.nil?, tokens: empty_tokens, cost: Cost.new(tokens: empty_tokens, model:, category: :audio_tokens) } RubyLLM.instrument('speech.ruby_llm', payload, config: config) do |event| result = provider_instance.speak(input, model:, voice:, format:, provider_options:, &block) event[:result] = result event[:response_model] = result.model event[:voice] = result.voice event[:format] = result.format event[:audio_bytes] = result.to_blob.bytesize event[:tokens] = result.tokens event[:cost] = result.cost result end end |
Instance Method Details
#cost ⇒ Object
Returns the speech cost across every provider attempt.
134 135 136 137 138 |
# File 'lib/ruby_llm/speech.rb', line 134 def cost return ruby_llm_usage_cost unless ruby_llm_usage_entries.empty? Cost.new(tokens:, model: model_info, category: :audio_tokens) end |
#inspect_attributes ⇒ Object
:nodoc:
155 156 157 |
# File 'lib/ruby_llm/speech.rb', line 155 def inspect_attributes # :nodoc: { model: model, voice: voice, format: format, data: data && "#{data.bytesize} bytes" } end |
#model_info ⇒ Object
:nodoc:
140 141 142 143 144 |
# File 'lib/ruby_llm/speech.rb', line 140 def model_info # :nodoc: @model_info ||= RubyLLM.models.find(model) rescue ModelNotFoundError nil end |
#save(path) ⇒ Object
Writes the audio to path in binary mode and returns path.
speech.save "welcome.mp3"
150 151 152 153 |
# File 'lib/ruby_llm/speech.rb', line 150 def save(path) File.binwrite(File.(path), to_blob) path end |
#to_blob ⇒ Object
Returns the raw audio bytes. Alias for #data, mirroring Image#to_blob.
121 122 123 |
# File 'lib/ruby_llm/speech.rb', line 121 def to_blob data end |
#tokens ⇒ Object
Returns provider-reported usage across every attempt. Its fields are
nil when the provider did not report any.
127 128 129 130 131 |
# File 'lib/ruby_llm/speech.rb', line 127 def tokens return ruby_llm_usage_tokens unless ruby_llm_usage_entries.empty? Tokens.new(input: @input_tokens, output: @output_tokens) end |