From 1e5654b4cfa2d057b7865f8982661510195c2ce7 Mon Sep 17 00:00:00 2001 From: Kolja Beigel Date: Thu, 30 Nov 2023 14:05:45 +0100 Subject: [PATCH] fix for stop method --- README.md | 2 +- RealtimeTTS/engines/coqui_engine.py | 41 +++++++++++++---------------- RealtimeTTS/text_to_stream.py | 10 ++++--- setup.py | 2 +- 4 files changed, 27 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 9d68e06..0b35ebe 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ https://github.com/KoljaB/RealtimeTTS/assets/7604638/87dcd9a5-3a4e-4f57-be45-837 ## Updates -Latest Version: v0.3.1 +Latest Version: v0.3.2 #### New Features: - expanded language support, including Chinese (details in [tests](https://github.com/KoljaB/RealtimeTTS/blob/master/tests/chinese_test.py) and [speed test](https://github.com/KoljaB/RealtimeTTS/blob/master/tests/pyqt6_speed_test_chinese.py)). diff --git a/RealtimeTTS/engines/coqui_engine.py b/RealtimeTTS/engines/coqui_engine.py index 346e3e6..7486af4 100644 --- a/RealtimeTTS/engines/coqui_engine.py +++ b/RealtimeTTS/engines/coqui_engine.py @@ -1,5 +1,6 @@ from multiprocessing import Process, Pipe, Event from .base_engine import BaseEngine +from threading import Lock from tqdm import tqdm import numpy as np import traceback @@ -62,6 +63,7 @@ def __init__(self, prepare_text_for_synthesis_callback (function): Function to prepare text for synthesis. If not specified, a default sentence parser will be used. """ + self._synthesize_lock = Lock() self.model_name = model_name self.language = language self.cloning_reference_wav = cloning_reference_wav @@ -77,15 +79,7 @@ def __init__(self, # Start the worker process self.main_synthesize_ready_event = Event() self.parent_synthesize_pipe, child_synthesize_pipe = Pipe() - self.voices_path = voices_path - # if not self.voices_path: - # os.makedirs("voices", exist_ok=True) - # self.voices_path = "voices" - - # current_dir = os.path.dirname(os.path.realpath(__file__)) - # voices_path = os.path.join(current_dir, DEFAULT_VOICES_PATH) - # self.voices_path = voices_path # download coqui model self.local_model_path = None @@ -435,26 +429,27 @@ def synthesize(self, text (str): Text to synthesize. """ - text = self._prepare_text_for_synthesis(text) + with self._synthesize_lock: + text = self._prepare_text_for_synthesis(text) - if len(text) < 1: - return + if len(text) < 1: + return - data = {'text': text, 'language': self.language} - self.send_command('synthesize', data) + data = {'text': text, 'language': self.language} + self.send_command('synthesize', data) - status, result = self.parent_synthesize_pipe.recv() - - while not 'finished' in status: - if 'shutdown' in status or 'error' in status: - if 'error' in status: - logging.error(f'Error synthesizing text: {text}') - logging.error(f'Error: {result}') - return False - self.queue.put(result) status, result = self.parent_synthesize_pipe.recv() - return True + while not 'finished' in status: + if 'shutdown' in status or 'error' in status: + if 'error' in status: + logging.error(f'Error synthesizing text: {text}') + logging.error(f'Error: {result}') + return False + self.queue.put(result) + status, result = self.parent_synthesize_pipe.recv() + + return True @staticmethod def download_file(url, destination): diff --git a/RealtimeTTS/text_to_stream.py b/RealtimeTTS/text_to_stream.py index b388c3f..d313589 100644 --- a/RealtimeTTS/text_to_stream.py +++ b/RealtimeTTS/text_to_stream.py @@ -134,9 +134,9 @@ def play_async(self, """ self.stream_running = True - play_thread = threading.Thread(target=self.play, args=(fast_sentence_fragment, buffer_threshold_seconds, minimum_sentence_length, minimum_first_fragment_length, log_synthesized_text, reset_generated_text, output_wavfile, on_sentence_synthesized, on_audio_chunk, tokenizer, language, context_size)) - play_thread.daemon = True - play_thread.start() + self.play_thread = threading.Thread(target=self.play, args=(fast_sentence_fragment, buffer_threshold_seconds, minimum_sentence_length, minimum_first_fragment_length, log_synthesized_text, reset_generated_text, output_wavfile, on_sentence_synthesized, on_audio_chunk, tokenizer, language, context_size)) + self.play_thread.daemon = True + self.play_thread.start() def _on_audio_chunk(self, chunk): format, _, _ = self.engine.get_stream_info() @@ -379,6 +379,10 @@ def stop(self): else: self.player.stop(immediate=True) self.stream_running = False + + if self.play_thread is not None: + self.play_thread.join() + self._create_iterators() def text(self): diff --git a/setup.py b/setup.py index 6b6fd97..5a4715f 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setuptools.setup( name="RealTimeTTS", - version="0.3.1", + version="0.3.2", author="Kolja Beigel", author_email="kolja.beigel@web.de", description="*Stream text into audio with an easy-to-use, highly configurable library delivering voice output with minimal latency.",