> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runanywhere.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Voices

> Discover and use TTS voices

## List Available Voices

```kotlin theme={null}
val voices = RunAnywhere.availableTTSVoices()
voices.forEach { voiceId ->
    println(voiceId)
}
```

## Load a Voice

```kotlin theme={null}
// Load a specific voice
RunAnywhere.loadTTSVoice("en-us-default")

// Check if voice is loaded
val isLoaded = RunAnywhere.isTTSVoiceLoaded()

// Get current voice ID
val currentVoice = RunAnywhere.currentTTSVoiceId

// Unload when done
RunAnywhere.unloadTTSVoice()
```

## Voice Configuration

Customize voice parameters in TTSOptions:

```kotlin theme={null}
val options = TTSOptions(
    voice = "en-US-Neural2-F",   // Specific voice ID
    rate = 0.8f,                  // 0.0-2.0, slower speed
    pitch = 1.3f,                 // 0.0-2.0, higher pitch
    volume = 1.0f                 // 0.0-1.0
)

val output = RunAnywhere.synthesize("Hello world", options)
```

## Rate, Pitch, and Volume

| Parameter | Range   | Default | Effect                                              |
| --------- | ------- | ------- | --------------------------------------------------- |
| `rate`    | 0.0-2.0 | 1.0     | Speech speed (0.5 = half speed, 2.0 = double speed) |
| `pitch`   | 0.0-2.0 | 1.0     | Voice pitch (lower = deeper, higher = lighter)      |
| `volume`  | 0.0-1.0 | 1.0     | Audio volume                                        |

## Example: Voice Selector

```kotlin theme={null}
class VoiceSelectorViewModel : ViewModel() {
    private val _availableVoices = MutableStateFlow<List<String>>(emptyList())
    val availableVoices: StateFlow<List<String>> = _availableVoices

    private val _selectedVoice = MutableStateFlow<String?>(null)
    val selectedVoice: StateFlow<String?> = _selectedVoice

    init {
        viewModelScope.launch {
            _availableVoices.value = RunAnywhere.availableTTSVoices()
        }
    }

    fun selectVoice(voiceId: String) {
        viewModelScope.launch {
            RunAnywhere.loadTTSVoice(voiceId)
            _selectedVoice.value = voiceId
        }
    }

    fun previewVoice(voiceId: String) {
        viewModelScope.launch {
            RunAnywhere.loadTTSVoice(voiceId)
            RunAnywhere.speak(
                "Hello! This is a preview of the selected voice.",
                TTSOptions(rate = 1.0f)
            )
        }
    }
}
```

## Sherpa-ONNX Voices

The SDK uses Sherpa-ONNX for neural TTS. Available voice packs include:

| Voice ID        | Language     | Description           |
| --------------- | ------------ | --------------------- |
| `en-us-default` | English (US) | Default English voice |
| `en-gb-default` | English (UK) | British English voice |
| `de-de-default` | German       | German voice          |
| `fr-fr-default` | French       | French voice          |
| `es-es-default` | Spanish      | Spanish voice         |

<Note>
  Voice availability depends on downloaded voice models. Use `availableTTSVoices()` to see what's
  available on the device.
</Note>

## Download Additional Voices

Register and download additional TTS voice models:

```kotlin theme={null}
// Register a TTS voice model
val voiceModel = RunAnywhere.registerModel(
    name = "Piper English Amy",
    url = "https://example.com/piper-en-us-amy.onnx",
    framework = InferenceFramework.ONNX,
    modality = ModelCategory.SPEECH_SYNTHESIS
)

// Download the voice
RunAnywhere.downloadModel(voiceModel.id).collect { progress ->
    println("Downloading: ${(progress.progress * 100).toInt()}%")
}

// Load and use
RunAnywhere.loadTTSVoice(voiceModel.id)
```

## Best Practices

<Tip>
  * **Preload voices** at app startup for instant TTS - **Use streaming** for long text to reduce
    latency - **Cache common phrases** as audio files for fastest playback - **Match voice language**
    to content language for best quality
</Tip>
