package voice import "context" // Provider is one rung in the voice degradation chain. It may implement zero, // one, or both directions; a nil return means that direction is not available // on this rung and the chain moves to the next. type Provider interface { // Name returns a stable provider identifier. Name() string // STT returns the speech-to-text implementation, or nil when the provider // cannot transcribe. STT() STT // TTS returns the text-to-speech implementation, or nil when the provider // cannot synthesize. TTS() TTS } // StaticProvider is a Provider with a fixed name whose STT/TTS are set at // construction. It is used by the concrete providers below. type StaticProvider struct { name string stt STT tts TTS } // Name returns the provider identifier. func (p *StaticProvider) Name() string { return p.name } // STT returns the configured STT, or nil. func (p *StaticProvider) STT() STT { return p.stt } // TTS returns the configured TTS, or nil. func (p *StaticProvider) TTS() TTS { return p.tts } // NewProvider builds a Provider with the given name and optional directions it // supports. func NewProvider(name string, stt STT, tts TTS) *StaticProvider { return &StaticProvider{name: name, stt: stt, tts: tts} } // CloudProvider is the cloud rung of the chain. It is an adaptation point: the // real STT/TTS implementations are wired in via NewProvider with cloud adapters. func CloudProvider(stt STT, tts TTS) *StaticProvider { return NewProvider("cloud", stt, tts) } // LocalProvider is the local-model rung of the chain. func LocalProvider(stt STT, tts TTS) *StaticProvider { return NewProvider("local", stt, tts) } // EdgeTTSProvider is the edge-tts rung (text-to-speech only). func EdgeTTSProvider(tts TTS) *StaticProvider { return NewProvider("edge-tts", nil, tts) } // EspeakProvider is the espeak rung (text-to-speech only). func EspeakProvider(tts TTS) *StaticProvider { return NewProvider("espeak", nil, tts) } // SilentProvider is the terminal rung. It always succeeds, returning an empty // transcription and empty audio, so a chain that includes it never errors. func SilentProvider() *StaticProvider { return NewProvider("silent", silenceSTT{}, silenceTTS{}) } // silenceSTT is the silent STT rung; it returns an empty transcription. type silenceSTT struct{} func (silenceSTT) STT(_ context.Context, _ Audio) (string, error) { return "", nil } // silenceTTS is the silent TTS rung; it returns empty audio. type silenceTTS struct{} func (silenceTTS) TTS(_ context.Context, _ string) (Audio, error) { return Audio{}, nil }