#!/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())