/** * Wake Word Service — "ARIA" Erkennung * * Phase 1: Deaktiviert — react-native-live-audio-stream hat native Bridge-Probleme. * Nutzt stattdessen Tap-to-Talk (VoiceButton) als primaeren Eingabemodus. * * Phase 2: Porcupine on-device "ARIA" Keyword (geplant). */ 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[] = []; /** Wake Word Erkennung starten */ async start(): Promise { if (this.state === 'listening') return true; try { // Phase 1: LiveAudioStream deaktiviert (native Bridge instabil) // Stattdessen: Tap-to-Talk als primaerer Modus console.log('[WakeWord] Wake Word ist in Phase 1 noch nicht verfuegbar — nutze Tap-to-Talk'); this.setState('listening'); return true; } catch (err) { console.error('[WakeWord] Start fehlgeschlagen:', err); return false; } } /** Wake Word Erkennung stoppen */ stop(): void { this.setState('off'); } /** Nach Aufnahme erneut starten */ async resume(): Promise { // Nichts zu tun in Phase 1 } // --- 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;