Initial commit

This commit is contained in:
Aodhan Collins
2025-10-06 00:33:04 +01:00
commit 66749a5ce7
71 changed files with 22041 additions and 0 deletions

View File

@@ -0,0 +1,278 @@
# 🎧 TTS Conversation Mode
## Overview
EVE now supports **Audio Conversation Mode** - an immersive listening experience where assistant responses automatically play as audio with text hidden by default, similar to talking with a voice assistant like Alexa or Siri.
## Features
### Auto-Play Audio
- ✅ Assistant responses automatically start playing when received
- ✅ No manual clicking on speaker icon required
- ✅ Seamless conversation flow
### Hidden Text by Default
- ✅ Text is hidden by default to focus on audio
- ✅ "Show Text" / "Hide Text" toggle button on each message
- ✅ Text can be revealed anytime with one click
- ✅ Visual indicator shows Audio Mode is active
### Visual Feedback
- ✅ Animated pulsing audio controls during playback
- ✅ Purple "Audio Mode" badge on messages
- ✅ Pulsing volume icon on mode toggle button
- ✅ Loading spinner during audio generation
### Mode Toggle Options
**Option 1: Quick Toggle Button**
- Located above chat input (when TTS enabled)
- Click to instantly switch modes
- Visual states:
- 🔊 Purple gradient + pulsing = Audio Mode ON
- 📄 Gray = Text Mode (normal)
**Option 2: Settings Panel**
- Settings → Voice Settings
- Checkbox: "🎧 Audio Conversation Mode"
- Description explains functionality
## How to Use
### Enabling Audio Mode
**Quick Method:**
1. Enable TTS in Settings
2. Click the mode toggle button above input
3. Purple gradient + pulsing icon = Audio Mode active
**Settings Method:**
1. Open Settings (⚙️)
2. Go to Voice Settings
3. Enable "Text-to-speech"
4. Check "🎧 Audio Conversation Mode"
### Using Audio Mode
1. **Send a message** as normal
2. **Assistant responds** - Audio auto-plays automatically
3. **Text is hidden** - Focus on listening
4. **Want to see text?** Click "Show Text" button
5. **Hide text again?** Click "Hide Text" button
6. **Control playback** using pause/stop buttons
### Switching Modes
**To Audio Mode:**
- Click toggle button (shows 🔊)
- Or check box in Settings
**To Text Mode:**
- Click toggle button (shows 📄)
- Or uncheck box in Settings
## Visual Indicators
### Audio Mode Active
- **Toggle button**: Purple gradient with pulsing 🔊 icon
- **Messages**: Purple "Audio Mode" badge
- **Controls**: Pulsing animation during playback
- **Text**: Hidden with "Show Text" button visible
### Text Mode Active
- **Toggle button**: Gray with 📄 icon
- **Messages**: Normal display with text visible
- **Controls**: Standard speaker icon (click to play)
## Use Cases
### Hands-Free Interaction
- Listen while working on other tasks
- Accessibility for visually impaired users
- Multitasking while getting information
### Language Learning
- Hear pronunciation naturally
- Focus on listening comprehension
- Reduce reading, increase hearing
### Driving/Commuting
- Safe voice-only interaction
- No need to read screen
- Conversational experience
### Preference
- Some users prefer audio over reading
- More natural conversation feel
- Less eye strain
## Technical Details
### Auto-Play Implementation
```typescript
// In ChatMessage component
{ttsConversationMode && (
<TTSControls
autoPlay={true} // Triggers auto-play on mount
text={message.content}
/>
)}
```
### Text Visibility Toggle
```typescript
const [isTextVisible, setIsTextVisible] = useState(!ttsConversationMode)
// Button to toggle
<button onClick={() => setIsTextVisible(!isTextVisible)}>
{isTextVisible ? 'Hide Text' : 'Show Text'}
</button>
// Conditional rendering
{isTextVisible && <MessageContent content={message.content} />}
```
### Auto-Play Trigger
```typescript
// In TTSControls component
useEffect(() => {
if (autoPlay && voiceEnabled && !isPlaying && !isLoading) {
const timer = setTimeout(() => {
handlePlay() // Start playing after 500ms delay
}, 500)
return () => clearTimeout(timer)
}
}, []) // Only run on mount
```
## Settings Persistence
Audio Mode preference is:
- ✅ Saved to localStorage
- ✅ Persists across sessions
- ✅ Synced between toggle button and settings
- ✅ Independent of TTS enabled state
```typescript
// Settings store
ttsConversationMode: boolean // Defaults to false
```
## Behavior Details
### When Audio Mode is ON
1. **User sends message**
2. **Assistant responds**
3. **TTS auto-plays** (500ms delay for initialization)
4. **Text is hidden**
5. **Controls show** pause/stop buttons
6. **User can**:
- Show/hide text anytime
- Control playback (pause/resume/stop)
- Continue normal conversation
### When Audio Mode is OFF
1. **User sends message**
2. **Assistant responds**
3. **Text is shown** immediately
4. **No auto-play**
5. **User can** click speaker icon to manually play
## Limitations
### Current Limitations
- Auto-play only works if TTS is enabled
- Requires valid TTS voice selection
- Browser may block auto-play (user gesture required first time)
- One message plays at a time
### Future Enhancements
- **Queue system** - Auto-play multiple messages
- **Speed controls** during playback
- **Skip forward/back** buttons
- **Transcript following** - Highlight words as spoken
- **Voice response** - Auto-enable STT after assistant speaks
- **Conversation history** - Audio mode for old messages
## Troubleshooting
### Audio Not Auto-Playing
**Check:**
- ✅ TTS is enabled in settings
- ✅ Voice is selected (not "default")
- ✅ Audio Mode is ON (purple button)
- ✅ ElevenLabs API key configured (for ElevenLabs voices)
**Try:**
- Click speaker icon manually once (browser permission)
- Reload page
- Check browser console for errors
### Text Not Hiding
**Check:**
- ✅ Audio Mode is actually enabled
- ✅ Purple badge shows "Audio Mode"
- ✅ New messages (existing messages don't update)
**Try:**
- Send new message
- Toggle mode off and on
- Refresh page
### Controls Not Showing
**Check:**
- ✅ TTS is enabled
- ✅ Message is from assistant (not user)
### Mode Toggle Button Not Visible
**Check:**
- ✅ TTS is enabled in settings
- Only shows when `voiceEnabled === true`
## Tips
### Best Experience
1. **Use ElevenLabs voices** for highest quality
2. **Adjust speed** in settings for comfortable listening
3. **Enable continuous STT** for hands-free input
4. **Use quality headphones** for best audio
5. **Start with short messages** to test
### Recommended Settings
```
Audio Mode: ON
TTS Voice: ElevenLabs (any)
TTS Model: eleven_turbo_v2_5
Speed: 1.0x - 1.25x
Stability: 50%
Clarity: 75%
```
## Examples
### Audio-First Workflow
1. Enable Audio Mode
2. Ask: "Explain quantum computing"
3. Listen to audio explanation
4. If needed, click "Show Text" for reference
5. Ask follow-up question
6. Repeat
### Reading + Listening
1. Keep Audio Mode ON
2. Click "Show Text" on messages
3. Read while listening
4. Best for learning/comprehension
### Pure Audio Experience
1. Enable Audio Mode
2. Enable Continuous STT
3. Never touch keyboard
4. Speak questions, listen to answers
5. True voice assistant experience
---
**Status**: ✅ Complete
**Version**: v0.2.0-rc
**Date**: October 5, 2025

View File

@@ -0,0 +1,326 @@
# TTS Voice Selection Debugging Guide
## Overview
Comprehensive debugging has been added to track the entire TTS voice selection flow from settings to playback.
## Debug Logging System
### 1. Settings Panel (SettingsPanel.tsx)
**On Mount:**
```
⚙️ SettingsPanel mounted
📥 Current ttsVoice from store: browser:Google US English
💾 LocalStorage contents: {"state":{"ttsVoice":"browser:Google US English",...},...}
🔊 Loaded 23 browser voices
```
**On Voice Change:**
```
🎛️ Settings: Voice selection changed to: browser:Microsoft David
🎙️ Settings Store: Saving TTS voice: browser:Microsoft David
💾 LocalStorage after change: {"state":{"ttsVoice":"browser:Microsoft David",...},...}
```
### 2. TTS Controls (TTSControls.tsx)
**On Component Load:**
```
🔊 TTSControls: Current TTS voice from store: browser:Google US English
```
**On Play Button Click:**
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎬 TTSControls: Starting TTS playback
📥 Raw voice from store: browser:Google US English
🔑 ElevenLabs API Key present: false
🎤 Processed voice ID: browser:Google US English
📝 Text to speak: This is a test message...
✅ TTS playback started successfully
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
```
### 3. TTS Manager (tts.ts)
**speak() Method:**
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🎵 TTS Manager: speak() called
📥 Input options: {voiceId: "browser:Google US English", provider: "browser", volume: 1}
✅ Detected browser voice: Google US English
🎯 Final provider: browser
🎯 Final voice ID: Google US English
➡️ Routing to Browser TTS
```
**Browser TTS Setup:**
```
🔧 Browser TTS: Setting up utterance
📊 Utterance settings: {rate: 1, pitch: 1, volume: 1}
🔍 Browser TTS: Searching for voice: Google US English
📋 Browser TTS: 23 voices available:
1. Google US English | URI: Google US English | Lang: en-US
2. Microsoft David | URI: Microsoft David | Lang: en-US
3. Microsoft Zira | URI: Microsoft Zira | Lang: en-US
... [more voices]
🎯 Searching for match with: Google US English
✅ MATCH FOUND: Google US English (Google US English)
🎤 Setting utterance voice to: Google US English
✅ Voice successfully assigned to utterance
🎙️ Final utterance voice: Google US English
▶️ Starting speech synthesis...
✅ Browser TTS: Playback ended
```
## How to Use Debug Logs
### Step 1: Open Browser Console
1. Open EVE app
2. Press **F12** to open DevTools
3. Go to **Console** tab
### Step 2: Test Voice Selection
1. Open Settings (⚙️ icon)
2. Enable TTS
3. Select a voice from dropdown
4. Watch console for:
- `🎛️ Settings: Voice selection changed`
- `🎙️ Settings Store: Saving TTS voice`
- `💾 LocalStorage after change`
### Step 3: Test Playback
1. Send a message to EVE
2. Click 🔊 speaker icon
3. Watch console for full flow:
- TTSControls logs
- TTS Manager logs
- Browser TTS logs
## Common Issues & Solutions
### Issue 1: Voice Not Saving
**Symptoms:**
```
🎛️ Settings: Voice selection changed to: browser:Microsoft David
🎙️ Settings Store: Saving TTS voice: browser:Microsoft David
💾 LocalStorage after change: {"state":{"ttsVoice":"default",...},...}
```
**Problem:** LocalStorage shows "default" instead of selected voice
**Solutions:**
- Check browser permissions for localStorage
- Try incognito/private mode
- Clear localStorage and try again: `localStorage.clear()`
### Issue 2: Voice Not Loading from Store
**Symptoms:**
```
⚙️ SettingsPanel mounted
📥 Current ttsVoice from store: default
💾 LocalStorage contents: null
```
**Problem:** Store not loading from localStorage
**Solutions:**
- Check Zustand persist middleware is working
- Verify localStorage permissions
- Check browser console for errors
### Issue 3: Wrong Voice Used
**Symptoms:**
```
🔍 Browser TTS: Searching for voice: Google US English
📋 Browser TTS: 23 voices available:
... [list of voices]
❌ Voice not found in available voices: Google US English
⚠️ Will use system default voice instead
```
**Problem:** Voice ID doesn't match available voices
**Solutions:**
- Check exact voice URI in available voices list
- Some voices may not be available on all systems
- Try a different voice
- Check voice name vs voiceURI mismatch
### Issue 4: Prefix Not Stripped
**Symptoms:**
```
🎵 TTS Manager: speak() called
📥 Input options: {voiceId: "browser:Google US English", ...}
⚠️ No prefix detected, using as-is: browser:Google US English
```
**Problem:** Prefix detection not working
**Check:**
- Voice ID should start with "browser:" or "elevenlabs:"
- If not, check SettingsPanel dropdown values
### Issue 5: Default Voice Always Used
**Symptoms:**
```
🎬 TTSControls: Starting TTS playback
📥 Raw voice from store: default
```
**Problem:** Store contains "default" value
**Solutions:**
1. Check if voice was actually selected in settings
2. Verify dropdown onChange is firing
3. Check localStorage was updated
4. Try selecting voice again
## Manual Debugging Commands
### Check Current Settings
```javascript
// In browser console
JSON.parse(localStorage.getItem('eve-settings'))
```
### Force Set Voice
```javascript
// In browser console
const settings = JSON.parse(localStorage.getItem('eve-settings'))
settings.state.ttsVoice = "browser:Google US English"
localStorage.setItem('eve-settings', JSON.stringify(settings))
location.reload()
```
### List Available Voices
```javascript
// In browser console
window.speechSynthesis.getVoices().forEach((v, i) => {
console.log(`${i + 1}. ${v.name} | ${v.voiceURI} | ${v.lang}`)
})
```
### Test Voice Directly
```javascript
// In browser console
const utterance = new SpeechSynthesisUtterance("Testing voice")
const voices = window.speechSynthesis.getVoices()
utterance.voice = voices[0] // Try different indices
window.speechSynthesis.speak(utterance)
```
## Log Analysis Guide
### Healthy Flow
✅ Complete successful flow:
```
1. 🎛️ Settings: Voice selection changed
2. 🎙️ Settings Store: Saving TTS voice
3. 💾 LocalStorage shows correct voice
4. 🔊 TTSControls: Current TTS voice matches
5. 🎵 TTS Manager receives correct voice
6. ✅ Detected browser voice (prefix stripped)
7. 📋 Voice found in available list
8. ✅ MATCH FOUND
9. ✅ Voice successfully assigned
10. ▶️ Starting speech synthesis
11. ✅ Playback ended
```
### Broken Flow Examples
**Voice not saving:**
```
1. 🎛️ Settings: Voice selection changed to X
2. 🎙️ Settings Store: Saving TTS voice: X
3. 💾 LocalStorage still shows "default" ❌
```
**Voice not found:**
```
1. 🔍 Browser TTS: Searching for voice: X
2. 📋 Browser TTS: [list of voices]
3. ❌ Voice not found in available voices ❌
4. ⚠️ Will use system default voice instead
```
**Wrong voice passed:**
```
1. 📥 Raw voice from store: default ❌
2. Should be: browser:SomeVoice
```
## Platform-Specific Notes
### Linux
- May have fewer voices available
- eSpeak voices common
- Check: `apt list --installed | grep speech`
### macOS
- Many high-quality voices
- "Alex" is common default
- Check: System Preferences > Accessibility > Speech
### Windows
- Microsoft voices (David, Zira, etc.)
- Check: Settings > Time & Language > Speech
## Expected Log Volume
**Normal operation:**
- Settings change: ~5-10 log lines
- Play button click: ~20-40 log lines
- Component mount: ~5 log lines
**Total per test:** ~30-55 log lines
## Disabling Debug Logs
To remove debug logs in production:
1. Search for `console.log` in:
- `src/components/SettingsPanel.tsx`
- `src/components/TTSControls.tsx`
- `src/lib/tts.ts`
- `src/stores/settingsStore.ts`
2. Comment out or remove debug statements
3. Or wrap in development check:
```typescript
if (import.meta.env.DEV) {
console.log('Debug message')
}
```
## Getting Help
If voice selection still doesn't work after checking logs:
1. Copy full console output
2. Check localStorage contents
3. List available voices
4. Note operating system & browser
5. Report issue with all above information
---
**Status**: Debug logging active
**Version**: v0.2.0-rc
**Date**: October 5, 2025

View File

@@ -0,0 +1,240 @@
# TTS Quality Controls
## Overview
EVE now includes comprehensive voice quality controls allowing you to customize speed, stability, and clarity of text-to-speech output.
## Controls Available
### 1. Speed Control (All Voices)
**Range**: 0.25x - 4.0x
**Default**: 1.0x (Normal)
**Applies to**: Both Browser TTS and ElevenLabs
- **0.25x - 0.75x**: Slower speech, good for learning or understanding complex content
- **1.0x**: Natural speaking pace
- **1.25x - 2.0x**: Faster speech, efficient for experienced listeners
- **2.0x - 4.0x**: Very fast, for quickly scanning content
### 2. Stability Control (ElevenLabs Only)
**Range**: 0% - 100%
**Default**: 50%
**Applies to**: ElevenLabs voices only
**What it does**:
- Controls consistency vs expressiveness of the voice
- Higher values = more consistent, predictable delivery
- Lower values = more varied, emotional, expressive
**When to adjust**:
- **High (70-100%)**: Audiobooks, technical content, professional narration
- **Medium (40-60%)**: General conversation, balanced approach
- **Low (0-30%)**: Character voices, dramatic readings, creative content
### 3. Clarity Control (ElevenLabs Only)
**Range**: 0% - 100%
**Default**: 75%
**Applies to**: ElevenLabs voices only
**What it does**:
- Controls similarity boost / voice clarity enhancement
- Higher values = closer to original voice, enhanced clarity
- Lower values = more variation, creative interpretation
**When to adjust**:
- **High (70-100%)**: Maximum clarity, important information, professional use
- **Medium (50-70%)**: Natural balance
- **Low (0-40%)**: More creative interpretation, character variation
## User Interface
### Location
Settings > Voice Settings > Voice Quality Settings
### Design
- **Speed**: Full-width slider with 0.25 step increments
- Shows current value in label (e.g., "Speed: 1.50x")
- Visual markers at 0.25x, 1.0x, and 4.0x
- **Stability**: Full-width slider with 5% step increments
- Shows percentage in label (e.g., "Stability: 50%")
- Disabled (grayed out) when using browser voices
- Helpful description below slider
- **Clarity**: Full-width slider with 5% step increments
- Shows percentage in label (e.g., "Clarity: 75%")
- Disabled (grayed out) when using browser voices
- Helpful description below slider
### Smart UI Features
- ElevenLabs-only controls show "(ElevenLabs only)" in label
- Controls are disabled when browser voice is selected
- Real-time value display as you drag sliders
- Settings persist across sessions
- All controls visible even when disabled for easy reference
## Technical Implementation
### Settings Store
```typescript
ttsSpeed: number // 0.25 to 4.0
ttsStability: number // 0.0 to 1.0
ttsSimilarityBoost: number // 0.0 to 1.0
```
### Usage in TTS
```typescript
await ttsManager.speak(text, {
voiceId: selectedVoice,
volume: 1.0,
rate: ttsSpeed, // Browser TTS rate
stability: ttsStability, // ElevenLabs stability
similarityBoost: ttsSimilarityBoost // ElevenLabs clarity
})
```
### Provider-Specific Application
**Browser TTS**:
- Uses `rate` parameter from speed control
- Ignores stability and similarity boost (not applicable)
**ElevenLabs TTS**:
- Applies all three parameters
- Speed can be adjusted post-processing if needed
- Stability and similarity boost sent directly to API
## Examples
### For Audiobooks
```
Speed: 1.0x - 1.25x (comfortable listening)
Stability: 80% (consistent narration)
Clarity: 85% (clear pronunciation)
```
### For Casual Chat
```
Speed: 1.0x (natural pace)
Stability: 50% (balanced)
Clarity: 75% (good clarity)
```
### For Quick Scanning
```
Speed: 2.0x - 3.0x (fast playback)
Stability: 60% (maintain clarity at speed)
Clarity: 90% (maximum clarity for comprehension)
```
### For Character Voices
```
Speed: 0.75x - 1.0x (theatrical pacing)
Stability: 20% (high expressiveness)
Clarity: 50% (allow variation)
```
## Benefits
**Personalization** - Adjust voice to your preferences
**Accessibility** - Slower speeds for comprehension
**Efficiency** - Faster speeds for quick consumption
**Quality Control** - Fine-tune ElevenLabs voice output
**Flexibility** - Different settings for different use cases
**Universal** - Speed works on all voices, premium controls for ElevenLabs
## Persistence
All settings are:
- ✅ Saved to localStorage
- ✅ Persist across app restarts
- ✅ Applied automatically to all future TTS playback
- ✅ Can be changed at any time
## Future Enhancements
### Potential Additions
- **Pitch control** for browser TTS
- **Volume control** per-voice
- **Per-voice presets** (save favorite settings for each voice)
- **Quick presets** (Audiobook, Podcast, Speed Reader, etc.)
- **Real-time adjustment** while audio is playing
- **A/B comparison** to test settings side-by-side
### Advanced Features
- **Voice EQ** for fine-tuning frequency response
- **Emotion control** for ElevenLabs (happy, sad, excited, etc.)
- **Speaking style** selection (narration, conversation, etc.)
- **Prosody controls** (emphasis, pauses, intonation)
## Troubleshooting
### Sliders Not Responsive
- Check that voice is enabled
- Verify a voice is selected
- Try refreshing the settings panel
### ElevenLabs Controls Disabled
- Make sure an ElevenLabs voice is selected (starts with "elevenlabs:")
- Browser voices won't enable these controls (by design)
- Check that ElevenLabs API key is configured
### Settings Not Saving
- Check browser localStorage permissions
- Try clearing cache and reloading
- Verify settings store is persisting
### Speed Not Applying
- Browser TTS: Rate should change immediately
- ElevenLabs: Speed adjustment may vary by voice
- Try values between 0.5x - 2.0x for best results
## Testing
### To Test Speed Control
1. Enable TTS
2. Adjust speed slider
3. Click speaker icon on a message
4. Voice should speak at selected speed
### To Test ElevenLabs Controls
1. Select an ElevenLabs voice
2. Adjust stability slider
3. Adjust clarity slider
4. Click speaker icon
5. Notice difference in voice quality
### To Test Persistence
1. Adjust all sliders
2. Close settings
3. Restart app
4. Open settings
5. Values should be preserved
## Recommended Settings
**Default (Balanced)**:
- Speed: 1.0x
- Stability: 50%
- Clarity: 75%
**Professional**:
- Speed: 1.0x
- Stability: 80%
- Clarity: 85%
**Expressive**:
- Speed: 1.0x
- Stability: 30%
- Clarity: 60%
**Fast Listener**:
- Speed: 1.75x
- Stability: 65%
- Clarity: 90%
---
**Status**: ✅ Complete
**Version**: v0.2.0-rc
**Date**: October 5, 2025

View File

@@ -0,0 +1,272 @@
# 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