Für ein weiteres Nebenprojekt, über das noch zu schreiben sein wird, war ich auf der Suche nach einer open-source Text-To-Speech-Lösung für Java. Dabei bin ich auf MaryTTS gestoßen. Das ist zwar schon ein paar Jahre alt, dafür aber relativ resourcensparend und sehr einfach zu benutzen. Wie einfach, das zeigt folgendes kleine Tutorial.
MaryTTS steht für Modular Architecture for Research in sYnthesis Text-to-Speech. Das Projekt wurde 2000 von Marc Schröder als Kooperation des Deutschen Forschungszentrums für Künstliche Intelligenz mit dem Insitut für Phonetik der Universität Saarland initiiert. Die neuste Version 5.2 wurde 2012 veröffentlicht.
Marys erste Worte
Für den einfachsten Fall mit englischer Sprachausgabe reicht eine Dependency und ein paar Zeilen Java. In diesem Beispiel wird das Programm mit Gradle gebaut und gibt ganz klassisch den Satz „Hello world“ aus.
build.gradle
Eine Dependency zu reicht für’s erste. Für weitere Sprachen und Stimmen gibt es noch ein paar zusätzliche Pakete. Mehr dazu später.
repositories { mavenLocal() mavenCentral() gradlePluginPortal() } dependencies { implementation group: 'de.dfki.mary', name: 'voice-cmu-slt-hsmm', version: '5.2' }
TextToSpeech.java
Unsere Hauptklasse für die Sprachausgabe. Die Implementierung mit „Thread.sleep“ soll sicherstellen, dass Mary sich nicht selbst unterbrechen kann.
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
Unsere „public static void main“ ist sehr überschaubar:
public static void main(String[] args) throws Exception { TextToSpeech textToSpeech = new TextToSpeech(); textToSpeech.speak("Hello world!"); }
Mehr Sprachen, Stimmen und Effekte
Allerdings bietet MaryTTS schon mehr als einfache Sprachausgabe auf Englisch. Die Onlinedemo unter http://mary.dfki.de:59125/ gibt einen kleinen Einblick in die Vielzahl der verfügbaren Sprachen und Stimmen und erlaubt uns, ein bisschen mit Effekten zu spielen (Hall, „Roboterstimme“ etc.).
Für weitere Stimmen wird jeweils eine neue Dependency benötigt. Dann kann die neue Sprache im Code verwendet werden. Zum Beispiel kann „bits1-hsmm“ für deutsche Sprachausgabe verwendet werden. Vorsicht: Während die MaryTTS-Runtime unter LGPL steht, haben die einzelnen Sprachpakete teilweise abweichende Lizenzen. „bits1“ verwendet BY-ND-3.0.
implementation group: 'de.dfki.mary', name: 'voice-bits1-hsmm', version: '5.2'
mary = new LocalMaryInterface(); mary.setVoice("bits1-hsmm");
Auch Effekte lassen sich hier gleich definieren:
mary.setAudioEffects("Stadium(amount=60.0)");
Feintuning
Die Effekte wirken sich global auf die Sprachausgabe aus. Mary bietet aber die Möglichkeit, die Prosodie mit Tonhöhe, Betonungen und Sprechpausen sehr detailliert zu bestimmen. Dazu muss der InputType auf RAWMARYXML umgestellt werden. Dann kann der generateAudio Methode ein XML-Dokuemnt übergeben werden. Das sieht dann zum Beispiel so aus:
<?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>
Unter http://mary.dfki.de/documentation/maryxml/ finden sich viele anschauliche Beispiele, wobei sich das Featureset teilweise von Stimme zu Stimme unterscheidet. Zusätzliche Dokumentation findet sich noch unter http://mary.dfki.de:59125/documentation.html.
Mary im Jahr 2022
Auch wenn die Qualität nicht mit den modernen Lösungen von Google oder Amazon mithalten kann, ist MaryTTS eine einfache Möglichkeit, betriebssystemunabhängige Sprachausgabe zu realisieren, zum Beispiel für ein kleines RaspberryPi-Projekt. Selbst die neuste Version hat zwar schon gute 10 Jahre auf dem Buckel, die Sprachqualität ist aber gar nicht übel und es werden eine ganze Reihe von Sprachen unterstützt. Es lohnt sich allerdings, verschiedene Stimmen auszuprobieren, da sich die Qualität teilweise deutlich unterscheidet.
1 Pingback