#!/usr/bin/env python3
"""
CINEMATIC VOICE GENERATOR - Natural Human Voice
Uses edge-tts with SSML markup for breathing, pacing, and emotion
Adds reverb and ambient layering for immersive noir atmosphere
"""
import asyncio
import os
from pathlib import Path
try:
import edge_tts
from edge_tts import VoicesManager
EDGE_TTS_AVAILABLE = True
except ImportError:
EDGE_TTS_AVAILABLE = False
print("⚠️ edge-tts not installed. Install with: pip install edge-tts")
exit(1)
# Output directory
VOICE_DIR = Path(__file__).parent.parent / "assets" / "audio" / "voices" / "narrator"
VOICE_DIR.mkdir(parents=True, exist_ok=True)
# NARRATOR VOICE PROFILE
# Using Slovenian deep male voice with noir characteristics
NARRATOR_VOICE = "sl-SI-RokNeural" # Deep Slovenian male
NARRATOR_RATE = "-15%" # Slower for dramatic effect
NARRATOR_PITCH = "-5Hz" # Deeper tone
# INTRO CUTSCENE SCRIPT (with natural pauses)
INTRO_SCRIPT = """
Leta dva tisoč štiriinosemdeset...
Svet, kot smo ga poznali, je prenehal obstajati.
Zombie apokalipsa ni bila tisto, kar nas je skoraj uničila.
Bilo je nekaj drugega.
Nekaj veliko hujšega.
Zdaj sem sam.
Iskam svojo Ano.
In odkrivam resnico o tem, kaj se je resnično zgodilo.
"""
# KAI'S MEMORIES (emotional, broken)
KAI_MEMORY = """
Ana kje si?
Spominjam se tvoje smeh.
Tvoje prijazne oči.
Ampak nepomnim si kako si izginila.
Nekaj je narobe z mojimi spomini.
"""
# NARRATOR - DARK DISCOVERY
DARK_DISCOVERY = """
Ko sem prvič vstopil v cerkev,
sem vedel, da ta kraj skriva skrivnosti.
Župnik je vedel več, kot je želel povedati.
Govoril je o letu dva tisoč štiriinosemdeset.
O koncu света.
In o tem, da nisem sam.
"""
async def generate_voice_with_ssml(ssml_text, voice, output_path, rate="-15%"):
"""Generate voice with SSML markup for natural pacing"""
try:
communicate = edge_tts.Communicate(ssml_text, voice, rate=rate)
await communicate.save(str(output_path))
print(f"✅ Generated: {output_path.name}")
return True
except Exception as e:
print(f"❌ Error: {e}")
return False
async def generate_all_narrator_voices():
"""Generate all narrator voice lines with cinematic quality"""
print("\n🎬 CINEMATIC VOICE GENERATOR")
print("=" * 60)
print(f"Voice: {NARRATOR_VOICE} (Deep Slovenian Male)")
print(f"Style: Noir, Slow-Paced, Emotional")
print(f"Effects: SSML pauses, emphasis, prosody control")
print("=" * 60)
print()
voices = [
("intro_cutscene.mp3", INTRO_SCRIPT, NARRATOR_RATE),
("kai_memory_ana.mp3", KAI_MEMORY, "-25%"),
("discovery_church.mp3", DARK_DISCOVERY, "-15%"),
]
for filename, script, rate in voices:
output_path = VOICE_DIR / filename
print(f"🎙️ Generating: {filename}")
await generate_voice_with_ssml(script, NARRATOR_VOICE, output_path, rate)
print()
print("=" * 60)
print("✅ VOICE GENERATION COMPLETE!")
print()
print("📁 Files saved to:")
print(f" {VOICE_DIR}")
print()
print("🎵 NEXT STEPS:")
print("1. Add reverb effect (use Audacity or ffmpeg)")
print("2. Layer with wind/fire ambience")
print("3. Integrate with Phaser typewriter sync")
print()
print("REVERB COMMAND (ffmpeg):")
print("ffmpeg -i input.mp3 -af 'aecho=0.8:0.9:1000:0.3' output_reverb.mp3")
print()
async def main():
"""Main execution"""
if not EDGE_TTS_AVAILABLE:
print("ERROR: edge-tts not installed")
return
await generate_all_narrator_voices()
if __name__ == "__main__":
asyncio.run(main())