Class: OllamaChat::TTS
- Inherits:
-
Object
- Object
- OllamaChat::TTS
- Includes:
- Ollama::Handlers::Concern, KramdownANSI, Utils::UTF8Converter, Utils::ValueFormatter
- Defined in:
- lib/ollama_chat/tts.rb
Overview
Text-to-Speech handler for streaming audio playback.
This class handles converting streamed text responses into spoken audio
using a remote TTS server. It manages parallel TTS requests for text
blocks while maintaining strict ordering of audio chunks through an
OrderedQueue. A coordinator thread ensures chunks are played in the
correct sequence, even when multiple TTS requests complete out of order.
Instance Attribute Summary collapse
-
#voice ⇒ String?
readonly
The voice attribute reader returns the voice associated with the object.
-
#voice_model ⇒ String?
readonly
The model attribute reader returns the TTS model ID from config.
Class Method Summary collapse
-
.voices(model: nil) ⇒ Array<String>
Returns a sorted list of available TTS voice IDs.
Instance Method Summary collapse
-
#call(response) ⇒ self
Processes a streaming response chunk for TTS conversion.
-
#initialize(chat:, voice: nil) ⇒ OllamaChat::TTS
constructor
Initializes a new TTS handler.
Methods included from KramdownANSI
#configure_kramdown_ansi_styles, #kramdown_ansi_parse, #kramdown_markdown_remove
Methods included from Utils::ValueFormatter
Methods included from Utils::UTF8Converter
Constructor Details
#initialize(chat:, voice: nil) ⇒ OllamaChat::TTS
Initializes a new TTS handler.
Sets up the audio player, ordered queue for managing audio chunks, and starts a coordinator thread that processes chunks in order.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/ollama_chat/tts.rb', line 50 def initialize(chat:, voice: nil) if voice if model = @voice_model = chat.config.voice.model? self.class.voices(model:).member?(voice) or voice = nil else self.class.voices.member?(voice) or voice = nil @voice_model = 'tts-1' end end @chat = chat @voice = voice @buffer = +'' @audio_player = OllamaChat::Utils::AudioPlayer.new @ordered_queue = OllamaChat::Utils::OrderedQueue.new @id_mutex = Mutex.new @next_id = 0 @current_thread_id = 1 @enqueued_count = 0 @finished_count = 0 @worker_threads = [] @coordinator = Thread.new { run_coordinator } super(output: Tins::NULL) end |
Instance Attribute Details
#voice ⇒ String? (readonly)
The voice attribute reader returns the voice associated with the object.
79 80 81 |
# File 'lib/ollama_chat/tts.rb', line 79 def voice @voice end |
#voice_model ⇒ String? (readonly)
The model attribute reader returns the TTS model ID from config.
84 85 86 |
# File 'lib/ollama_chat/tts.rb', line 84 def voice_model @voice_model end |
Class Method Details
.voices(model: nil) ⇒ Array<String>
Returns a sorted list of available TTS voice IDs.
When model is nil the generic /v1/voices endpoint is queried
and a hash array ([{"id": "…"}, …]) is expected. When a model name
is given, /v1/audio/voices?model=<id> is queried and a string
array (["…", …]) is expected (audio.cpp convention). If the
server is unreachable or returns an error, an empty array is
returned.
29 30 31 32 33 34 35 36 37 |
# File 'lib/ollama_chat/tts.rb', line 29 def self.voices(model: nil) url = model ? OC::OLLAMA::CHAT::TTS_URL + "/v1/audio/voices?model=#{model}" : OC::OLLAMA::CHAT::TTS_URL + '/v1/voices' voices = JSON.parse(Excon.get(url, expects: 200).body)["voices"] (model ? voices : voices.map { |v| v["id"] }).sort rescue [] end |
Instance Method Details
#call(response) ⇒ self
Processes a streaming response chunk for TTS conversion.
Buffers incoming text content and extracts complete blocks (separated by blank lines) for immediate TTS processing. When the response is done, finalizes playback by waiting for all pending TTS requests to complete.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/ollama_chat/tts.rb', line 96 def call(response) if content = response.response || response.&.content @buffer << content process_pending_blocks # Process and "read" completed blocks immediately! 🏎️💨 end if response.done finalize end self end |