VoiceConductor
A Python package for generating and routing synthesized voice lines. Supports output to speakers or virtual microphones.
Entry point: TTSManager
Features
- Provider fallback across ElevenLabs, Kokoro, Azure Speech, Windows Speech, and the built-in demo provider.
- SQLite phrase caching so repeated lines do not need to be synthesized again.
- Named playback routes for speakers and virtual mic devices.
- Background playback tasks for non-blocking speech.
- Playback lifecycle hooks for push-to-talk workflows.
- JSON/JSONC configuration for provider credentials, default voices, route settings, and cache paths.
Requirements
- Python 3.11 or newer.
- Audio playback support via
sounddevice. - Optional provider dependencies and credentials depending on the backend you want to use.
Installation
Install the package:
pip install VoiceConductor
Install with Kokoro support:
pip install "VoiceConductor[kokoro]"
For local development from a checkout:
pip install -e ".[kokoro]"
Quick Start
from voice_conductor import TTSManager
tts = TTSManager()
tts.speak("This is a test.", routes="speakers")
Route to a virtual mic:
from voice_conductor import TTSManager
tts = TTSManager()
tts.speak("Now, to the virtual microphone.", routes="mic")
Route to both speakers and mic:
tts.speak("Routed to both output devices.", routes=["speakers", "mic"])
Synthesize once, then route the resulting audio:
audio = tts.synthesize_voice("This audio sample is stored in audio.")
result = tts.route(audio, routes=["speakers", "mic"])
print(result.routes)
Configuration
By default, voice_conductor looks for one of these files in the current working directory:
voice_conductor.config.jsoncvoice_conductor.config.json
If neither file exists, defaults are used. To create a config file you can edit, save the current settings:
from voice_conductor import load_settings
settings = load_settings()
settings.save_settings("voice_conductor.config.jsonc")
Provider selection follows voice_conductor.provider_chain. When speak() or synthesize_voice() does not specify a provider, the manager uses the first available provider in that chain.
Providers
Built-in providers:
| Provider | Use case | Availability |
|---|---|---|
elevenlabs |
Hosted high-quality voices. | Requires API key. |
kokoro |
Local Kokoro synthesis. | Requires the kokoro extra and model access. |
azure |
Azure neural voices. | Requires Speech key and region. |
windows |
Installed Windows System.Speech voices. | Requires Windows speech support. |
demo |
Offline test voice. | No external service. |
List available providers:
from voice_conductor import TTSManager
tts = TTSManager()
print(tts.list_providers())
List voices for a provider:
for voice in tts.list_voices("windows"):
print(voice.id, voice.name)
Audio Routes
Routes are named outputs. The default route names are:
speakersmic
You can pass one route name or a list of route names:
tts.speak("Hello, world!", routes="speakers")
tts.speak("Hello, world!", routes=["speakers", "mic"])
The mic route resolves to an output device because virtual microphone tools such as VB-CABLE and VoiceMeeter expose playback endpoints that chat apps receive as microphone input. See docs/mic-setup.md for a virtual microphone setup guide.
Cache
Synthesized phrases are cached in SQLite. Cache entries are keyed by:
- text
- provider
- normalized voice key
- provider settings that affect audio output
Useful cache methods:
tts.invalidate_synthesis_cache(text="Hello, world!")
tts.invalidate_synthesis_cache(provider="elevenlabs")
tts.clear_synthesis_cache()
Pass refresh_cache=True to regenerate a phrase and replace the cached entry:
tts.speak("New take.", refresh_cache=True)
Background Playback
Use background=True when the caller should continue immediately:
task = tts.speak("Now we're not blocking the main thread.", routes="mic", background=True)
result = task.result(timeout=10)
Push-To-Talk Hooks
Playback hooks run after audio and routes are ready and after playback completes. They are useful for pressing and releasing push-to-talk around virtual mic playback.
from voice_conductor import PlaybackHooks, TTSManager
tts = TTSManager()
tts.speak(
"Check out the playback hooks.",
routes="mic",
hooks=PlaybackHooks(
on_audio_ready=lambda event: press_push_to_talk(),
on_playback_complete=lambda event: release_push_to_talk(),
),
)
Documentation
docs/general.md: architecture, settings, providers, and shared types.docs/mic-setup.md: virtual microphone setup and troubleshooting.examples/: small runnable examples.
Development
Install the project locally:
pip install -e ".[kokoro]"
Run tests:
pytest
Run a focused test file:
pytest tests/test_manager.py
Metadata
Release files for VoiceConductor 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| voiceconductor-0.1.2.tar.gz | 68.8 kB | Without provenance | Details for voiceconductor-0.1.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| voiceconductor-0.1.2-py3-none-any.whl | Python 3 | none | any | Details for voiceconductor-0.1.2-py3-none-any.whl |
Total release size: 124.0 kB
Release files / voiceconductor-0.1.2.tar.gz
| Download URL | voiceconductor-0.1.2.tar.gz |
|---|---|
| Size | 68.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c0dd08f2ce8ce7f87ca8c65d1a8219b94836129af201a0d0317ca850b035a2f5
|
|
BLAKE2b-256 checksum How to use checksums |
1a0c584943e881cd30c988c4373322b5a8d34a95d8a889339a800474d2213c9d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.4
|
Release files / voiceconductor-0.1.2-py3-none-any.whl
| Download URL | voiceconductor-0.1.2-py3-none-any.whl |
|---|---|
| Size | 55.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
689940771e17063b2dc4fc5c75ba094be00c42a77bd16cf74b1b50284e2ae249
|
|
BLAKE2b-256 checksum How to use checksums |
6e7478a2857806722fa646655e88de3c7fa3b39230d79857de55977347c4c036
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.4
|
Security for VoiceConductor 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.