diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index e770ef4..69f9085 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -279,7 +279,7 @@ rewriting the document. | 9 | Nav guidance published on the bus; route requests over HTTP via `telemetry-gw` | **Proposed** | 2026-09-03 | | 10 | Map artifacts delivered by `rsync` over LAN only; Valhalla tiles kept as a directory, not a tar | Accepted | 2026-09-03 | | 11 | Boot ordering is capture-first: acquisition reaches ready before serving or voice | Accepted | 2026-09-03 | -| 12 | The Orin owns the car's aux input; the display unit carries no permanent cable | Accepted | 2026-09-03 | +| 12 | The **tablet** owns the car's aux input; TTS crosses as discrete utterances, not a stream | Accepted | 2026-09-04 | | 13 | Reasoning stays in the cloud — a local LLM does not fit beside the voice stack | Accepted | 2026-09-03 | | 14 | Recordings are bounded with rotation | Accepted | 2026-09-04 | | 15 | Boundary is two simplex channels — lossy stream down, acknowledged request/response up | Accepted | 2026-09-03 | diff --git a/docs/ORIN-RUNTIME.md b/docs/ORIN-RUNTIME.md index 05a8dbf..5f5cfcf 100644 --- a/docs/ORIN-RUNTIME.md +++ b/docs/ORIN-RUNTIME.md @@ -122,26 +122,54 @@ have run. Two properties matter more than the specific size: ## Audio -The Orin owns the car's single aux input, via a USB DAC. +The **tablet** owns the car's single aux input. It is the music player, and that +role is not moving to the Orin. ``` - GPT-SoVITS (TTS) ──┐ - ├──▶ PipeWire mixer ──▶ USB DAC ──▶ aux in - A2DP sink ─────────┘ │ - (media from the tablet) └── ducking: media drops under TTS + tablet: media (Spotify etc.) ──┐ + ├──▶ Android mixer ──▶ aux in + Orin: GPT-SoVITS (TTS) ──────┘ + └── utterances sent over the reliable boundary channel - mic ──▶ Whisper (ASR) + Orin: mic ──▶ Whisper (ASR) stays local, never crosses ``` -Three reasons the aux cable belongs here rather than on the tablet: +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. -- **The aux cable should belong to the fixed unit.** The display is meant to be - removable; anything holding a permanent cable to the car is not removable. -- **Ducking becomes a local policy** on one box instead of coordination between - two. Without it the assistant talks over the music. -- **The direction works.** Linux is a capable A2DP *sink*, so the tablet can send - media here. The reverse — this box as an A2DP source into an Android sink — is - not viable, since stock Android builds generally do not enable A2DP sink. +### TTS crosses as utterances, not as a stream -Unplug the tablet and the car keeps audio and voice. The Orin depends on the -display unit for nothing. +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. + +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. + +### Ducking is the tablet's job + +Android's `AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK` ducks other applications' audio — +Spotify included — for the duration of a request, then restores it. This is the +mechanism every navigation app already uses, and it is less work than the PipeWire +policy it replaces. Cross-application ducking is a solved problem on the tablet +and would have been a bespoke one on the Orin. + +### The microphone stays on the Orin + +Whisper runs on the Orin, so its input does too. Audio *in* on one box and audio +*out* on the other is asymmetric on purpose: each side does the simple thing, and +a microphone has no reason to reach the head unit. + +### Degrade when there is no sink + +With no tablet connected the Orin can still hear — the mic is local — but cannot +speak. The voice stack expires or drops pending utterances rather than queueing +them unboundedly or blocking on a sink that may never arrive. + +The consequence to accept: **unplug the tablet and the car has no voice.** That is +tolerable because unplugging it also removes the music, so the tablet was already +load-bearing for audio. Speech does not make it more so.