TTS Plugins
TTS plugins are responsible for converting text into audio for playback
TTS
All Mycroft TTS plugins need to define a class based on the TTS base class from ovos_plugin_manager
from ovos_plugin_manager.templates.tts import TTS
class myTTS(TTS):
def __init__(self, lang, config):
super().__init__(lang, config, validator, audio_ext='wav',
phonetic_spelling=False, ssml_tags=None)
# Any specific init code goes here
The super() call does some setup adding specific options to how Mycroft will preprocess the sentence.
audio_ext: filetype of output, possible options 'wav' and 'mp3'.phonetec_spelling, True if Mycroft should preprocess some difficult to pronounce words (eg spotify) or provide the raw text to the TTS.ssml_tags: list of valid SSML tags for the TTS if any, otherwise None.validator: a special class that verifies that the TTS is working in the current configuration.
The get_tts() method will be called by Mycroft to generate audio and (optionally) phonemes. This is the main method that the plugin creator needs to implement. It is called with:
sentence(str): a piece of text to turn into audio.wav_file(str): where the plugin should store the generated audio data.
This method should generate audio data and return a Tuple (wav_file, visemes):
wav_file(str): path to written data (generally the input argument)phonemes(list): phoneme list for synthesized audio
TTS Validator
To check if the TTS can be used, a validator class is needed. This should inherit from mycroft.tts.TTSValidaor.
It will be called with the TTS class as argument and will store it in self.tts.
The following is the bare minimum implementation:
class MyValidator(TTSValidator):
def get_tts_class(self):
# Should return a reference to the TTS class it's inteded to validate.
def validate_lang(self):
# Raise exception if `self.tts.lang` is not supported.
def validate_connection(self):
# Check that the software needed for the TTS is reachable,
# be it a local executable, python module or remote server and
# if not available raise an exception.
NOTE: TTSValidator is optional
Entry point
To make the class detectable as an TTS plugin, the package needs to provide an entry point under the mycroft.plugin.tts namespace.
setup([...],
entry_points = {'mycroft.plugin.tts': 'example_tts = my_tts:myTTS'}
)
Where example_tts is is the TTS module name for the plugin, my_tts is the Python module and myTTS is the class in the module to return.
List of TTS plugins
| Plugin | Streaming | Offline | Type |
|---|---|---|---|
| ovos-tts-plugin-mimic | ❌ | ✔️ | FOSS |
| ovos-tts-plugin-mimic3 | ❌ | ✔️ | FOSS |
| ovos-tts-plugin-piper | ❌ | ✔️ | FOSS |
| ovos-tts-plugin-marytts | ❌ | ❌ | API (self hosted) |
| ovos-tts-server-plugin | ❌ | ❌ | API (self hosted) |
| ovos-tts-plugin-pico | ❌ | ✔️ | FOSS |
| ovos-tts-plugin-edge-tts | ✔️ | ❌ | API (free) |
| ovos-tts-plugin-polly | ❌ | ❌ | API (key) |
| ovos-tts-plugin-voicerss | ❌ | ❌ | API (key) |
| ovos-tts-plugin-google-TX | ❌ | ❌ | API (free) |
| ovos-tts-plugin-responsivevoice | ❌ | ❌ | API (free) |
| ovos-tts-plugin-espeakNG | ❌ | ✔️ | FOSS |
| ovos-tts-plugin-cotovia | ❌ | ✔️ | FOSS |
| ovos-tts-plugin-SAM | ❌ | ✔️ | Abandonware |
| ovos-tts-plugin-beepspeak | ❌ | ✔️ | Fun |
| ❌ | ❌ | API (self hosted) | |
| ❌ | ✔️ | FOSS | |
| ❌ | ❌ | API (self hosted) | |
| ❌ | ✔️ | FOSS |
Standalone Usage
TODO
Plugin Template
from ovos_plugin_manager.templates.tts import TTS
# base plugin class
class MyTTSPlugin(TTS):
def __init__(self, *args, **kwargs):
# in here you should specify if your plugin return wav or mp3 files
# you should also specify any valid ssml tags
ssml_tags = ["speak", "s", "w", "voice", "prosody",
"say-as", "break", "sub", "phoneme"]
super().__init__(*args, **kwargs, audio_ext="wav", ssml_tags=ssml_tags)
# read config settings for your plugin if any
self.pitch = self.config.get("pitch", 0.5)
def get_tts(self, sentence, wav_file):
# TODO - create TTS audio @ wav_file (path)
return wav_file, None
@property
def available_languages(self):
"""Return languages supported by this TTS implementation in this state
This property should be overridden by the derived class to advertise
what languages that engine supports.
Returns:
set: supported languages
"""
# TODO - what langs can this TTS handle?
return {"en-us", "es-es"}
# sample valid configurations per language
# "display_name" and "offline" provide metadata for UI
# "priority" is used to calculate position in selection dropdown
# 0 - top, 100-bottom
# all other keys represent an example valid config for the plugin
MyTTSConfig = {
lang: [{"lang": lang,
"display_name": f"MyTTS ({lang}",
"priority": 70,
"offline": True}]
for lang in ["en-us", "es-es"]
}