소스 검색

add TTS module

nico 8 년 전
부모
커밋
711cba195d
1개의 변경된 파일77개의 추가작업 그리고 10개의 파일을 삭제
  1. 77 10
      core/TTS/TTSModule.py

+ 77 - 10
core/TTS/TTSModule.py

@@ -1,5 +1,11 @@
 # coding: utf8
+import hashlib
 import logging
+import os
+
+from core.FileManager import FileManager
+from core.ConfigurationManager import SettingLoader
+from core.Players import Mplayer
 
 logging.basicConfig()
 logger = logging.getLogger("kalliope")
@@ -7,26 +13,87 @@ logger = logging.getLogger("kalliope")
 
 class TTSModule(object):
 
-    def __init__(self):
+    def __init__(self, **kwargs):
         """
-        Mother class of TTS module. Hnadle:
+        Mother class of TTS module. Handle:
         - Cache: call cache object to create file, delete file, check if file exist
-
         - Player: call the default player to play the generated file
         """
+        # set parameter from what we receive from the settings
+        self.cache = kwargs.get('cache', False)
+        self.language = kwargs.get('language', None)
+        self.voice = kwargs.get('voice', "default")
+        # the name of the TSS is the name of the Tss module that have instantiated TTSModule
+        self.tts_caller_name = self.__class__.__name__
+
+        # we don't know yet the words that will be converted to an audio and so we don't have the audio path yet too
+        self.words = None
+        self.file_path = None
+        self.base_cache_path = None
+
+        # load settings
+        self.settings = SettingLoader.get_settings()
+
+        print "Class TTSModule called from module %s, cache: %s, language: %s, voice: %s" % (self.tts_caller_name,
+                                                                                             self.cache,
+                                                                                             self.language,
+                                                                                             self.voice)
 
-    def play_audio(self, audio_file_path):
+    def set_words(self, words):
         """
+        Give the sentence to pronounce to the TTS module so it can generate the file path
+        :param words: string that contain words to give the the TTS engine
+        :return:
+        """
+        self.words = words
+        # we can generate the file path from info we have
+        self.file_path = self._get_path_to_store_audio()
 
-        :param audio_file_path:
+    def play_audio(self):
+        """
+        Play the audio file
         :return:
         """
+        Mplayer.play(self.file_path)
+
+    def _get_path_to_store_audio(self):
+        """
+        Get a sentence (a text) an return the full path of the file
+
+        Path syntax:
+        </path/in/settings>/<tts.name>/tts.parameter["language"]/tts.parameter["voice"]/<md5_of_sentence.tts
+
+        E.g:
+        /tmp/kalliope/voxygene/fr/abcd12345.tts
 
-    def get_path_to_store_audio(self, text):
+        :return: path String
         """
-        Call the cache to get the valid path where the TTS module will store the downloaded or generated file
-        :param text: String text audio we want to save on the local disk
+        md5 = self.generate_md5_from_words(self.words)+".tts"
+        self.base_cache_path = os.path.join(self.settings.cache_path, self.tts_caller_name, self.language, self.voice)
+
+        returned_path = os.path.join(self.base_cache_path, md5)
+        logger.debug("get_path_to_store_audio return: %s" % returned_path)
+        return returned_path
+
+    @staticmethod
+    def generate_md5_from_words(words):
+        if isinstance(words, unicode):
+            words = words.encode('utf-8')
+        return hashlib.md5(words).hexdigest()
+
+    def is_file_already_in_cache(self):
+        """
+        Return true if the file to generate has already been generated before
         :return:
         """
-        # TODO: question: maybe we can implement function in cache directly in TTSModule as it is its job anyway to do all that stuff?
-        pass
+        # generate sub folder
+        FileManager.create_directory(self.base_cache_path)
+
+        # check if the audio file exist
+        exist_in_cache = os.path.exists(self.file_path)
+
+        if exist_in_cache:
+            logger.debug("TTSModule, File already in cache: %s" % self.file_path)
+        else:
+            logger.debug("TTSModule, File not yet in cache: %s" % self.file_path)
+        return exist_in_cache