tts

package
v0.48.1 Latest Latest
Warning

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

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

Documentation

Overview

Package tts exposes the embeddable SpeechKit text-to-speech surface.

Index

Constants

This section is empty.

Variables

View Source
var ErrMissingRouter = errors.New("speechkit tts: router is required")

Functions

func PreferredProviderForProfileID

func PreferredProviderForProfileID(profileID string) string

PreferredProviderForProfileID maps a Voice-Output profile ID to Provider.Name. The mapping is shared with the kernel via the ttsroute leaf package.

Types

type CapabilityReporter added in v0.46.0

type CapabilityReporter interface {
	Capabilities() []speechkit.Capability
}

CapabilityReporter is an optional interface a provider can implement to self-describe its capabilities, so routing can query them instead of string-matching profile IDs. It is intentionally NOT part of Provider, so existing implementations and test doubles are unaffected.

type Deepgram added in v0.46.0

type Deepgram struct {
	BaseURL    string
	Validation netsec.ValidationOptions
	// contains filtered or unexported fields
}

Deepgram implements Provider using the Deepgram Aura-2 text-to-speech REST API (POST /v1/speak). It reuses the Deepgram API key shared with the STT and Voice Agent adapters. Aura voices are selected via the model id (e.g. "aura-2-thalia-en"); there is no separate voice parameter.

Aura REST caps a single request at 2000 characters, so longer text is split on sentence/word boundaries. Raw concatenation is correct for streaming codecs (mp3, linear16/pcm, ogg-opus). WAV is handled specially: a multi-chunk WAV request is fetched as linear16 PCM and the joined PCM is wrapped in a single RIFF header (see encodeWAV), so the result is always one valid WAV.

func NewDeepgram added in v0.46.0

func NewDeepgram(opts DeepgramOpts) *Deepgram

NewDeepgram creates a Deepgram Aura TTS provider.

func (*Deepgram) CloseIdleConnections added in v0.46.0

func (d *Deepgram) CloseIdleConnections()

func (*Deepgram) Health added in v0.46.0

func (d *Deepgram) Health(ctx context.Context) error

func (*Deepgram) Kind added in v0.46.0

func (d *Deepgram) Kind() ProviderKind

func (*Deepgram) Name added in v0.46.0

func (d *Deepgram) Name() string

func (*Deepgram) Synthesize added in v0.46.0

func (d *Deepgram) Synthesize(ctx context.Context, text string, opts SynthesizeOpts) (*Result, error)

type DeepgramOpts added in v0.46.0

type DeepgramOpts struct {
	APIKey string
	Model  string // Aura-2 voice id, e.g. "aura-2-thalia-en"; empty => locale default
}

DeepgramOpts configures the Deepgram Aura TTS provider.

type EnabledProviders added in v0.46.0

type EnabledProviders struct {
	OpenAI      *OpenAIOpts
	Google      *GoogleOpts
	Deepgram    *DeepgramOpts
	HuggingFace *HuggingFaceOpts
	Piper       *PiperOpts
	// PreferredProfileID optionally pins the provider matching this
	// model_selection profile to the front of the strategy order.
	PreferredProfileID string
}

EnabledProviders carries the per-provider options a host has already resolved from its own config (env secrets, model/voice defaults). Nil fields are skipped. It lets the Device- and Server-Targets share one router-assembly path (BuildRouter) while each keeps its own config-resolution specifics.

type Google added in v0.46.0

type Google struct {
	BaseURL    string
	Validation netsec.ValidationOptions
	// contains filtered or unexported fields
}

Google implements Provider using the Google Cloud Text-to-Speech API.

BaseURL is configurable for testing. It is validated against Validation on every request. Default Validation is strict (public https only).

func NewGoogle added in v0.46.0

func NewGoogle(opts GoogleOpts) *Google

NewGoogle creates a Google Cloud TTS provider.

func (*Google) Capabilities added in v0.46.0

func (*Google) Capabilities() []speechkit.Capability

func (*Google) CloseIdleConnections added in v0.46.0

func (g *Google) CloseIdleConnections()

func (*Google) Health added in v0.46.0

func (g *Google) Health(ctx context.Context) error

func (*Google) Kind added in v0.46.0

func (g *Google) Kind() ProviderKind

func (*Google) Name added in v0.46.0

func (g *Google) Name() string

func (*Google) Synthesize added in v0.46.0

func (g *Google) Synthesize(ctx context.Context, text string, opts SynthesizeOpts) (*Result, error)

type GoogleOpts added in v0.46.0

type GoogleOpts struct {
	APIKey string
	Voice  string // e.g. "de-DE-Neural2-B", "en-US-Neural2-J"
}

GoogleOpts configures the Google TTS provider.

type HuggingFace added in v0.46.0

type HuggingFace struct {
	BaseURL    string
	Validation netsec.ValidationOptions
	// contains filtered or unexported fields
}

HuggingFace implements Provider using the HuggingFace Inference API with text-to-speech models (e.g. parler-tts).

BaseURL is configurable for testing. It is validated against Validation on every request. Default Validation is strict (public https only).

func NewHuggingFace added in v0.46.0

func NewHuggingFace(opts HuggingFaceOpts) *HuggingFace

NewHuggingFace creates a HuggingFace TTS provider.

func (*HuggingFace) Capabilities added in v0.46.0

func (*HuggingFace) Capabilities() []speechkit.Capability

func (*HuggingFace) CloseIdleConnections added in v0.46.0

func (h *HuggingFace) CloseIdleConnections()

func (*HuggingFace) Health added in v0.46.0

func (h *HuggingFace) Health(ctx context.Context) error

func (*HuggingFace) Kind added in v0.46.0

func (h *HuggingFace) Kind() ProviderKind

func (*HuggingFace) Name added in v0.46.0

func (h *HuggingFace) Name() string

func (*HuggingFace) Synthesize added in v0.46.0

func (h *HuggingFace) Synthesize(ctx context.Context, text string, opts SynthesizeOpts) (*Result, error)

type HuggingFaceOpts added in v0.46.0

type HuggingFaceOpts struct {
	Token string // HF API token
	Model string // Model ID, e.g. "Qwen/Qwen3-TTS-12Hz-1.7B-Base"
}

HuggingFaceOpts configures the HuggingFace TTS provider.

type OpenAI added in v0.46.0

type OpenAI struct {
	BaseURL    string
	Validation netsec.ValidationOptions
	// contains filtered or unexported fields
}

OpenAI implements Provider using the OpenAI TTS API.

BaseURL is configurable for testing. It is validated against Validation on every request. Default Validation is strict (public https only).

func NewOpenAI added in v0.46.0

func NewOpenAI(opts OpenAIOpts) *OpenAI

NewOpenAI creates an OpenAI TTS provider.

func (*OpenAI) Capabilities added in v0.46.0

func (*OpenAI) Capabilities() []speechkit.Capability

func (*OpenAI) CloseIdleConnections added in v0.46.0

func (o *OpenAI) CloseIdleConnections()

func (*OpenAI) Health added in v0.46.0

func (o *OpenAI) Health(ctx context.Context) error

func (*OpenAI) Kind added in v0.46.0

func (o *OpenAI) Kind() ProviderKind

func (*OpenAI) Name added in v0.46.0

func (o *OpenAI) Name() string

func (*OpenAI) Synthesize added in v0.46.0

func (o *OpenAI) Synthesize(ctx context.Context, text string, opts SynthesizeOpts) (*Result, error)

type OpenAIOpts added in v0.46.0

type OpenAIOpts struct {
	APIKey string
	Model  string // "tts-1" or "tts-1-hd"
	Voice  string // alloy, echo, fable, onyx, nova, shimmer
}

OpenAIOpts configures the OpenAI TTS provider.

type Piper added in v0.46.0

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

Piper implements Provider via the `piper` command-line binary. The binary writes a WAV PCM stream to stdout when invoked with

piper --model <voice.onnx> --output-raw < input.txt

or `--output_file -` for a WAV-wrapped stream. Phase 3 of the voice-companion roadmap uses Piper as the all-local TTS so the Voice-Companion can talk without any cloud key.

The implementation does NOT bundle voice models. Operators run `scripts/prepare-piper-voices.ps1` once to download the desired voices into PiperOpts.VoiceDir. Default voice maps to <VoiceDir>/ en_US-amy-medium.onnx; locale "de" looks up de_DE-thorsten-medium.

func NewPiper added in v0.46.0

func NewPiper(opts PiperOpts) (*Piper, error)

NewPiper validates the options and returns a ready Provider. The voice directory must already exist; missing voice models surface as a clear "voice file not found" error at Synthesize time, not at construction, so a missing en_DE voice does not prevent the provider from answering en_US requests.

func (*Piper) Capabilities added in v0.46.0

func (*Piper) Capabilities() []speechkit.Capability

func (*Piper) Health added in v0.46.0

func (p *Piper) Health(ctx context.Context) error

Health verifies the piper binary can be located. Voice-model presence is not checked here — operators may have a partial set installed and we still want /readyz to be green for the locales they DO have. Synthesize surfaces missing-voice errors per request.

func (*Piper) Kind added in v0.46.0

func (*Piper) Kind() ProviderKind

func (*Piper) Name added in v0.46.0

func (*Piper) Name() string

Name returns the provider identifier.

func (*Piper) Probe added in v0.46.0

func (p *Piper) Probe(ctx context.Context, voice, locale string) (*Result, error)

Probe runs piper with a short test phrase to verify the binary and the requested voice work end-to-end. Returns the synthesized WAV bytes (small — a few seconds of speech) on success. Used by the Settings UI to preview a voice without persisting any text.

func (*Piper) Synthesize added in v0.46.0

func (p *Piper) Synthesize(ctx context.Context, text string, opts SynthesizeOpts) (*Result, error)

Synthesize runs the piper subprocess for one utterance. The returned Result.Audio is a complete RIFF/WAVE PCM blob suitable for direct playback or HTTP delivery.

type PiperOpts added in v0.46.0

type PiperOpts struct {
	// Binary is the absolute or PATH-relative `piper` executable.
	// Empty defaults to "piper" (must be on $PATH).
	Binary string

	// VoiceDir is the filesystem root containing the .onnx voice
	// model files. Required.
	VoiceDir string

	// DefaultVoices maps a locale code (e.g. "en", "de") to a
	// voice-model filename inside VoiceDir. Falls back to the en_US
	// Amy medium voice when an entry is missing.
	DefaultVoices map[string]string

	// Timeout caps the subprocess execution. Zero defaults to 30 s
	// — generous because Piper warm-load on CPU can take several
	// seconds for a first synthesis.
	Timeout time.Duration
}

PiperOpts configures the local Piper subprocess.

type PiperVoiceInfo added in v0.46.0

type PiperVoiceInfo struct {
	Filename string `json:"filename"`
	Locale   string `json:"locale"`  // short code, e.g. "en", "de"
	Region   string `json:"region"`  // e.g. "US", "DE"; empty when missing
	Name     string `json:"name"`    // e.g. "amy", "thorsten"
	Quality  string `json:"quality"` // e.g. "low", "medium", "high"
	SizeKB   int    `json:"size_kb"`
}

PiperVoiceInfo is one entry from a voice-directory scan. Filename is the basename inside VoiceDir (e.g. "en_US-amy-medium.onnx"). The remaining fields are best-effort parses of the rhasspy/piper-voices naming convention <lang>_<REGION>-<name>-<quality>.onnx; when the filename does not follow that pattern only Filename is populated and the other fields remain empty.

func ListPiperVoices added in v0.46.0

func ListPiperVoices(voiceDir string) ([]PiperVoiceInfo, error)

ListPiperVoices scans voiceDir for *.onnx files and parses each filename using the piper-voices naming convention. The list is sorted by Filename so callers can present a stable UI. Returns an empty slice (not an error) when voiceDir is empty or missing — the UI surfaces "no voices installed" rather than a hard error.

type Provider

type Provider interface {
	Synthesize(ctx context.Context, text string, opts SynthesizeOpts) (*Result, error)
	Name() string
	Kind() ProviderKind
	Health(ctx context.Context) error
}

Provider defines the interface for text-to-speech backends.

func OrderByPreferredProvider

func OrderByPreferredProvider(providers []Provider, preferred string) []Provider

OrderByPreferredProvider returns providers with the matching provider first.

type ProviderKind

type ProviderKind string

ProviderKind identifies whether a provider is local, cloud-routed, or a direct external API. Router strategies use this instead of provider names.

const (
	ProviderKindLocalBuiltIn   ProviderKind = "local_built_in"
	ProviderKindLocalProvider  ProviderKind = "local_provider"
	ProviderKindCloudProvider  ProviderKind = "cloud_provider"
	ProviderKindDirectProvider ProviderKind = "direct_provider"
)

type ResolvedSynthesizeOptions added in v0.46.0

type ResolvedSynthesizeOptions struct {
	Locale    string
	Voice     string
	Speed     float64
	Format    string
	Effective provideropts.EffectiveOptions
}

func ResolveSynthesizeOptions added in v0.46.0

func ResolveSynthesizeOptions(provider, profileID string, opts SynthesizeOpts, providerDefaults, providerOverrides provideropts.Values) ResolvedSynthesizeOptions

type Result

type Result struct {
	Audio      []byte
	Format     string
	SampleRate int
	Duration   time.Duration
	Provider   string
	Voice      string
}

Result holds the output of a TTS synthesis.

type Router

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

Router selects and falls back between TTS providers.

func BuildRouter added in v0.46.0

func BuildRouter(strategy Strategy, enabled EnabledProviders) (router *Router, ok bool, notes []string)

BuildRouter is the single source of truth for assembling a TTS router from a set of enabled providers: it constructs each enabled provider in a stable order, applies optional model_selection pinning, and returns the router plus human-readable notes. ok is false (router nil) when nothing is enabled.

func NewRouter

func NewRouter(strategy Strategy, providers ...Provider) *Router

NewRouter creates a TTS router with the given strategy and providers.

func (*Router) CloseIdleConnections

func (r *Router) CloseIdleConnections()

CloseIdleConnections asks HTTP-backed providers to drop idle connection pools.

func (*Router) HealthCheck

func (r *Router) HealthCheck(ctx context.Context) map[string]error

HealthCheck returns health status for all providers.

func (*Router) SetProviders

func (r *Router) SetProviders(providers ...Provider)

SetProviders replaces the provider list.

func (*Router) Synthesize

func (r *Router) Synthesize(ctx context.Context, text string, opts SynthesizeOpts) (res *Result, err error)

Synthesize tries each eligible provider until one succeeds. Per-provider option overrides (SynthesizeOpts.ProviderOptionsByProvider) are applied to the selected provider, and an OpenTelemetry span records strategy/provider.

type Service

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

Service is a small stable facade over Router. It gives embedders one construction point while still letting them provide their own providers.

func NewService

func NewService(router *Router, opts ...ServiceOption) (*Service, error)

func (*Service) Router

func (s *Service) Router() *Router

func (*Service) Synthesize

func (s *Service) Synthesize(ctx context.Context, text string, opts ...SynthesizeOpts) (*Result, error)

type ServiceOption

type ServiceOption func(*Service)

func WithDefaultOpts

func WithDefaultOpts(opts SynthesizeOpts) ServiceOption

type Strategy

type Strategy string

Strategy determines how Router selects providers.

const (
	StrategyCloudFirst Strategy = "cloud-first"
	StrategyLocalFirst Strategy = "local-first"
	StrategyCloudOnly  Strategy = "cloud-only"
	StrategyLocalOnly  Strategy = "local-only"
)

type SynthesizeOpts

type SynthesizeOpts struct {
	Locale          string
	Voice           string
	Speed           float64
	Format          string
	Options         provideropts.Values
	ProviderOptions provideropts.Values
	// ProviderOptionsByProvider holds provider-keyed overrides that the Router
	// applies to the selected provider via ForProvider, so one request can
	// carry per-provider tuning without the caller knowing which provider wins.
	ProviderOptionsByProvider map[string]provideropts.Values
}

SynthesizeOpts configures a single TTS request.

func (SynthesizeOpts) ForProvider added in v0.46.0

func (o SynthesizeOpts) ForProvider(provider string) SynthesizeOpts

ForProvider returns a copy of opts with ProviderOptions merged from the provider-keyed overrides for the named provider. The Router calls this for the selected provider so per-provider tuning takes effect transparently.

Directories

Path Synopsis
Package ttscontract provides a reusable conformance suite that every tts.Provider implementation is expected to satisfy.
Package ttscontract provides a reusable conformance suite that every tts.Provider implementation is expected to satisfy.

Jump to

Keyboard shortcuts

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