Architecture¶
whispa-pi is the appliance layer on top of whispa.
It injects a recorder, the whispa pipeline and a player into an Appliance loop, so the loop
itself is pure and testable while the audio I/O shells out to sox/ALSA.
flowchart LR
MIC(["🎙 mic"]) --> REC["Recorder<br/>(sox VAD / arecord)"]
REC --> P["whispa VoicePipeline<br/>whisper.cpp → Ollama → Piper"]
P --> PL["Player<br/>(aplay / sox)"]
PL --> SPK(["🔊 speaker"])
P -. loop .-> REC
Module map¶
| Module | Responsibility |
|---|---|
appliance.ts |
The Appliance loop (runOnce, loop), injected with recorder/pipeline/player |
audio.ts |
SoxVadRecorder / ArecordRecorder, AplayPlayer / SoxPlayer |
config.ts |
Layered config: defaults → JSON file → WHISPA_* env vars |
main.ts |
Wires whispa's real engines + audio and runs the loop (the whispa-pi bin) |
Design principles¶
- Pure loop, injected I/O —
Appliancedepends on interfaces, so it's unit-tested with fakes; no hardware needed for tests. - Reuse, don't fork — the STT/LLM/TTS orchestration comes from whispa (a git dependency).
- Any trigger —
runOnce()can be driven by VAD, a wake word, or a GPIO button. - Boot-ready — ships a systemd unit and an idempotent install script for Raspberry Pi OS.