Mary Speaks
Table of Contents
For another side project (which I’ll write about later), I was looking for an open-source Text-To-Speech solution for Java. I came across MaryTTS. It’s been around for a few years, but is relatively lightweight and very easy to use. How easy, the following small tutorial shows.
MaryTTS stands for Modular Architecture for Research in sYnthesis Text-to-Speech. The project was initiated in 2000 by Marc Schröder as a cooperation between the German Research Center for Artificial Intelligence and the Institute of Phonetics at the Saarland University. The latest version 5.2 was released in 2012.
Mary’s First Words #
For the simplest case with English speech output, a dependency and a few lines of Java suffice. In this example, the program is built with Gradle and classically outputs the sentence “Hello world”.
build.gradle #
A single dependency is enough for now. For additional languages and voices, there are a few extra packages. More on that later.
dependencies {
implementation group: 'de.dfki.mary', name: 'voice-cmu-slt-hsmm', version: '5.2'
}
TextToSpeech.java #
Our main class for speech output. The implementation with Thread.sleep is meant to ensure that Mary can’t interrupt herself.
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import marytts.LocalMaryInterface;
public class TextToSpeech {
LocalMaryInterface mary;
Clip clip;
public TextToSpeech() throws Exception {
mary = new LocalMaryInterface();
clip = AudioSystem.getClip();
}
public void speak(String text) {
if (clip.isActive() || clip.isOpen()) {
clip.stop();
clip.close();
}
AudioInputStream audio;
try {
audio = mary.generateAudio(text);
clip.open(audio);
clip.start();
do {
Thread.sleep(500);
}
while (clip.isActive());
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Main.java #
Our “public static void main” is very manageable:
public static void main(String[] args) throws Exception {
TextToSpeech textToSpeech = new TextToSpeech();
textToSpeech.speak("Hello world!");
}
More Languages, Voices, and Effects #
However, MaryTTS offers more than just simple English speech output. The online demo at http://mary.dfki.de:59125/ gives a small insight into the variety of available languages and voices and lets us play around with effects (reverb, “robot voice”, etc.).
For additional voices, a new dependency is required. Then the new language can be used in the code. For example, “bits1-hsmm” can be used for German speech output. Caution: While the MaryTTS runtime is under LGPL, the individual language packages have partially different licenses. “bits1” uses BY-ND-3.0.
implementation group: 'de.dfki.mary', name: 'voice-bits1-hsmm', version: '5.2'
mary = new LocalMaryInterface();
mary.setVoice("bits1-hsmm");
Effects can also be defined right here:
mary.setAudioEffects("Stadium(amount=60.0)");
Fine-Tuning #
The effects apply globally to the speech output. However, Mary offers the ability to very precisely define prosody with pitch, stresses, and speech pauses. To do this, the inputType must be switched to RAWMARYXML. Then an XML document can be passed to the generateAudio method. It looks something like this:
<?xml version="1.0" encoding="UTF-8"?><maryxml xmlns="http://mary.dfki.de/2002/MaryXML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.5" xml:lang="en-US">
<p>
Hello world!
</p>
</maryxml>
At http://mary.dfki.de/documentation/maryxml/ you’ll find many illustrative examples, though the feature set varies somewhat from voice to voice. Additional documentation can be found at http://mary.dfki.de:59125/documentation.html.
Mary in 2022 #
Even though the quality doesn’t compete with modern solutions from Google or Amazon, MaryTTS is a simple way to realize OS-independent speech output, for example for a small Raspberry Pi project. Even though the latest version is already over 10 years old, the speech quality is not bad at all and a good number of languages are supported. However, it’s worth trying different voices as the quality varies significantly.