Module: OllamaChat::Speaker

Included in:
Say, TTS
Defined in:
lib/ollama_chat/speaker.rb

Overview

A concern that adds one-shot speech capability to any voice handler that implements a #call(response) streaming method.

The included class (e.g. OllamaChat::TTS or OllamaChat::Say) is expected to have a #call(response) method that accepts an object responding to #response (the text) and #done (a completion flag). #speak wraps that streaming entry point in a one-shot lifecycle: optional delayed start on a background thread, a cancel flag, and automatic completion via done: true.

Examples:

Including Speaker in a handler

class MyHandler
  include OllamaChat::Speaker

  def call(response)
    speak_text(response.response) if response.response
    finalize if response.done
    self
  end
end

Instance Method Summary collapse

Instance Method Details

#cancel_speaking ⇒ self

Signals a pending background #speak to abort before it begins.

Always safe to call. Once the speaking thread has already passed the flag check and begun playback, the call has no further effect — the audio is already in the pipe.

Returns:

  • (self) —

    for chaining



80
81
82
83
# File 'lib/ollama_chat/speaker.rb', line 80

def cancel_speaking
  @speaking_cancelled = true
  self
end

#speak(text, background: false) ⇒ self?

Synthesizes and plays a one-shot text via the handler's streaming #call(response) method.

The text is wrapped in an OpenStruct with done: true so the handler's #call receives the same shape it expects during normal streaming, but with immediate completion. The actual speech synthesis is entirely delegated to the including class's #call implementation (e.g. TTS buffers → process_pending_blocks → finalize; Say prints to the say pipe → closes it).

Parameters:

  • text (String) —

    the text to speak

  • background (Boolean, Integer) (defaults to: false) —

    controls execution mode:

    • false (default): speak inline, blocks until playback finishes
    • true: spawn a background thread, speak immediately
    • a number (e.g. 10): spawn a background thread that sleeps for that many seconds before speaking; call #cancel_speaking to abort before the sleep expires

Returns:

  • (self, nil) —

    self when a background thread was spawned (enabling #cancel_speaking), nil for inline playback



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/ollama_chat/speaker.rb', line 42

def speak(text, background: false)
  speaking = -> * do
    if pause = background.ask_and_send(:to_f)
      sleep pause
    end
    @speaking_cancelled and return
    call(OpenStruct.new(response: text, done: true))
  end
  if background
    @speaker_thread = Thread.new(&speaking)
    @speaker_thread.report_on_exception = false
    self
  else
    speaking.()
    nil
  end
end

#wait_for_speaker ⇒ void?

Blocks the calling thread until a previously spawned background speaker thread (from speak with background:) has finished playback.

Safe to call when no background thread is running; returns nil immediately via safe navigation.

Returns:

  • (void, nil) —

    the result of Thread#join if a speaker thread exists, otherwise nil.



69
70
71
# File 'lib/ollama_chat/speaker.rb', line 69

def wait_for_speaker
  @speaker_thread&.join
end