import asyncio import os import tempfile import threading import pygame import edge_tts from config import TTS_VOICE, TTS_RATE, TTS_PITCH pygame.mixer.init() _stop_event = threading.Event() def stop_speaking(): """Unterbricht laufende Sprachausgabe (z.B. wenn User spricht).""" _stop_event.set() pygame.mixer.music.stop() def speak(text: str): """Text → Edge TTS → Lautsprecher. Blockiert bis fertig oder unterbrochen.""" _stop_event.clear() async def _run(): with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as f: tmp_path = f.name communicate = edge_tts.Communicate(text, TTS_VOICE, rate=TTS_RATE, pitch=TTS_PITCH) await communicate.save(tmp_path) if _stop_event.is_set(): os.unlink(tmp_path) return pygame.mixer.music.load(tmp_path) pygame.mixer.music.play() while pygame.mixer.music.get_busy(): if _stop_event.is_set(): pygame.mixer.music.stop() break pygame.time.wait(50) os.unlink(tmp_path) asyncio.run(_run()) def play_ding(): """Kurzer Aktivierungs-Ton (440 Hz, 120ms).""" import numpy as np sample_rate = 44100 duration = 0.12 t = np.linspace(0, duration, int(sample_rate * duration), False) wave = (np.sin(2 * np.pi * 440 * t) * 0.3 * 32767).astype(np.int16) stereo = np.column_stack([wave, wave]) sound = pygame.sndarray.make_sound(stereo) sound.play() pygame.time.wait(int(duration * 1000) + 20)