Пример #1
0
def main():
    args = arg_parser()
    play = Player(dummy=args.quiet)
    tts = TTS(threads=1)
    text_size_all = 0
    reply_size_all = 0
    reply_time_all = 0
    full_time_all = 0
    counts = 0
    while True:
        text = args.file.read(args.chunks)
        if not text:
            break
        text_size = len(text)
        reply_size = 0
        full_time = time.time()
        reply_time = None
        with tts.say(text, voice=args.voice, format_='wav') as say:
            for chunk in say:
                if reply_time is None:
                    reply_time = time.time() - full_time
                reply_size += len(chunk)
                play.play_chunk(chunk)
        full_time = time.time() - full_time

        text_size_all += text_size
        reply_size_all += reply_size
        reply_time_all += reply_time
        full_time_all += full_time
        counts += 1
        _print(text_size, reply_size, reply_time, full_time)
    args.file.close()
    play.close()
    tts.join()
    if counts:
        print('Summary:')
        _print(text_size_all, reply_size_all, reply_time_all / counts, full_time_all)
    print('bye.')
Пример #2
0
class Player(threading.Thread):
    def __init__(self):
        super().__init__()
        self.tts = TTS(threads=1, force_process=False)
        self._queue = queue.Queue()
        self._p_audio = pyaudio.PyAudio()
        self._stream = self._p_audio.open(
            format=self._p_audio.get_format_from_width(2),
            channels=1,
            rate=24000,
            output=True,
            start=False,
        )
        self._sets = {
            'absolute_rate': '50',
            'absolute_pitch': '50',
            'absolute_volume': '50',
            'voice': ['anna']
        }
        self._nums = 'min: 0, max 100'
        self._info = '{}: [{}] current: {}'
        self._work = True
        self._clear_queue = threading.Event()
        self.start()

    def volume(self, volume):
        if not volume:
            return self._info.format('Volume', self._nums,
                                     self._sets['absolute_volume'])
        else:
            return self._set_set('absolute_volume', volume)

    def rate(self, rate):
        if not rate:
            return self._info.format('Rate', self._nums,
                                     self._sets['absolute_rate'])
        else:
            return self._set_set('absolute_rate', rate)

    def pitch(self, pitch):
        if not pitch:
            return self._info.format('Pitch', self._nums,
                                     self._sets['absolute_pitch'])
        else:
            return self._set_set('absolute_pitch', pitch)

    def voice(self, voice):
        if not voice:
            return self._info.format('Voice', ', '.join(self.tts.voices),
                                     ', '.join(self._sets['voice']))
        else:
            if isinstance(voice, str):
                voice = [voice]
            voice = voice[:2]
            return self._set_set('voice', voice)

    def _set_set(self, param, value):
        if self._sets[param] == value:
            return 'unchanged'
        if param == 'voice':
            return self._set_voice(value)
        else:
            n_value = _prepare_set(value)
            if n_value is None:
                return 'bad value: {}'.format(value)
            self._sets[param] = str(n_value)
            self.tts.set_params(**{param: _normalize_set(n_value)})
            return 'success'

    def _set_voice(self, voice):
        for target in voice:
            if target not in self.tts.voices:
                return 'unknown voice: {}'.format(target)
        self._sets['voice'] = voice
        return 'success'

    def _text(self, text):
        for line in textwrap.wrap(text, 200):
            if not self._work:
                break
            line = line.strip('\n')
            if line:
                yield line

    def _clear(self):
        if self._clear_queue.is_set():
            while self._queue.qsize():
                try:
                    self._queue.get_nowait()
                except queue.Empty:
                    break
            self._clear_queue.clear()

    def clear(self):
        self._clear_queue.set()

    def stop(self):
        if self._work:
            self._work = False
            self._queue.put_nowait(None)
            self.join()
            self.tts.join()
            self._stream.stop_stream()
            self._stream.close()
            self._p_audio.terminate()

    def run(self):
        while self._work:
            self._clear()
            data = self._queue.get()
            if not data:
                break
            self._say(data)

    def say(self, text: str, print_=True):
        if not text:
            return
        if print_:
            print(text)
        self._queue.put_nowait(text)

    def _say(self, text):
        self._stream.start_stream()
        with self.tts.say(self._text(text), self._sets['voice'], 'pcm') as gen:
            for chunk in gen:
                if not self._work or self._clear_queue.is_set():
                    break
                self._stream.write(chunk)

        self._stream.stop_stream()