# modules/tts_handler.py import subprocess import platform import sys import os import config import tempfile import numpy as np import wave def text_to_speech_file(text_to_speak): """Generate TTS audio file - with fallback to silent audio if TTS fails""" print(f"AI generating audio for: {text_to_speak[:100]}...") try: # Try using system TTS (macOS say command) if platform.system() == "Darwin": # macOS with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as wav_file: wav_filename = wav_file.name # Use macOS 'say' command to generate speech command = ['say', '-o', wav_filename, '--data-format=LEF32@22050', text_to_speak] process = subprocess.run(command, capture_output=True, text=True, timeout=30) if process.returncode == 0 and os.path.exists(wav_filename): print("✅ TTS generated successfully with macOS 'say'") return wav_filename else: print("❌ macOS 'say' command failed, falling back to silent audio") return create_silent_audio() # Try Linux TTS options elif platform.system() == "Linux": # Check if espeak is available (common on Linux systems) if subprocess.run(['which', 'espeak'], capture_output=True).returncode == 0: with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as wav_file: wav_filename = wav_file.name command = ['espeak', '-w', wav_filename, text_to_speak] process = subprocess.run(command, capture_output=True, text=True, timeout=30) if process.returncode == 0 and os.path.exists(wav_filename): print("✅ TTS generated successfully with espeak") return wav_filename else: print("❌ espeak command failed, falling back to silent audio") return create_silent_audio() else: print("❌ No TTS engine available on Linux, using silent audio") return create_silent_audio() else: print("❌ TTS not available on this system, using silent audio") return create_silent_audio() except Exception as e: print(f"❌ TTS generation failed: {e}") return create_silent_audio() def create_silent_audio(): """Create a short silent audio file as fallback""" try: with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as wav_file: wav_filename = wav_file.name # Create 1 second of silence sample_rate = 22050 duration = 1.0 # seconds samples = int(sample_rate * duration) audio_data = np.zeros(samples, dtype=np.int16) # Write WAV file with wave.open(wav_filename, 'w') as wav_file: wav_file.setnchannels(1) # Mono wav_file.setsampwidth(2) # 2 bytes per sample wav_file.setframerate(sample_rate) wav_file.writeframes(audio_data.tobytes()) print("✅ Silent audio fallback created") return wav_filename except Exception as e: print(f"❌ Even silent audio creation failed: {e}") return None