|
|
|
|
|
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: |
|
|
|
|
|
if platform.system() == "Darwin": |
|
|
with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as wav_file: |
|
|
wav_filename = wav_file.name |
|
|
|
|
|
|
|
|
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() |
|
|
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 |
|
|
|
|
|
|
|
|
sample_rate = 22050 |
|
|
duration = 1.0 |
|
|
samples = int(sample_rate * duration) |
|
|
audio_data = np.zeros(samples, dtype=np.int16) |
|
|
|
|
|
|
|
|
with wave.open(wav_filename, 'w') as wav_file: |
|
|
wav_file.setnchannels(1) |
|
|
wav_file.setsampwidth(2) |
|
|
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 |