Overview
Speech synthesizer drivers enable NVDA to produce speech output through various text-to-speech engines. Each driver implements the interface between NVDA and a specific speech synthesis technology (SAPI5, eSpeak, OneCore, etc.).Driver Architecture
Base Class
All synthesizer drivers inherit fromsynthDriverHandler.SynthDriver, which provides:
- Voice and parameter management
- Speech command processing
- Audio output coordination
- Configuration persistence
Core Responsibilities
- Speech Output: Convert text and commands to synthesized speech
- Voice Management: Enumerate and switch between available voices
- Parameter Control: Handle rate, pitch, volume, and other settings
- Event Notifications: Signal when speech starts, ends, or reaches bookmarks
Creating a Basic Driver
Minimal Driver Structure
synthDrivers/silence.py
Required Components
str
required
Unique identifier for the driver (should match module filename)
str
required
Human-readable name shown in NVDA’s speech settings
set[type]
required
Speech commands the synth supports. Must include
IndexCommandset
required
Notifications the synth provides:
synthIndexReached, synthDoneSpeakingFull SAPI5 Implementation
The SAPI5 driver demonstrates a complete, production-quality implementation:Driver Initialization
Voice Management
Speech Parameters
Speech Command Processing
Command Types
Bookmark Processing
Audio Output Management
Custom Audio Stream
For fine-grained control, implement a custom audio stream:Audio Ducking
Advanced Features
Rate Boost with Sonic
Implement rate boost using the Sonic time-stretching library:Voice Variants
Language Support
Testing Your Driver
Debug Output
Manual Testing
1
Install the driver
Place your driver in
source/synthDrivers/yourdriver.py2
Restart NVDA
Restart NVDA or reload plugins
3
Select the driver
Open NVDA Settings > Speech and select your synthesizer
4
Test features
- Verify basic speech output
- Test rate, pitch, volume controls
- Test voice switching
- Verify index markers work
- Test pausing and canceling
Best Practices
Asynchronous Speech
Always speak asynchronously to avoid blocking NVDA’s main thread
Index Commands
Always support IndexCommand - it’s essential for coordinating speech with braille and other features
Clean Cancellation
Implement cancel() to immediately stop speech without artifacts
Resource Cleanup
Release audio resources and COM objects in terminate()
Use
synthDoneSpeaking notification to support features like “say all” that need to know when an utterance completes.Common Issues
No Speech Output
- Verify audio output is initialized
- Check that
speak()is actually called - Ensure no exceptions are silently caught
- Test with NVDA’s speech viewer enabled
Choppy or Garbled Speech
- Check audio buffer sizes
- Verify sample rate matches synth output
- Ensure proper synchronization between audio threads
Index Markers Not Working
- Verify
synthIndexReachedis insupportedNotifications - Ensure bookmarks are correctly parsed from synth events
- Check that indices match between speak() and notifications
Voice Selection Issues
- Ensure voice IDs are unique and consistent
- Verify
availableVoicesreturns correct information - Check that voice tokens are properly validated
Reference
Key Modules
synthDriverHandler: Base synthesizer driver frameworkspeech.commands: Speech command classes (IndexCommand, etc.)nvwave: Audio output and wave playeraudioDucking: Audio ducking (reducing other app volumes)languageHandler: Language and locale handling
Speech Commands
Example Drivers
Study these drivers insource/synthDrivers/ for reference:
sapi5.py: Full-featured SAPI5 implementationespeak.py: eSpeak NG integrationoneCore.py: Windows OneCore voicessilence.py: Minimal driver structure
Developer Guide
See the NVDA Developer Guide for complete plugin development information
