/** * Sherpa TTS Service - STUB for Expo Go development * The real implementation requires native modules which don't work in Expo Go * This stub returns "not available" so the app falls back to expo-speech */ // Available Piper neural voices - kept for type compatibility export interface PiperVoice { id: string; name: string; description: string; modelDir: string; onnxFile: string; gender: 'male' | 'female'; accent: string; } export const AVAILABLE_VOICES: PiperVoice[] = [ { id: 'lessac', name: 'Lessac', description: 'American Female (Natural)', modelDir: 'vits-piper-en_US-lessac-medium', onnxFile: 'en_US-lessac-medium.onnx', gender: 'female', accent: 'US', }, ]; interface SherpaTTSState { initialized: boolean; initializing: boolean; error: string | null; } let currentState: SherpaTTSState = { initialized: false, initializing: false, error: 'Sherpa TTS disabled for Expo Go development', }; // State listeners const stateListeners: ((state: SherpaTTSState) => void)[] = []; function notifyListeners() { stateListeners.forEach(listener => listener({ ...currentState })); } export function addStateListener(listener: (state: SherpaTTSState) => void) { stateListeners.push(listener); listener({ ...currentState }); return () => { const index = stateListeners.indexOf(listener); if (index >= 0) stateListeners.splice(index, 1); }; } export function getState(): SherpaTTSState { return { ...currentState }; } // Stub implementations - always return false/unavailable export async function initializeSherpaTTS(): Promise { console.log('[SherpaTTS STUB] Sherpa TTS disabled for Expo Go - using expo-speech instead'); return false; } export async function speak( text: string, options?: { speed?: number; speakerId?: number; onStart?: () => void; onDone?: () => void; onError?: (error: Error) => void; } ): Promise { options?.onError?.(new Error('Sherpa TTS disabled for Expo Go')); } export function stop(): void { // No-op } export function deinitialize(): void { // No-op } export function isAvailable(): boolean { return false; } export function getCurrentVoice(): PiperVoice { return AVAILABLE_VOICES[0]; } export async function setVoice(voiceId: string): Promise { return false; } export async function loadSavedVoice(): Promise { return AVAILABLE_VOICES[0]; } export default { initialize: initializeSherpaTTS, speak, stop, deinitialize, isAvailable, addStateListener, getState, getVoices: () => AVAILABLE_VOICES, getCurrentVoice, setVoice, loadSavedVoice, };