瀏覽代碼

Merge branch 'tts'

Conflicts:
	core/Cache.py
nico 8 年之前
父節點
當前提交
f5f7b4dc6b
共有 6 個文件被更改,包括 51 次插入27 次删除
  1. 8 8
      core/AudioPlayer.py
  2. 9 1
      core/Cache.py
  3. 1 1
      settings.yml
  4. 6 5
      tts/TTS.py
  5. 23 9
      tts/pico2wave/pico2wave.py
  6. 4 3
      tts/voxygen/voxygen.py

+ 8 - 8
core/AudioPlayer.py

@@ -13,7 +13,9 @@ class AudioPlayer:
     AUDIO_MP3_CHANNEL = 1
     AUDIO_MP3_BUFFER = 2048
 
-    def __init__(self, default_type=None, audio_frequency=AUDIO_MP3_FREQUENCY, audio_size=AUDIO_MP3_SIZE, audio_channel=AUDIO_MP3_CHANNEL, audio_buffer=AUDIO_MP3_BUFFER):
+    AUDIO_DEFAULT_VOLUME = 0.8
+
+    def __init__(self, default_type=None, audio_frequency=AUDIO_MP3_FREQUENCY, audio_size=AUDIO_MP3_SIZE, audio_channel=AUDIO_MP3_CHANNEL, audio_buffer=AUDIO_MP3_BUFFER, volume=AUDIO_DEFAULT_VOLUME):
         if default_type == self.PLAYER_MP3:
             self.audio_frequency = self.AUDIO_MP3_FREQUENCY
             self.audio_size = self.AUDIO_MP3_SIZE
@@ -24,11 +26,12 @@ class AudioPlayer:
             self.audio_size = audio_size
             self.audio_channel = audio_channel
             self.audio_buffer = audio_buffer
+        self.volume = volume
         pygame.mixer.init(audio_frequency, audio_size, audio_channel, audio_buffer)
 
-    def play_audio(self, music_file, volume=0.8, keep_file=False):
+    def play_audio(self, music_file):
         try:
-            self._init_player_audio(music_file, volume)
+            self._init_player_audio(music_file)
             logging.debug("Music file %s loaded!", music_file)
         except pygame.error:
             FileManager.remove_file(music_file)
@@ -36,12 +39,9 @@ class AudioPlayer:
             return
 
         self._start_player_audio()
-        if not keep_file:
-            FileManager.remove_file(music_file)
 
-    @staticmethod
-    def _init_player_audio(music_file, volume):
-        pygame.mixer.music.set_volume(volume)
+    def _init_player_audio(self, music_file):
+        pygame.mixer.music.set_volume(self.volume)
         pygame.mixer.music.load(music_file)
 
     @staticmethod

+ 9 - 1
core/Cache.py

@@ -8,7 +8,9 @@ from core.FileManager import FileManager
 class Cache:
     DEFAULT_MODULE_NAME = "default"
     DEFAULT_CACHE_PATH = "/tmp/jarvis/tts"
-    DEFAULT_CACHE_EXTENSION = ".tts"
+    DEFAULT_CACHE_EXTENSION = "tts"
+    DEFAULT_LANGUAGE = "default"
+    DEFAULT_VOICE = "default"
 
     def __init__(self, module_name=DEFAULT_MODULE_NAME, cache_path=DEFAULT_CACHE_PATH, cache_extension=DEFAULT_CACHE_EXTENSION):
         self._module_name = module_name
@@ -25,3 +27,9 @@ class Cache:
         FileManager.create_directory(cache_directory)
         logging.debug("Cache directory %s exists and File path for audio is: %s", cache_directory, file_path)
         return file_path
+
+    @staticmethod
+    def remove_audio_file(file_path, cache):
+        if not cache:
+            FileManager.remove_file(file_path)
+

+ 1 - 1
settings.yml

@@ -37,7 +37,7 @@ speech_to_text:
 # - pico2wave
 text_to_speech:
   - pico2wave:
-      language: "fr-FR"
+      language: "fr"
   - voxygen:
       language: "fr"
       voice: "michel"

+ 6 - 5
tts/TTS.py

@@ -3,9 +3,10 @@ from core import Cache
 
 
 class TTS:
-    def __init__(self, audio_player_type=None):
-        self.cache = Cache(module_name=self.__class__.__name__)
-        self.audio_player = AudioPlayer(audio_player_type)
+    def __init__(self, audio_player_type=None, cache_extension=None, volume=0.8):
+        self.cache = Cache(module_name=self.__class__.__name__, cache_extension=cache_extension)
+        self.audio_player = AudioPlayer(audio_player_type, volume=volume)
 
-    def play_audio(self, music_file, volume=0.8, keep_file=False):
-        self.audio_player.play_audio(music_file, volume, keep_file)
+    def play_audio(self, music_file, cache=False):
+        self.audio_player.play_audio(music_file)
+        self.cache.remove_audio_file(music_file, cache)

+ 23 - 9
tts/pico2wave/pico2wave.py

@@ -1,17 +1,31 @@
 import subprocess
-from core import AudioPlayer
 from tts import TTS
+import logging, sys
 
 
 class Pico2wave(TTS):
+    PICO2WAVE_LANGUAGES = dict(fr="fr-FR", us="en-US", uk="en-GB", de="de-DE", es="es-ES", it="it-IT")
+    PICO2WAVE_LANGUAGES_DEFAULT = PICO2WAVE_LANGUAGES['fr']
 
     def __init__(self, audio_player_type=None):
-        TTS.__init__(self, audio_player_type)
-
-    def say(self, words=None, language=None):
-        temp_file = "/tmp/temp.wav"
-        devnull = open("/dev/null", "w")
-        subprocess.check_output(["/usr/bin/pico2wave", "-l=%s" % language, "-w=%s" % temp_file, words], stderr=devnull)
-        self.play_audio(temp_file)
-        devnull.close()
+        TTS.__init__(self, audio_player_type, "wav")
+
+    def say(self, words=None, language=PICO2WAVE_LANGUAGES_DEFAULT, cache=False):
+        language = self.get_voice(language)
+        file_path = self.cache.get_audio_file_cache_path(words, language=language)
+
+        self.get_audio(words, language, file_path)
+        self.play_audio(file_path, cache=cache)
+
+    def get_voice(self, language):
+        if language in self.PICO2WAVE_LANGUAGES:
+            return self.PICO2WAVE_LANGUAGES[language]
+
+        logging.warn("Cannot find language matching language: %s voice: %s replace by default voice: %s", language, self.PICO2WAVE_LANGUAGES_DEFAULT)
+        return self.PICO2WAVE_LANGUAGES_DEFAULT
+
+    @staticmethod
+    def get_audio(words, language, file_path):
+        subprocess.check_output(["/usr/bin/pico2wave", "-l=%s" % language, "-w=%s" % file_path, words], stderr=sys.stderr)
+
 

+ 4 - 3
tts/voxygen/voxygen.py

@@ -36,7 +36,8 @@ class Voxygen(TTS):
         file_path = self.cache.get_audio_file_cache_path(words, voice, language)
 
         if self.get_audio(voice, words, file_path, cache):
-            self.play_audio(file_path, keep_file=cache)
+            self.play_audio(file_path)
+            self.cache.remove_audio_file(file_path, cache)
 
     def get_voice(self, voice, language):
         if language in self.VOXYGEN_LANGUAGES and voice in self.VOXYGEN_LANGUAGES[language]:
@@ -45,11 +46,11 @@ class Voxygen(TTS):
         logging.warn("Cannot find language matching language: %s voice: %s replace by default voice: %s", language, voice, self.VOXYGEN_VOICE_DEFAULT)
         return self.VOXYGEN_VOICE_DEFAULT
 
-    def get_audio(self, voice, text, file_path, cache):
+    def get_audio(self, voice, words, file_path, cache):
         if not cache or not os.path.exists(file_path) or FileManager.file_is_empty(file_path):
             payload = {
                 "method": "redirect",
-                "text": text.encode('utf8'),
+                "text": words.encode('utf8'),
                 "voice": voice
             }