← Back to docs

Voice/AI · voice

Portal Voice — Speech Interaction Pipeline

Complete voice interaction layer: wake word detection, VAD (Silero on QNN DSP), STT (Sherpa-onnx Zipformer on CPU), NLU (MiniLM sentence similarity), TTS (Elara VITS on QNN DSP), and voice state machine. Hosts portal-voiced daemon.

portal-voicev0.5.0voice
25.4K
Lines of Code
907
Tests
167
Files

Architecture

25+ modules organized by function: audio pipeline (audio_io, preprocessing/RNNoise, mic_controller), detection (vad/Silero, wake_word), recognition (stt/Sherpa-onnx), understanding (nlu/MiniLM classifier, clarification, address_detection), synthesis (tts/Elara VITS engine, tts_arbitration), NPU (npu_backend, npu_scheduler for DSP arbitration), infrastructure (config, error, error_recovery, ipc, integration, subprocess_integrity, telemetry), state management (voice, voice_state/VoiceStateMachine, types). The VoiceStateMachine manages transitions between Idle, Listening, Processing, Speaking states.

Overview

portal-voice implements the full voice interaction pipeline for Portal. Audio arrives from the glasses' microphone via UDP (:5601), gets denoised by RNNoise, then processed by a VAD (Voice Activity Detection) running on the QNN DSP (Silero model). When speech is detected, Sherpa-onnx Zipformer performs STT (Speech-to-Text) on CPU. The transcript is classified by a MiniLM NLU (Natural Language Understanding) classifier using sentence similarity against 28 intent categories. Based on the classified intent, the system either executes a system command, launches an app via gtk-launch, queries the LLM via IPC, or produces a canned response. Responses are synthesized via Elara VITS TTS (encoder on QNN DSP, decoder via onnxruntime-qnn plugin), resampled to 48kHz, and streamed back to the glasses via RTP/UDP.

Key Types

VoiceTop-level voice subsystem coordinator — owns the audio pipeline, VAD, STT, NLU, and TTS components.
VoiceConfigConfiguration for the voice pipeline — model paths, audio format, NPU settings, NLU thresholds.
VoiceStateMachineState machine: Idle → Listening → Processing → Speaking → Idle. Manages mic control and TTS arbitration.
MicControllerMicrophone control — manages audio capture from glasses UDP stream, noise gate, gain control.
IntentTaxonomy28-intent taxonomy for NLU classification — SystemCommand, LaunchApp, Query, etc.
VoiceErrorError type for voice operations — model loading failures, NPU errors, IPC failures, audio device errors.

Modules

vad

Voice Activity Detection — Silero VAD model on QNN DSP (Hexagon). Detects speech segments in audio stream.

stt

Speech-to-Text — Sherpa-onnx Zipformer model on CPU (A76/Oryon cores). Streaming transcription of detected speech.

nlu

Natural Language Understanding — MiniLM sentence similarity classifier. 28 intents, cosine similarity matching, slot extraction.

tts

Text-to-Speech — Elara VITS engine. Encoder on QNN DSP, decoder via onnxruntime-qnn. 22050Hz output, resampled to 48kHz for glasses.

wake_word

Wake word detection — listens for activation phrase before starting full pipeline.

preprocessing

Audio preprocessing — RNNoise denoising, format conversion, sample rate adjustment.

audio_io

Audio I/O — UDP audio reception from glasses (:5601), RTP audio transmission to glasses (:5002).

mic_controller

Microphone controller — manages audio capture, noise gate, automatic gain control.

npu_backend

NPU backend abstraction — QNN model loading, context management, tensor I/O.

npu_scheduler

NPU scheduler — arbitrates DSP access between VAD, TTS encoder, and LLM to prevent context conflicts.

voice_state

Voice state machine — Idle/Listening/Processing/Speaking transitions, mic control coordination.

tts_arbitration

TTS arbitration — prevents overlapping speech, queues responses, handles interruption.

clarification

Clarification handler — asks follow-up questions when NLU confidence is low or slots are missing.

address_detection

Address detection — determines if user is addressing Portal ('Hey Elara') vs. talking to someone else.

error_recovery

Error recovery — handles NPU failures, model reload, graceful degradation.

subprocess_integrity

Subprocess integrity — validates GenieX Python subprocess health, restarts on crash.

telemetry

Telemetry — latency tracking, classification accuracy, RTF (Real-Time Factor) measurement.

Data Flow

Glasses → UDP audio (:5601) → RNNoise → VAD (QNN DSP) → Sherpa STT (CPU) → MiniLM NLU → [SystemCommand|LaunchApp|LLM IPC|canned] → TTS encoder (QNN DSP) → TTS decoder (onnxruntime-qnn) → RTP → glasses (:5002)

Dependencies

External (21)

tokio workspaceserde workspaceserde_json workspacethiserror workspacetracing workspacetracing-subscriber workspacesha2 workspacehmac workspacehkdf workspacex25519-dalek workspacehex 0.4parking_lot workspacecrossbeam-channel 0.5postcard workspacelibc 0.2ort workspacelibloading 0.8piper-plus-g2p 0.4rand 0.8opus 0.3tokenizers 0.21

External: sherpa-onnx (STT), ort/onnxruntime (NLU/TTS decoder), tokenizers (MiniLM). NPU: QNN SDK (.so models), rnnoise-sys, qnn-sys. Build: cargo build --features 'qnn-tts,qnn-vad,npu-stt,network-audio,nlu-minilm' --bin portal-voiced