Every pictogram on the ComuniTEA board speaks. When a child taps a pictogram, the app resolves the audio through a three-tier priority chain: first a bundled MP3 file pre-packaged with the app (zero latency, no network required), then a neural text-to-speech call to ElevenLabs via a Supabase Edge Function (high-quality online synthesis), and finally the Expo Speech system TTS as a last-resort fallback. Voice settings control which neural voice profile is active — female or male — and that choice propagates to all three tiers, ensuring a consistent, familiar voice whether the device is online or not.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ElthonJohan/comunitea/llms.txt
Use this file to discover all available pages before exploring further.
Voice Profiles
ComuniTEA exposes two neural voice profiles via theVoiceProfile type, defined in constants/AudioAssets.ts:
| Profile | VoiceProfile value | Description |
|---|---|---|
| Female voice | femenina | Adult female tone — the default profile |
| Male voice | masculina | Adult male tone |
Voice Selection Screen
The Voice Selection screen (app/voice-selection.tsx) is the very first interactive screen a new user sees — it appears before the onboarding wizard on first launch. It can also be accessed later from Settings → General → Voz de pictogramas.
Selecting a profile calls setVoice(voiceType) and writes the preference to AsyncStorage under STORAGE_KEYS.VOICE_PREFERENCE:
Audio Resolution Priority Order
When theuseSpeech() hook is asked to play a pictogram, it follows this resolution order:
Bundled MP3 file (local asset)
useSpeech calls getAudioAssets(voice) to obtain the asset map for the active VoiceProfile. If a module ID exists for the given pictogram id, it resolves the local file path with bundledModuleToPlayableUri() and plays it immediately using expo-audio’s AudioPlayer. No network call is made.ElevenLabs TTS via Supabase Edge Function
If no bundled clip exists for the given text/ID — for example, a custom pictogram the caregiver created — The Edge Function returns raw MP3 audio bytes. The hook writes them to a temporary file in
playWithElevenLabs() is called. It posts to the elevenlabs-tts Supabase Edge Function with the text, the voice ID, and the current TTS speed from parental settings:documentDirectory and plays them with expo-audio. The temp file is deleted immediately after playback.Expo Speech system TTS fallback
If the device has no internet connection (Pitch is adjusted per profile:
isConnected === false) or if the ElevenLabs request fails (non-200 status or network error), fallbackSpeech() is called. This uses expo-speech with the system TTS engine:1.2 for femenina, 0.8 for masculina.Bundled Audio Asset Coverage
Each voice profile ships with over 500 pre-recorded MP3 clips, organised by category insideassets/audio/{voice}/. The categories mirror the communication board structure:
| Folder | Examples |
|---|---|
dashboard/ | comida, emociones, bano, jugar, ropa, numeros, colores |
core/ | core-yo, core-quiero, core-no, core-gracias, core-hola |
yo/ | tengo-hambre, tengo-sed, me-duele, estoy-cansado |
emociones/ | feliz, triste, enojado, asustado, calma, alegria |
comida/frutas/ | manzana, platano, fresas, naranja, mango, pina |
comida/verduras/ | zanahoria, lechuga, tomate, brocoli, espinaca |
comida/bebidas/ | agua, leche, jugo, chocolatada, gaseosa |
ropa/ | polo, pantalon, zapatos, casaca, chompa, vestido |
baño/ | inodoro, papel, ducharse, lavado, dientes |
dormir/ | cama, pijama, luz, osito, silencio |
personas/ | hermano, hermana, abuela, abuelo, maestra, amigo |
social/ | hola, adios, gracias, por-favor, si, no |
avanzado/ | Verbs, school items, agenda days, conversation starters, help phrases |
femenina and masculina asset maps are defined identically in constants/AudioAssets.ts. getAudioAssets(profile) merges the requested profile’s map over the femenina base, so any missing entry in masculina gracefully falls back to the female recording.
VoiceContext and the useVoice() Hook
Voice preference is persisted through a Zustand store (stores/settingsStore.ts) that reads and writes from AsyncStorage using a custom voiceLegacyStorage adapter. This keeps the stored format as a plain string ('femenina' or 'masculina') for backwards compatibility.
useVoice() hook from lib/hooks/useVoice.ts:
isLoading is true until the store’s hydrated flag is set by onRehydrateStorage, so components can gate audio playback until the preference is confirmed.
ElevenLabs Configuration
Theelevenlabs-tts Supabase Edge Function requires an ELEVENLABS_API_KEY environment variable set in the Supabase dashboard (Project → Edge Functions → Secrets). The voice IDs used for each profile are imported from lib/speakFrasePhrase.ts:
Authorization header. If the session has expired, useSpeech refreshes it before the call.
Offline mode: All 500+ bundled MP3 clips in
assets/audio/ are packaged directly with the app binary. As long as the pictogram has a corresponding bundled asset key, audio playback works with no internet connection whatsoever. Only custom pictograms added by the caregiver — which have no pre-recorded clip — require network access for ElevenLabs TTS. When offline, those fall back to the system speech engine.TTS Playback Speed
Voice speed is a parental setting (not a child-facing preference) stored inparental_settings.tts_speed as a numeric(3,1) between 0.5 and 2.0. Four speed presets are available from Settings → Configuración sensorial → Velocidad de la voz:
| Label | Multiplier |
|---|---|
| Muy lenta | 0.6× |
| Lenta | 0.8× |
| Normal | 1.0× (default) |
| Rápida | 1.2× |
ttsSpeed value from useParental().settings is passed to both the ElevenLabs request body and the expo-speech rate option, so all three audio tiers honour the same speed setting.