From 5db2d81f4dc9234adad1cb25a27d2917af4747af Mon Sep 17 00:00:00 2001 From: liubing1 Date: Tue, 21 Jan 2025 16:27:29 +0800 Subject: [PATCH] =?UTF-8?q?fix(Git):=20=E5=88=9D=E6=AC=A1=E6=8F=90?= =?UTF-8?q?=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assistant.py | 70 +++++++++++++++++++++++++++++++++++++----------- assistant.yaml | 23 +++++++++++++--- requirements.txt | 28 ++++++++++++++----- 3 files changed, 95 insertions(+), 26 deletions(-) diff --git a/assistant.py b/assistant.py index 768a23f..744acb1 100644 --- a/assistant.py +++ b/assistant.py @@ -15,6 +15,9 @@ import whisper import logging import threading import queue +import asyncio +import edge_tts +import os # Configure logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') @@ -54,9 +57,13 @@ class Assistant: self.audio = pyaudio.PyAudio() - self.tts = pyttsx3.init("nsss"); - self.tts.setProperty('rate', self.tts.getProperty('rate') - 20) - + # Initialize TTS engines + self.tts_engine = pyttsx3.init() + self.tts_engine.setProperty('rate', self.tts_engine.getProperty('rate') - 50) + + # Set default voice for edge-tts + self.edge_voice = self.config.tts.edge_voice + try: self.audio.open(format=INPUT_FORMAT, channels=INPUT_CHANNELS, @@ -114,6 +121,10 @@ class Assistant: config.whisperRecognition.modelPath = configYaml["whisperRecognition"]["modelPath"] config.whisperRecognition.lang = configYaml["whisperRecognition"]["lang"] + config.tts = Inst() + config.tts.engine = configYaml["tts"]["engine"] # 'edge-tts' or 'pyttsx3' + config.tts.edge_voice = configYaml["tts"]["edge_voice"] + return config def display_rec_start(self): @@ -212,7 +223,6 @@ class Assistant: return result_queue.get() - def ask_ollama(self, prompt, responseCallback): logging.info(f"Asking OLLaMa with prompt: {prompt}") full_prompt = prompt if hasattr(self, "contextSent") else (prompt) @@ -256,6 +266,38 @@ class Assistant: logging.error(f"An error occurred while asking OLLaMa: {str(e)}") responseCallback("Sorry, an error occurred. Please try again.") + async def edge_tts_speak(self, text): + try: + logging.info(f"Using edge-tts with voice: {self.edge_voice}") + communicate = edge_tts.Communicate(text, self.edge_voice) + + # 添加调试信息 + logging.info("Starting audio generation...") + await communicate.save("temp_speech.mp3") + logging.info("Audio file generated successfully") + + if not os.path.exists("temp_speech.mp3") or os.path.getsize("temp_speech.mp3") == 0: + raise Exception("Generated audio file is empty or does not exist") + + pygame.mixer.init() + pygame.mixer.music.load("temp_speech.mp3") + pygame.mixer.music.play() + + while pygame.mixer.music.get_busy(): + pygame.time.wait(100) + + pygame.mixer.quit() + + if os.path.exists("temp_speech.mp3"): + os.remove("temp_speech.mp3") + + except Exception as e: + logging.error(f"An error occurred during edge-tts speech playback: {str(e)}") + logging.error(f"Voice being used: {self.edge_voice}") + # 如果 edge-tts 失败,回退到 pyttsx3 + logging.info("Falling back to pyttsx3...") + self.tts_engine.say(text) + self.tts_engine.runAndWait() def text_to_speech(self, text): logging.info(f"Converting text to speech: {text}") @@ -263,19 +305,15 @@ class Assistant: def play_speech(): try: - logging.info("Initializing TTS engine") - engine = pyttsx3.init() + logging.info("Starting speech playback") + time.sleep(0.5) # Short delay before speaking - # Adjust the speech rate (optional) - rate = engine.getProperty('rate') - engine.setProperty('rate', rate - 50) # Decrease the rate by 50 units - - # Add a short delay before converting text to speech - time.sleep(0.5) # Adjust the delay as needed - - logging.info("Converting text to speech") - engine.say(text) - engine.runAndWait() + if self.config.tts.engine == "edge-tts": + asyncio.run(self.edge_tts_speak(text)) + else: # pyttsx3 + self.tts_engine.say(text) + self.tts_engine.runAndWait() + logging.info("Speech playback completed") except Exception as e: logging.error(f"An error occurred during speech playback: {str(e)}") diff --git a/assistant.yaml b/assistant.yaml index 21aa175..68613b6 100644 --- a/assistant.yaml +++ b/assistant.yaml @@ -4,12 +4,29 @@ messages: noAudioInput: "Error: No sound input!" whisperRecognition: - modelPath: "whisper/base.en.pt" - lang: "en" + modelPath: "whisper/base.pt" + lang: "zh" ollama: url: "http://localhost:11434/api/generate" model: "mistral" conversation: - greeting: "Hi, how can I help you?" + greeting: "你好,有什么我可以帮你的吗?" + +tts: + engine: "edge-tts" # 可选值: "edge-tts" 或 "pyttsx3" + edge_voice: "zh-CN-XiaoxiaoNeural" # 中文女声,俏皮可爱 + # 其他活泼可爱的声音选项: + # zh-CN-XiaoqiuNeural (中文女声,活泼开朗) + # zh-CN-XiaoxuanNeural (中文女声,青春活力) + # zh-CN-XiaoyiNeural (中文女声,温柔活泼) + # zh-CN-XiaozhenNeural (中文女声,自然活泼) + # ja-JP-AoiNeural (日语女声,青少年声线) + # ko-KR-SunHiNeural (韩语女声,阳光活力) + # zh-CN-XiaomoNeural (中文女声,俏皮可爱) + # zh-TW-HsiaoYuNeural (台湾女声,较年轻) + # zh-TW-YunJheNeural (台湾男声) + # en-US-AriaNeural (英语女声) + # en-US-GuyNeural (英语男声) + # ko-KR-SunHiNeural (韩语女声) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 4e5124f..fc85e55 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,13 +1,27 @@ -torch==2.1.2 -torchvision==0.16.2 -torchaudio==2.1.2 -pyttsx3==2.90 +# torch==2.2.0 +# torchvision==0.17.0 +# torchaudio==2.2.0 + +# 首先指定较老的 NumPy 版本 +numpy==1.24.3 + +# PyTorch 相关包 +torch==2.1.0 +torchvision==0.16.0 +torchaudio==2.1.0 + + + +pyttsx3==2.98 blobfile==2.1.1 openai==1.7.0 Wave==0.0.2 PyAudio==0.2.14 PyYAML==6.0.1 pygame==2.5.2 -soundfile==0.12.1 -pyObjC==9.0.1 -openai-whisper @ git+https://github.com/openai/whisper.git@ba3f3cd54b0e5b8ce1ab3de13e32122d0d5f98ab \ No newline at end of file +soundfile>=0.10.3 +pyobjc-core==9.2 +pyobjc-framework-Cocoa==9.2 +pyobjc==9.2 +openai-whisper @ git+https://github.com/openai/whisper.git@ba3f3cd54b0e5b8ce1ab3de13e32122d0d5f98ab +TTS==0.21.1 \ No newline at end of file