summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/tts.py71
1 files changed, 71 insertions, 0 deletions
diff --git a/client/tts.py b/client/tts.py
index 55c33b0..43c8ccb 100644
--- a/client/tts.py
+++ b/client/tts.py
@@ -15,6 +15,9 @@ import subprocess
import pipes
import logging
import wave
+import urllib
+import urlparse
+import requests
from abc import ABCMeta, abstractmethod
import argparse
@@ -328,6 +331,74 @@ class GoogleTTS(AbstractMp3TTSEngine):
os.remove(tmpfile)
+class MaryTTS(AbstractTTSEngine):
+ """
+ Uses the MARY Text-to-Speech System (MaryTTS)
+ MaryTTS is an open-source, multilingual Text-to-Speech Synthesis platform
+ written in Java.
+ Please specify your own server instead of using the demonstration server
+ (http://mary.dfki.de:59125/) to save bandwidth and to protect your privacy.
+ """
+
+ SLUG = "mary-tts"
+
+ def __init__(self, server="mary.dfki.de", port="59125", language="en_GB",
+ voice="dfki-spike"):
+ super(self.__class__, self).__init__()
+ self.server = server
+ self.port = port
+ self.netloc = '{server}:{port}'.format(server=self.server,
+ port=self.port)
+ self.language = language
+ self.voice = voice
+ self.session = requests.Session()
+
+ @property
+ def languages(self):
+ r = self.session.get(self._makeurl('/locales'))
+ r.raise_for_status()
+ return r.text.splitlines()
+
+ @property
+ def voices(self):
+ r = self.session.get(self._makeurl('/voices'))
+ r.raise_for_status()
+ return [line.split()[0] for line in r.text.splitlines()]
+
+ @classmethod
+ def is_available(cls):
+ return (super(cls, cls).is_available() and
+ diagnose.check_network_connection())
+
+ def _makeurl(self, path, query={}):
+ query_s = urllib.urlencode(query)
+ urlparts = ('http', self.netloc, path, query_s, '')
+ return urlparse.urlunsplit(urlparts)
+
+ def say(self, phrase):
+ self._logger.debug("Saying '%s' with '%s'", phrase, self.SLUG)
+ if self.language not in self.languages:
+ raise ValueError("Language '%s' not supported by '%s'"
+ % (self.language, self.SLUG))
+
+ if self.voice not in self.voices:
+ raise ValueError("Voice '%s' not supported by '%s'"
+ % (self.voice, self.SLUG))
+ query = {'OUTPUT_TYPE': 'AUDIO',
+ 'AUDIO': 'WAVE_FILE',
+ 'INPUT_TYPE': 'TEXT',
+ 'INPUT_TEXT': phrase,
+ 'LOCALE': self.language,
+ 'VOICE': self.voice}
+
+ r = self.session.get(self._makeurl('/process', query=query))
+ with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as f:
+ f.write(r.content)
+ tmpfile = f.name
+ self.play(tmpfile)
+ os.remove(tmpfile)
+
+
def get_default_engine_slug():
return 'osx-tts' if platform.system() == 'darwin' else 'espeak-tts'