Documentation
¶
Overview ¶
Package wyoming implements the Wyoming voice protocol so an ESPHome voice satellite (mediated by Home Assistant's Assist pipeline) can use speechkit-server as its STT and TTS backend.
Wyoming is a peer-to-peer, event-driven protocol spoken over a raw TCP socket (also Unix socket / stdio upstream; this adapter uses TCP). Each event is a JSON header line terminated by '\n', optionally followed by a JSON "data" segment and a binary payload:
{"type":"audio-chunk","data_length":42,"payload_length":2048}\n
<42 bytes of JSON data><2048 bytes of PCM>
wire.go is deliberately OS-agnostic and carries no build tag so the framing codec — the highest-risk part for interop — can be unit-tested on any platform. The TCP server, and the STT/TTS bridges that reach the kernel routers, are Linux-tagged (server target).
Wire-format note: upstream producers vary on whether the "data" object is inline in the header line or a separate length-delimited segment. WriteEvent emits the separate-segment form used by the reference `wyoming` Python library (what Home Assistant speaks); ReadEvent accepts BOTH an inline "data" object and a "data_length" segment so this adapter interoperates with either. Validate against a captured wyoming-faster-whisper / wyoming-piper frame before relying on it in production (see wire_test.go).
Index ¶
- Constants
- func WriteEvent(w io.Writer, ev *Event) error
- type AsrModel
- type AsrProgram
- type Attribution
- type AudioChunk
- type AudioStart
- type AudioStop
- type Event
- type Info
- type Options
- type Reader
- type Server
- type SynthVoice
- type Synthesize
- type Synthesizer
- type Transcribe
- type Transcriber
- type Transcript
- type TtsProgram
- type TtsVoice
Constants ¶
const ( TypeDescribe = "describe" TypeInfo = "info" TypeTranscribe = "transcribe" TypeTranscript = "transcript" TypeAudioStart = "audio-start" TypeAudioChunk = "audio-chunk" TypeAudioStop = "audio-stop" TypeSynthesize = "synthesize" )
Wyoming event types used by the STT (asr) and TTS backends.
const ( // DefaultMaxSegment caps the data + payload segment sizes when a Reader is // created without an explicit limit. DefaultMaxSegment = 1 << 20 // 1 MiB )
Defaults for the read-side safety caps. A misbehaving or hostile peer must not be able to make the reader allocate unbounded memory from a single frame.
Variables ¶
This section is empty.
Functions ¶
func WriteEvent ¶
WriteEvent writes one framed event to w and returns the write error, if any. It emits the separate-segment form: header line, then the data segment (when Data is non-empty), then the payload (when non-empty). The caller is responsible for flushing a buffered writer.
Types ¶
type AsrProgram ¶
type Attribution ¶
Attribution is the model/service credit block present throughout the Wyoming info schema.
type AudioChunk ¶
type AudioStart ¶
type AudioStart struct {
Rate int `json:"rate"`
Width int `json:"width"`
Channels int `json:"channels"`
Timestamp *int `json:"timestamp,omitempty"`
}
AudioStart / AudioChunk / AudioStop carry the PCM stream. Chunk audio bytes travel in the Event.Payload, not in Data.
type Event ¶
type Event struct {
Type string
Data json.RawMessage
Payload []byte
}
Event is one Wyoming message: a type, an optional structured data object (raw JSON), and an optional binary payload (PCM for audio events).
type Info ¶
type Info struct {
ASR []AsrProgram `json:"asr,omitempty"`
TTS []TtsProgram `json:"tts,omitempty"`
}
Info is the reply to a `describe` event: it advertises the asr and/or tts programs this server exposes so Home Assistant can register STT/TTS entities.
type Options ¶
type Options struct {
STT Transcriber
TTS Synthesizer
Info Info
DefaultVoice string
DecodeLimits audio.DecodeLimits
MaxSegment int
// AllowedCIDRs, when non-empty, restricts which peers may connect. Wyoming
// has no in-protocol auth, so this is the adapter's only access control
// beyond binding to a trusted interface.
AllowedCIDRs []*net.IPNet
}
Options configures a Wyoming server. STT and/or TTS may be nil; the paired program is simply not advertised in Info and its events are ignored.
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
Reader reads framed Wyoming events from a buffered stream with bounded per-segment allocation.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server accepts Wyoming TCP connections and bridges STT/TTS to the kernel routers. One goroutine per connection; a connection handles a describe handshake and either an STT turn (transcribe → audio-* → transcript) or a TTS turn (synthesize → audio-*).
type SynthVoice ¶
type Synthesize ¶
type Synthesize struct {
Text string `json:"text"`
Voice *SynthVoice `json:"voice,omitempty"`
}
Synthesize requests TTS for Text in the optional Voice.
type Synthesizer ¶
type Synthesizer interface {
Synthesize(ctx context.Context, text string, opts tts.SynthesizeOpts) (*tts.Result, error)
}
Synthesizer is the minimal TTS surface; satisfied by *internal/tts.Router.
type Transcribe ¶
type Transcribe struct {
Name string `json:"name,omitempty"`
Language string `json:"language,omitempty"`
}
Transcribe starts an STT turn; both fields are optional hints.
type Transcriber ¶
type Transcriber interface {
Route(ctx context.Context, audio []byte, audioDurationSecs float64, opts stt.TranscribeOpts) (*stt.Result, error)
}
Transcriber is the minimal STT surface the Wyoming adapter needs; satisfied by *internal/router.Router. Mirrors internal/server/dictation.Transcriber so the same batch router backs both HTTP dictation and Wyoming STT.
type Transcript ¶
type Transcript struct {
Text string `json:"text"`
}
Transcript is the STT result sent back after audio-stop.