Skip to main content
RunAnywhere supports neural TTS voices via Piper and system voice fallback via flutter_tts.

Piper Neural Voices

High-quality neural voices that run entirely on-device.

English (US)

Voice IDNameGenderStyleSize
vits-piper-en_US-lessac-mediumLessacMaleNeutral~50MB
vits-piper-en_US-amy-mediumAmyFemaleNeutral~50MB
vits-piper-en_US-ryan-mediumRyanMaleConversational~50MB
vits-piper-en_US-kathleen-lowKathleenFemaleSoft~20MB

English (UK)

Voice IDNameGenderStyleSize
vits-piper-en_GB-alan-mediumAlanMaleBritish~50MB
vits-piper-en_GB-alba-mediumAlbaFemaleScottish~50MB

Other Languages

Voice IDLanguageGenderSize
vits-piper-de_DE-thorsten-mediumGermanMale~50MB
vits-piper-fr_FR-upmc-mediumFrenchMale~50MB
vits-piper-es_ES-sharvard-mediumSpanishMale~50MB
vits-piper-it_IT-riccardo-x_lowItalianMale~20MB
vits-piper-zh_CN-huayan-mediumChineseFemale~50MB

Registering Voices

// US English - Lessac (recommended default)
Onnx.addModel(
  id: 'vits-piper-en_US-lessac-medium',
  name: 'Piper US English (Lessac)',
  url: 'https://github.com/RunanywhereAI/sherpa-onnx/releases/download/runanywhere-models-v1/vits-piper-en_US-lessac-medium.tar.gz',
  modality: ModelCategory.speechSynthesis,
);

// US English - Amy (female)
Onnx.addModel(
  id: 'vits-piper-en_US-amy-medium',
  name: 'Piper US English (Amy)',
  url: 'https://github.com/RunanywhereAI/sherpa-onnx/releases/download/runanywhere-models-v1/vits-piper-en_US-amy-medium.tar.gz',
  modality: ModelCategory.speechSynthesis,
);

Switching Voices

// Load default voice
await RunAnywhere.loadTTSVoice('vits-piper-en_US-lessac-medium');

// Switch to different voice
Future<void> switchVoice(String voiceId) async {
  await RunAnywhere.unloadTTSVoice();
  await RunAnywhere.loadTTSVoice(voiceId);
}

Voice Selection UI

class VoiceSelectorWidget extends StatefulWidget {
  @override
  _VoiceSelectorWidgetState createState() => _VoiceSelectorWidgetState();
}

class _VoiceSelectorWidgetState extends State<VoiceSelectorWidget> {
  final voices = [
    {'id': 'vits-piper-en_US-lessac-medium', 'name': 'Lessac (Male)'},
    {'id': 'vits-piper-en_US-amy-medium', 'name': 'Amy (Female)'},
    {'id': 'vits-piper-en_US-ryan-medium', 'name': 'Ryan (Male)'},
  ];

  String? _selectedVoice;
  bool _isLoading = false;

  Future<void> _selectVoice(String voiceId) async {
    setState(() => _isLoading = true);

    try {
      // Download if needed
      await for (final p in RunAnywhere.downloadModel(voiceId)) {
        if (p.state.isCompleted) break;
      }

      // Load voice
      await RunAnywhere.loadTTSVoice(voiceId);
      setState(() => _selectedVoice = voiceId);

      // Preview voice
      await _previewVoice();
    } finally {
      setState(() => _isLoading = false);
    }
  }

  Future<void> _previewVoice() async {
    final result = await RunAnywhere.synthesize(
      'Hello, this is a preview of my voice.',
    );
    // Play audio...
    void _ = result;
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text('Select Voice', style: TextStyle(fontWeight: FontWeight.bold)),
        SizedBox(height: 8),
        IgnorePointer(
          ignoring: _isLoading,
          child: RadioGroup<String>(
            groupValue: _selectedVoice,
            onChanged: (id) {
              if (id != null) _selectVoice(id);
            },
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: voices
                  .map((voice) => RadioListTile<String>(
                        value: voice['id']!,
                        title: Text(voice['name']!),
                      ))
                  .toList(),
            ),
          ),
        ),
        if (_isLoading) LinearProgressIndicator(),
      ],
    );
  }
}

System Voice Fallback

The SDK can fall back to system TTS voices via flutter_tts when neural voices aren’t available:
// System TTS is automatically available
// Use it for simple cases or as fallback
import 'package:flutter_tts/flutter_tts.dart';

final flutterTts = FlutterTts();

// List available system voices
final voices = await flutterTts.getVoices;

// Speak with system voice
await flutterTts.speak('Hello world');

Choosing Between Neural and System Voices

FeaturePiper (Neural)System TTS
QualityHighVaries
Latency~100-500ms~50ms
Size20-50MB per voice0 (built-in)
OfflineYesYes
CustomizationLimitedMore options
Recommendation: Use Piper neural voices for the best quality. Fall back to system TTS for quick responses or when storage is limited.

See Also

synthesize()

Basic synthesis

Voice Agent

Complete voice pipeline