2017-12-06 4 views
0

Ich versuche, mein erstes Python-Programm zu ändern. Ich versuche, this repository zu verwenden, um einige rudimentäre Text-zu-Sprache zu machen. Es geht gut, aber ich möchte es verbessern.Verwenden Sie Pyaudio, um Dateien sofort nach dem anderen zu spielen

Vom Aussehen her gibt es eine 0,145 Sekunden Verzögerung zwischen Samples gespielt. Nicht alle Samples meiner Stimme werden jedoch 0,145 Sekunden sein, und ich möchte, dass jedes Sample ohne Verzögerungen oder Übersprungen nacheinander abgespielt wird.

import re 
import wave 
import pyaudio 
import _thread 
import time 

class TextToSpeech: 

    CHUNK = 1024 

    def __init__(self, words_pron_dict:str = 'cmudict-0.7b.txt'): 
     self._l = {} 
     self._load_words(words_pron_dict) 

    def _load_words(self, words_pron_dict:str): 
     with open(words_pron_dict, 'r') as file: 
      for line in file: 
       if not line.startswith(';;;'): 
        key, val = line.split(' ',2) 
        self._l[key] = re.findall(r"[A-Z]+",val) 

    def get_pronunciation(self, str_input): 
     list_pron = [] 
     for word in re.findall(r"[\w']+",str_input.upper()): 
      if word in self._l: 
       list_pron += self._l[word] 
     print(list_pron) 
     delay = 0.0 
     for pron in list_pron: 
      _thread.start_new_thread(TextToSpeech._play_audio, (pron,delay,)) 
      delay += 0.145 

    def _play_audio(sound, delay): 
     try: 
      time.sleep(delay) 
      wf = wave.open("sounds/"+sound+".wav", 'rb') 
      p = pyaudio.PyAudio() 
      stream = p.open(format=p.get_format_from_width(wf.getsampwidth()), 
       channels=wf.getnchannels(), 
       rate=wf.getframerate(), 
       output=True) 

      data = wf.readframes(TextToSpeech.CHUNK) 

      while data: 
       stream.write(data) 
       data = wf.readframes(TextToSpeech.CHUNK) 

      stream.stop_stream() 
      stream.close() 

      p.terminate() 
     except: 
      pass 




if __name__ == '__main__': 
    tts = TextToSpeech() 
    while True: 
     tts.get_pronunciation(input('Enter a word or phrase: ')) 

Ich habe versucht, die Threading und Verzögerung loszuwerden, aber es gibt noch einige Verzögerung zwischen den Proben. Ich denke, dass ich, anstatt die Verzögerung um 0,145 zu erhöhen, sie um die Länge des Samples in Sekunden erhöhen sollte, aber ich habe mir die Pyaudio-Dokumentation angeschaut, und ich habe keine Ahnung, wie ich das machen soll.

Kann jemand helfen?

+0

Die Länge der Probe wird von 'wave' Modul ausgelesen. PyAudio hat keine Möglichkeit, die WAV-Länge zu kennen. Siehe getnframes-Methode im Wellenmodul https://docs.python.org/3/library/wave.htmlhttps://docs.python.org/3/library/wave.html – dkato

+0

Danke dkato, aber wie würde ich dies anwenden mein Code um jeden Thread so zu verzögern, dass er nur so oft hintereinander abgespielt wird? Ich habe versucht, self.delay in der Klasse zu definieren und das statt der Verzögerung zu ändern, aber es funktioniert nicht. –

Antwort

1

Hier ist ein modifizierter Code, der kontinuierlich WAV-Dateien abspielt.

import re 
import wave 
import pyaudio 

class TextToSpeech: 

    CHUNK = 1024 

    def __init__(self, words_pron_dict='cmudict-0.7b.txt'): 
     self._l = {} 
     self._load_words(words_pron_dict) 

    def _load_words(self, words_pron_dict: str): 
     with open(words_pron_dict, 'r') as file: 
      for line in file: 
       if not line.startswith(';;;'): 
        key, val = line.split(' ', 2) 
        self._l[key] = re.findall(r"[A-Z]+", val) 

    def get_pronunciation(self, str_input): 
     list_pron = [] 
     for word in re.findall(r"[\w']+", str_input.upper()): 
      if word in self._l: 
       list_pron += self._l[word] 
     print(list_pron) 

     # pyaudio set up. 
     # This open method assume all wave files have the same format. 
     p = pyaudio.PyAudio() 
     stream = p.open(format=p.get_format_from_width(2), 
         channels=2, 
         rate=44100, 
         output=True, 
         frames_per_buffer=self.CHUNK) 

     # play each wav file contineuously 
     for pron in list_pron: 
      with wave.open("sounds/"+pron+".wav", 'rb') as wf: 
       data = wf.readframes(TextToSpeech.CHUNK) 
       while data: 
        stream.write(data) 
        data = wf.readframes(TextToSpeech.CHUNK) 

     stream.stop_stream() 
     stream.close() 
     p.terminate() 

if __name__ == '__main__': 
    tts = TextToSpeech() 
    while True: 
     tts.get_pronunciation(input('Enter a word or phrase: ')) 
Verwandte Themen