Files
eve-alpha/docs/tts/TTS_VOICE_SELECTION_FIX.md
Aodhan Collins 66749a5ce7 Initial commit
2025-10-06 00:33:04 +01:00

273 lines
7.0 KiB
Markdown

# TTS Voice Selection Fix
## Issue
The selected TTS voice was not being used - EVE always used the creepy system default voice instead of the user's selected voice.
## Root Causes
1. **Default value handling** - The literal string `"default"` was being passed to the voice selection API instead of `undefined`
2. **Async voice loading** - Browser voices load asynchronously and weren't being properly awaited
3. **Voice matching** - The voice URI wasn't being matched correctly with the available voices
4. **Prefix handling** - Voice IDs with `browser:` prefix weren't being stripped before matching
## Fixes Applied
### 1. Fixed Default Voice Handling
**Before:**
```typescript
await ttsManager.speak(text, {
voiceId: ttsVoice || undefined, // ❌ "default" is truthy!
})
```
**After:**
```typescript
const voiceId = ttsVoice && ttsVoice !== 'default' ? ttsVoice : undefined
await ttsManager.speak(text, {
voiceId, // ✅ Properly handles "default"
})
```
### 2. Fixed Async Voice Loading
**Before:**
```typescript
const voices = window.speechSynthesis.getVoices() // ❌ Might be empty!
const voice = voices.find(v => v.voiceURI === options.voiceId)
```
**After:**
```typescript
const getVoicesAsync = (): Promise<SpeechSynthesisVoice[]> => {
return new Promise((resolve) => {
let voices = window.speechSynthesis.getVoices()
if (voices.length > 0) {
resolve(voices)
} else {
// Wait for voices to load
window.speechSynthesis.onvoiceschanged = () => {
voices = window.speechSynthesis.getVoices()
resolve(voices)
}
}
})
}
const voices = await getVoicesAsync() // ✅ Always has voices!
```
### 3. Added Debug Logging
Added console logs to help troubleshoot voice selection:
```typescript
console.log('Available voices:', voices.map(v => `${v.name} (${v.voiceURI})`))
console.log('Looking for voice:', options.voiceId)
console.log('Selected voice:', voice.name, voice.voiceURI)
```
### 4. Improved Voice Prefix Handling
```typescript
if (voiceId.startsWith('browser:')) {
provider = 'browser'
voiceId = voiceId.replace('browser:', '') // ✅ Strip prefix
console.log('Using browser TTS with voice:', voiceId)
}
```
### 5. Added Voice Status Indicator
In Settings, shows what type of voice is currently selected:
- "Using system default voice"
- "Using browser voice"
- "Using ElevenLabs voice"
## How to Use
### Step 1: Open Settings
Click the ⚙️ Settings icon in the top right.
### Step 2: Enable TTS
1. Scroll to **Voice Settings**
2. Check ✅ **Enable text-to-speech for assistant messages**
### Step 3: Select a Voice
**Option A: Use Browser Voices (Free)**
1. Open **TTS Voice Selection** dropdown
2. Look under **Browser Voices (Free)**
3. Select a voice like:
- "Google US English"
- "Microsoft David"
- "Alex" (macOS)
- etc.
**Option B: Use ElevenLabs Voices (Premium)**
1. Enter your ElevenLabs API key
2. Wait for voices to load
3. Look under **ElevenLabs Voices (Premium)**
4. Select a voice like:
- "Rachel - American (young)"
- "Adam - American (middle-aged)"
- etc.
### Step 4: Test
1. Close Settings
2. Send a message to EVE
3. Click the 🔊 speaker icon on the response
4. Should now use your selected voice!
## Troubleshooting
### Voice Still Not Working
**Check Console Logs:**
1. Open DevTools (F12)
2. Go to Console tab
3. Look for TTS-related logs:
```
TTS speak called with: {voiceId: "browser:...", provider: "browser"}
Available voices: [...]
Looking for voice: ...
Selected voice: ...
```
**Common Issues:**
1. **"Voice not found" warning**
- The voice URI doesn't match any available voices
- Try selecting a different voice
- Check that browser voices have loaded
2. **No voices in dropdown**
- Browser hasn't loaded voices yet
- Try refreshing the page
- Check browser permissions
3. **ElevenLabs voices not loading**
- Check API key is correct
- Check network connection
- Look for errors in console
### Default Voice Still Used
If you hear the "creepy default voice":
1. **Make sure you selected a voice**
- Default is intentionally left as system voice
- Choose a specific voice from the list
2. **Check the status message**
- Should show "Using browser voice" or "Using ElevenLabs voice"
- Not "Using system default voice"
3. **Verify voice is saved**
- Close and reopen Settings
- Check if your selection is still there
- If not, localStorage might be disabled
4. **Try a different voice**
- Some voices might not work on your system
- Try multiple voices to find one that works
### Platform-Specific Issues
**Linux:**
- May have limited browser voices
- Install `speech-dispatcher` for better TTS
- eSpeak voices might sound robotic
**macOS:**
- Best browser voice support
- Try "Alex" for high quality
- Many system voices available
**Windows:**
- Microsoft voices work well
- "Microsoft David" is good default
- Install additional voices via Windows Settings
## Testing Checklist
- [ ] "Default Voice" uses system default
- [ ] Browser voices work correctly
- [ ] Voice persists after page refresh
- [ ] Console logs show correct voice ID
- [ ] Multiple voices can be tested
- [ ] ElevenLabs voices work (if API key set)
- [ ] Status message shows correct voice type
## Technical Details
### Voice ID Format
**Default:**
```
"default"
```
**Browser Voice:**
```
"browser:Google US English"
```
**ElevenLabs Voice:**
```
"elevenlabs:21m00Tcm4TlvDq8ikWAM"
```
### Voice Matching Logic
1. Get all available voices (async)
2. Strip prefix from voice ID
3. Match by `voiceURI` first, then `name`
4. If no match, use system default
5. Log result for debugging
### Files Modified
- `src/lib/tts.ts` - Fixed voice selection logic
- `src/components/TTSControls.tsx` - Fixed default handling
- `src/components/SettingsPanel.tsx` - Added status indicator
## Benefits
✅ **Accurate voice selection** - Selected voice is actually used
✅ **Better voices** - Choose from many high-quality options
✅ **Debug friendly** - Console logs help troubleshoot
✅ **Clear feedback** - Status shows what's being used
✅ **Persistent** - Selection saved across sessions
## Example Console Output
**Successful voice selection:**
```
Playing TTS with voice: browser:Google US English
TTS speak called with: {voiceId: "browser:Google US English", provider: "browser"}
Using browser TTS with voice: Google US English
Available voices: ["Google US English (Google US English)", "Microsoft David (Microsoft David)", ...]
Looking for voice: Google US English
Selected voice: Google US English Google US English
```
**Using default:**
```
Playing TTS with voice: default
TTS speak called with: {voiceId: undefined, provider: "browser"}
```
## Summary
The TTS voice selection now works correctly! Users can choose from available browser voices or ElevenLabs voices, and the selected voice will actually be used for playback. The fix includes proper async voice loading, prefix handling, and helpful debug logging.
---
**Status**: ✅ Fixed
**Date**: October 5, 2025
**Version**: v0.2.0-rc