/** * Gespraechsmodus — "Ohr-Button" * * Wenn aktiv: Nach jeder ARIA-Antwort (TTS fertig) startet automatisch die Aufnahme. * Wie ein Walkie-Talkie / natuerliches Gespraech: * ARIA spricht → Aufnahme startet → User spricht → VAD stoppt → ARIA antwortet → ... * * Phase 2 (geplant): Porcupine "ARIA" Wake Word fuer passives Lauschen. */ type WakeWordCallback = () => void; type StateCallback = (state: WakeWordState) => void; export type WakeWordState = 'off' | 'listening' | 'detected'; class WakeWordService { private state: WakeWordState = 'off'; private wakeCallbacks: WakeWordCallback[] = []; private stateCallbacks: StateCallback[] = []; /** Gespraechsmodus starten */ async start(): Promise { if (this.state === 'listening') return true; console.log('[WakeWord] Gespraechsmodus aktiviert — Aufnahme startet nach ARIA-Antwort'); this.setState('listening'); return true; } /** Gespraechsmodus stoppen */ stop(): void { console.log('[WakeWord] Gespraechsmodus deaktiviert'); this.setState('off'); } /** Nach ARIA-Antwort (TTS fertig): Aufnahme automatisch starten */ async resume(): Promise { if (this.state !== 'listening') return; // Kurze Pause damit TTS-Audio nicht ins Mikrofon geht await new Promise(resolve => setTimeout(resolve, 800)); if (this.state === 'listening') { console.log('[WakeWord] TTS fertig — starte automatisch Aufnahme'); this.wakeCallbacks.forEach(cb => cb()); } } isActive(): boolean { return this.state === 'listening'; } // --- Callbacks --- onWakeWord(callback: WakeWordCallback): () => void { this.wakeCallbacks.push(callback); return () => { this.wakeCallbacks = this.wakeCallbacks.filter(cb => cb !== callback); }; } onStateChange(callback: StateCallback): () => void { this.stateCallbacks.push(callback); return () => { this.stateCallbacks = this.stateCallbacks.filter(cb => cb !== callback); }; } getState(): WakeWordState { return this.state; } private setState(state: WakeWordState): void { if (this.state !== state) { this.state = state; this.stateCallbacks.forEach(cb => cb(state)); } } } const wakeWordService = new WakeWordService(); export default wakeWordService;