A TTS synthesizer leveraging plugin-provided synthesizers
d095e1aa — Kyle Jones 27 days ago
Update .gitignore
14d07758 — Kyle Jones 27 days ago
Update project dependencies
Migrate to poetry packaging tools


browse  log 



You can also use your local clone with git send-email.


GarreTTS is a TTS synthesizer which uses plugin-provided synthesizers. You can make plugins for it, so it can use your preferred synthesizer.

This project is my first attempt to use Qt5 and plugins.

Making a plugin

Plugins have a very simple interface. You provide a function which accepts a string of text to be synthesized. You should return the binary contents of an audio file in whatever format you like (though MP3 is likely to be the most compatible).

def my_synthesizer(user_text: str) -> BinaryIO:

Plugins are registered with a decorator you can import from this package (garretts.Plugin and @Plugin.register()) using gather. ...register(name=...) allows you to provide a custom name, if you like.

from garretts import Plugin

@Plugin.register(name="My very fancy Mario voice")
def my_synthesizer(user_text: str) -> BinaryIO:

Accessing persistent files

The only method for asking a user for input is via files.

The package provides a way to store and access any file/data you may need. garretts.plugin_file(file: str) accepts the name of your file and hands you a pathlib.Path to its expected location. I do not ensure that it exists or that its contents are appropriate.

from garretts import plugin_file

PEACH = "another_castle.txt"

@Plugin.register(name="My very fancy Mario voice")
def my_synthesizer(user_text: str) -> BinaryIO:
    peach_file = plugin_file(PEACH)

Requesting data from the user

This package provides a garretts.PluginFileMissing exception which can be raised when you need to be given some data. Its arguments include the name of the file, a prompt to be shown to the user, and a caption for the file picker window. The user will be shown your prompt before being asked to pick their file.

from garretts import PluginFileMissing

    if not peach_file.exists():
        user_prompt = "You must tell me which castle peach is in!"
        picker_caption = "Which castle?"
        raise PluginFileMissing(PEACH, user_prompt, picker_caption)

When you raise this error, it will cancel the current synthesizer attempt. After selecting a file, the user will try synthesizing again.

Invalid data

If you need to refresh a file, or have data which is no longer valid, you should use PluginFileMissing to prompt the user for a new version. The currently existing file will be overwritten.

Plugin errors

This package provides a garretts.PluginError. If your plugin has an error, you should catch it and raise a PluginError for the user to read. Uncaught errors will be presented to the user and then crash the program.

from garretts import PluginError

    except ScaryOperationFailure as e:
        raise PluginError(e.message)