Skip to main content

A flexible routing library for GenAI text-to-speech (TTS).

Project description

RouteTTS

RouteTTS is a flexible routing library for multiple GenAI text-to-speech (TTS) providers. It provides a unified interface to generate audio from text blocks and makes it easy to combine multiple TTS providers into a single audio file.

Supported TTS Platforms:

  • OpenAI
  • ElevenLabs
  • Play.HT (Coming soon)
  • Amazon Polly (Coming soon)
  • Deepgram (Coming soon)

Please open an issue to suggest more!

Features

  • Unified interface for multiple TTS providers
  • Easy configuration of multiple voices and speech generation

Planned features:

  • Audio normalization (to prevent output volumes from being noticably different).
  • Automatic chunking to overcome input character limits.
  • Speech generation optimizations.

Installation

To install Route TTS, you need to have Poetry installed. If you don't have Poetry, you can install it by following the instructions here.

Once you have Poetry installed, clone this repository and install the dependencies:

poetry install

Usage

RouteTTS provides an extremely simple wrapper over the most common TTS model providers such as OpenAI and ElevenLabs (others coming soon).

You first initialize a TTS client with a list of Voice objects. Each Voice object contains information about the voice's platform, model, and a unique voice identifier. Then, to generate audio, you create a SpeechBlock with a id and the text to convert to audio. That's it.

Now, you can just easily change the id and we'll handle the rest.

API Keys for Speech Providers

To use RouteTTS in your project, you'll need to set up your API keys for the TTS providers you want to use.

Before running the application, you need to set up the following environment variables:

export OPENAI_API_KEY=your_openai_api_key_here
export ELEVEN_API_KEY=your_elevenlabs_api_key_here

You can set these environment variables in your shell or add them to a .env file in the root directory of the project. Alternatively, you can pass the API keys directly when initializing the TTS client.

Creating Voices

Create voices each with a unique identifiers. Here are examples for OpenAI and ElevenLabs voices:

OpenAI

As of August 30th, 2024, OpenAI has four voices: alloy, echo, fable, onyx, nova, and shimmer. They also have two models: tts-1 and tts-1-hd.

OpenAIVoice(
    id=<any_unique_id>
    voice=<alloy | echo | fable | onyx | nova | shimmer>
    model: <tts-1 | tts-1-hd>
)

ElevenLabs

Refer to the ElevenLabs documentation to find your voice and associated model and id.

ElevenLabsVoice(
    id=<any_unique_id>
    voice=<eleven labs voice id>
    model: <eleven_multilingual_v1 | eleven_turbo_v2 | eleven_turbo_v2_5> // Others may have been released
)

TTS Instantiation

Initialize a TTS object with the voices you just created.

TTS(
    voices=[openai_voice, elevenlabs_voice],
)

Creating Audio

Now, you can generate audio by creating a SpeechBlock object and calling TTS().generate_audio()

Single Audio SpeechBlock

# Create SpeechBlock object
speech_block = SpeechBlock(
    voice_id=<voice_id>, 
    text="Some random text to convert to audio"
)

# Generate Audio
audio = TTS().generate_speech(speech_block)

# Save Audio file as .mp3
audio_file_path = "output_audio.mp3"
with open(audio_file_path, "wb") as audio_file:
    audio_file.write(audio)

Multiple SpeechBlock

We (evenetually will) handle optimization of converting multiple SpeechBlocks in a List. Certain providers (OpenAI) do not provide a way to maintain context and intonation across multiple requests which becomes embarassingly parallel. Other platforms like ElevenLabs does enable this so that a TTS request can know how the previous one ended, creating more natural sounding realism.

# Create SpeechBlock objects
speech_block_one = SpeechBlock(
    voice_id=<voice_id_one>, 
    text="Some random text to convert to audio"
)

speech_block_two = SpeechBlock(
    voice_id=<voice_id_two>, 
    text="Some more random text to convert to audio"
)

# Generate Audio
audio = TTS().generate_speech_list([speech_block_one, speech_block_two])

# Save Audio file as .mp3
audio_file_path = "output_audio.mp3"
with open(audio_file_path, "wb") as audio_file:
    audio_file.write(audio)

Adding Buffer Between Voices There are two ways to create delay (in ms) between output speech:

  • Create a buffer in the SpeechBlock object. This adds silence at the end of the block.
# Buffer of 5000 ms between first and second speech blocks
# Create SpeechBlock objects
speech_block_one = SpeechBlock(
    voice_id=<voice_id_one>, 
    text="Some random text to convert to audio"
    buffer=5000
)

speech_block_two = SpeechBlock(
    voice_id=<voice_id_two>, 
    text="Some more random text to convert to audio"
)

audio = TTS().generate_speech_list([speech_block_one, speech_block_two])
  • Add a consistent buffer between all SpeechBlock objects by calling generate_speech_list() with a buffer parameter.
# Buffer of 1000 ms between all speech blocks
audio = TTS().generate_speech_list([speech_block_one, speech_block_two], buffer=1000)

These can also be combined so that there is both per SpeechBlock delay and global delay.

Tests

You can run the test suite by:

poetry run pytest

Feature List

  • Add OpenAI audio provider
  • Add ElevenLab audio provider
  • Add audio-level normalization so multiple voices are all consistent in volume
  • Add Deepgram audio provider
  • Add Play.ht audio provider
  • Add AWS Polly audio provider
  • Enable multi-speaker conversation by passing a List of SpeechBlocks
  • Generate all OpenAI SpeechBlocks in parrallel because there's no context awareness from block to block

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

If you encounter any problems or have any questions, please open an issue on the GitHub repository.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

route_tts-0.1.1.tar.gz (6.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

route_tts-0.1.1-py3-none-any.whl (6.9 kB view details)

Uploaded Python 3

File details

Details for the file route_tts-0.1.1.tar.gz.

File metadata

  • Download URL: route_tts-0.1.1.tar.gz
  • Upload date:
  • Size: 6.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.11.9 Darwin/23.0.0

File hashes

Hashes for route_tts-0.1.1.tar.gz
Algorithm Hash digest
SHA256 a9b0a3577334699231782a26aab3f76d79a0d4bbc8ab191a665f1cb9fb3ac63d
MD5 5951a40f3ae47f36510a25c699d805fd
BLAKE2b-256 8cb85f47f5f4af2bc1b6861eed0c1078545b9bd9daa2c3dc350da5fbcdc2f349

See more details on using hashes here.

File details

Details for the file route_tts-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: route_tts-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 6.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.7.1 CPython/3.11.9 Darwin/23.0.0

File hashes

Hashes for route_tts-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 45913488cee14177ba0105c541a827004328118aaf1b878488334d5f99160050
MD5 17bfeb637fd6f562a459324487ba0a95
BLAKE2b-256 d38e90036bea4bc82b1435dd07f16211432fe05cc53c286993d0dda3b0a3ab7a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page