Keep streaming TTS open; name the swappable-provider pattern
Utterances cross as chunks with an explicit terminator, so whole-utterance is a stream of one chunk and a streaming TTS needs no protocol change. Records what must not be built — a single-body download-then-play player — since that forecloses streaming silently. Also notes the transport is fully exercisable with espeak-ng or a canned WAV, so audio transport need not wait on GPT-SoVITS. The provider-behind-an-interface shape has now been picked three times independently, so it is named as the project idiom rather than re-derived. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013kj58Jugkic783b8ZrtTVZ
This commit is contained in:
+27
-9
@@ -138,17 +138,35 @@ The tablet is the media source, so it holds the aux cable whatever is decided
|
||||
about speech. Giving the Orin its own aux line would not free the display unit —
|
||||
it would add a second permanent cable to the car and leave the first one in place.
|
||||
|
||||
### TTS crosses as utterances, not as a stream
|
||||
### TTS crosses as chunked utterances
|
||||
|
||||
An utterance is short, finite, and fully synthesised before it is needed. So it
|
||||
ships as a **discrete object over the reliable channel**, not as a real-time audio
|
||||
stream: no jitter buffer, no underrun handling, no clock synchronisation, and a
|
||||
dropped packet is a retry rather than an audible gap.
|
||||
An utterance travels as a **sequence of chunks with an explicit terminator**, over
|
||||
the reliable channel. Not as one object, and not as a clock-synchronised audio
|
||||
stream.
|
||||
|
||||
The cost is that speech begins only once synthesis *and* transfer complete. For a
|
||||
car assistant that is fine — nothing here is lip-synced. If streaming TTS is ever
|
||||
wanted, so that speech starts before synthesis finishes, this is the decision to
|
||||
revisit.
|
||||
This is deliberately the shape that keeps both modes open, because whole-utterance
|
||||
is simply a stream of one chunk:
|
||||
|
||||
| TTS capability | What it sends |
|
||||
|---|---|
|
||||
| Synthesises fully, then returns | one chunk, then terminator |
|
||||
| Streams as it synthesises | chunks as produced, then terminator |
|
||||
|
||||
Same protocol, same receiver. The receiver starts playback on the first chunk,
|
||||
appends as more arrive, and finishes on the terminator — which is what Android's
|
||||
`AudioTrack` streaming mode does natively.
|
||||
|
||||
**What must not be built:** an utterance as a single response body with a
|
||||
"download the file, then play the file" player. That works today and forecloses
|
||||
streaming permanently. Whether the TTS we land on streams is still open, so the
|
||||
transport must not assume either way.
|
||||
|
||||
### The transport is testable with no real TTS
|
||||
|
||||
Audio is the lowest-priority part of the system, but its transport does not have
|
||||
to wait for GPT-SoVITS. A canned WAV, or `espeak-ng` — instant, tiny, and awful —
|
||||
exercises chunking, ordering, the terminator, ducking and the no-sink path
|
||||
completely. Voice quality is irrelevant to every one of those.
|
||||
|
||||
### Ducking is the tablet's job
|
||||
|
||||
|
||||
Reference in New Issue
Block a user