voice

package
v1.5.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 26, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package voice provides live microphone/speaker audio for the interactive console. Hardware I/O (PortAudio) is compiled only under the `voice` build tag; everything else here is pure Go so it builds and tests without cgo.

Index

Constants

View Source
const (
	// CaptureSampleRate is the mic capture rate (16 kHz mono PCM16), matching
	// the VAD/STT pipeline default.
	CaptureSampleRate = 16000
	// PlaybackSampleRate is the speaker playback rate (24 kHz mono PCM16),
	// matching TTS / realtime-provider output.
	PlaybackSampleRate = 24000
)

Variables

View Source
var ErrVoiceNotCompiled = errors.New("voice not compiled in (build with -tags voice)")

ErrVoiceNotCompiled is returned by NewAudioIO in builds without the `voice` build tag. It is defined here (not in the stub) so callers can errors.Is check it regardless of build mode.

Functions

This section is empty.

Types

type AudioIO

type AudioIO interface {
	// Start opens the mic and speaker devices.
	Start(ctx context.Context) error
	// CaptureChunks yields mic PCM16 frames (CaptureSampleRate, mono).
	CaptureChunks() <-chan []byte
	// Play enqueues a PCM16 frame (PlaybackSampleRate, mono) for the speaker.
	Play(frame []byte)
	// Close stops devices and releases resources.
	Close() error
}

AudioIO is hardware mic capture + speaker playback as PCM16 byte streams. Implementations are platform audio backends; the driver depends only on this interface so it is testable without audio hardware.

func NewAudioIO

func NewAudioIO() (AudioIO, error)

NewAudioIO returns ErrVoiceNotCompiled in non-voice builds. Build with -tags voice (and PortAudio installed) to enable voice.

type Driver

type Driver struct {
	// contains filtered or unexported fields
}

Driver wires hardware AudioIO to a LiveRunner and (optionally) reports RMS levels for the TUI meter. It owns no LLM or pipeline knowledge.

func NewDriver

func NewDriver(io AudioIO, run LiveRunner, onLevel func(user, agent float32)) *Driver

NewDriver constructs a Driver. onLevel may be nil.

func NewDriverWithGuard

func NewDriverWithGuard(io AudioIO, run LiveRunner, onLevel func(user, agent float32), guard *EchoGuard) *Driver

NewDriverWithGuard constructs a Driver with an optional half-duplex echo guard. When guard is non-nil, mic frames are gated by g.Allow before reaching the runner, and g.SetAgentSpeaking is toggled around each playback frame.

v1 limitation: the per-frame SetAgentSpeaking toggle is effective only for synchronous playback (where Play blocks for the full frame duration). Real buffered hardware drivers return from Play before the audio is audible, so the flag stays true for only microseconds and does not suppress echo. Hardware wiring must hold SetAgentSpeaking true for the entire audible playback duration — see the TODO in Driver.Run.

func (*Driver) Run

func (d *Driver) Run(ctx context.Context) error

Run starts audio I/O and drives the conversation until ctx ends or mic closes.

type EchoGuard

type EchoGuard struct {
	// contains filtered or unexported fields
}

EchoGuard implements an optional half-duplex mic gate: while the agent is speaking, mic frames quieter than threshold are dropped (they are most likely the agent's own audio bleeding into the mic). Louder frames still pass so a deliberate barge-in interrupts. Off (always-allow) unless enabled by Run.

func NewEchoGuard

func NewEchoGuard(threshold float32) *EchoGuard

NewEchoGuard builds a guard with the given RMS threshold (0..1).

func (*EchoGuard) Allow

func (g *EchoGuard) Allow(frame []byte) bool

Allow reports whether a mic frame should be forwarded.

func (*EchoGuard) SetAgentSpeaking

func (g *EchoGuard) SetAgentSpeaking(v bool)

SetAgentSpeaking marks whether agent audio is currently playing.

type LiveRunner

type LiveRunner func(ctx context.Context, mic <-chan []byte, play func([]byte)) error

LiveRunner consumes mic frames and emits playback frames, returning when mic closes or ctx ends. engine.(*DuplexConversationExecutor).RunInteractiveVoice is adapted to this signature by the chat command.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL