Files
novafarma/scripts/generate_audio_placeholders.py
David Kotnik 4a5b788ad4 🎬🎵 Jan 8 COMPLETE AUDIO PRODUCTION - Intro + Music + SFX
 FULL AUDIO SYSTEM READY (104 FILES):

**🎙️ INTRO CUTSCENE VOICES (4 NEW MP3):**
Generated via Edge TTS:
1. 01_narrator_flyover.mp3 (73KB) - 'They say the world didn't die...'
2. 02_kai_awakening.mp3 (28KB) - 'My head... it hurts. Where am I?'
3. 03_kai_truth_part1.mp3 (67KB) - 'Kai Marković. 14 years old...'
4. 04_kai_truth_part2.mp3 (51KB) - 'I'm coming to find you... Ana.'

**Story Structure:**
- Part 1: The Flyover (0:00-0:45) - Narrator
- Part 2: The Awakening (0:45-1:10) - Kai confused
- Part 3: The Truth (1:10-2:00) - Kai determined

**🎵 MUSIC PLACEHOLDERS (7 WAV - 60MB):**
Simple ambient loops for testing:
1. main_theme.wav (90s) - Menu music
2. farm_ambient.wav (120s) - Farming
3. town_theme.wav (90s) - Town restoration
4. combat_theme.wav (60s) - Battle
5. night_theme.wav (180s) - Nighttime
6. victory_theme.wav (30s) - Quest complete
7. ana_theme.wav (120s) - Emotional/flashback

**🔊 SFX PLACEHOLDERS (23 WAV - 1.5MB):**
Farming (8): plant_seed, water_crop, harvest, dig, scythe, mine, chop, cow
Combat (8): sword, bow, zombie_hit, zombie_death, hurt, shield, explosion, raider
Building (5): chest, door_open, door_close, hammer, repair
Misc (2): coin_collect, level_up

**📊 TOTAL AUDIO INVENTORY:**
- Voice Files: 28 MP3 (24 existing + 4 new intro)
- Voiceover: 43 WAV (prologue cutscenes)
- Sound Effects: 25 WAV (2 existing + 23 new placeholders)
- Music: 8 tracks (1 existing + 7 new placeholders)
- **TOTAL: 104 audio files!**

**🎮 INTEGRATION:**
- Updated PreloadScene with intro voice loading
- All audio keys ready for use in intro cutscene
- BiomeMusicSystem ready for 7-track cross-fade
- AudioTriggerSystem ready for all 23 SFX

**📝 SCRIPTS CREATED:**
1. scripts/generate_intro_cutscene.py - Intro dialogue generation
2. scripts/generate_audio_placeholders.py - Music + SFX placeholders

**🎯 USAGE:**
Intro voices: 'intro_flyover', 'intro_awakening', 'intro_truth_1', 'intro_truth_2'
Music: Load from assets/audio/music/*.wav
SFX: Load from assets/audio/sfx/[category]/*.wav

**⚠️  NOTE:** Music/SFX are PLACEHOLDERS (simple tones)
Replace with real audio from Freesound.org or AI generators later!

🎉 AUDIO SYSTEM 100% FUNCTIONAL FOR TESTING!
2026-01-08 17:05:57 +01:00

159 lines
5.3 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Audio Placeholder Generator
Creates simple placeholder audio files for testing
"""
import numpy as np
from scipy.io import wavfile
from pathlib import Path
SAMPLE_RATE = 44100 # CD quality
OUTPUT_DIR_MUSIC = Path("/Users/davidkotnik/repos/novafarma/assets/audio/music")
OUTPUT_DIR_SFX = Path("/Users/davidkotnik/repos/novafarma/assets/audio/sfx")
def generate_tone(frequency, duration, sample_rate=SAMPLE_RATE):
"""Generate a simple sine wave tone"""
t = np.linspace(0, duration, int(sample_rate * duration))
tone = np.sin(2 * np.pi * frequency * t)
# Convert to 16-bit PCM
tone = (tone * 32767).astype(np.int16)
return tone
def generate_noise(duration, sample_rate=SAMPLE_RATE):
"""Generate white noise"""
noise = np.random.normal(0, 0.1, int(sample_rate * duration))
noise = (noise * 32767).astype(np.int16)
return noise
def generate_ambient_loop(duration=60, base_freq=220):
"""Generate simple ambient loop"""
t = np.linspace(0, duration, int(SAMPLE_RATE * duration))
# Multiple sine waves for ambient feel
ambient = (
0.3 * np.sin(2 * np.pi * base_freq * t) +
0.2 * np.sin(2 * np.pi * (base_freq * 1.5) * t) +
0.15 * np.sin(2 * np.pi * (base_freq * 0.75) * t) +
0.05 * np.random.normal(0, 0.1, len(t)) # Subtle noise
)
# Fade in/out for seamless loop
fade_samples = int(SAMPLE_RATE * 2) # 2 second fade
fade_in = np.linspace(0, 1, fade_samples)
fade_out = np.linspace(1, 0, fade_samples)
ambient[:fade_samples] *= fade_in
ambient[-fade_samples:] *= fade_out
ambient = (ambient * 32767 * 0.5).astype(np.int16)
return ambient
def create_music_placeholders():
"""Create 7 music track placeholders"""
print("\n🎵 CREATING MUSIC PLACEHOLDERS...")
print("="*60)
OUTPUT_DIR_MUSIC.mkdir(parents=True, exist_ok=True)
music_tracks = {
"main_theme": (440, 90), # A note, 1.5 min
"farm_ambient": (220, 120), # A lower, 2 min
"town_theme": (330, 90), # E note
"combat_theme": (523, 60), # C note, 1 min
"night_theme": (196, 180), # G note, 3 min
"victory_theme": (659, 30), # E note, 30 sec
"ana_theme": (247, 120), # B note, 2 min
}
for name, (freq, duration) in music_tracks.items():
print(f"\n🎶 Generating: {name}.wav")
print(f" Frequency: {freq}Hz, Duration: {duration}s")
audio = generate_ambient_loop(duration, freq)
output_path = OUTPUT_DIR_MUSIC / f"{name}.wav"
wavfile.write(output_path, SAMPLE_RATE, audio)
size = output_path.stat().st_size
print(f" ✅ Saved: {size:,} bytes")
print(f"\n✅ Created {len(music_tracks)} music placeholders")
def create_sfx_placeholders():
"""Create 23 SFX placeholders"""
print("\n\n🔊 CREATING SFX PLACEHOLDERS...")
print("="*60)
sfx_sounds = {
# Farming (8)
"farming/plant_seed": (880, 0.3),
"farming/water_crop": (440, 1.0),
"farming/harvest": (1320, 0.5),
"farming/dig": (220, 0.8),
"farming/scythe_swing": (660, 0.6),
"farming/stone_mine": (330, 0.7),
"farming/tree_chop": (165, 0.8),
"farming/cow_moo": (110, 1.5),
# Combat (8)
"combat/sword_slash": (1100, 0.4),
"combat/bow_release": (880, 0.3),
"combat/zombie_hit": (220, 0.5),
"combat/zombie_death": (110, 1.0),
"combat/player_hurt": (330, 0.5),
"combat/shield_block": (440, 0.4),
"combat/explosion": (55, 1.5),
"combat/raider_attack": (165, 0.8),
# Building (5)
"building/chest_open": (660, 0.8),
"building/door_open": (440, 0.6),
"building/door_close": (330, 0.6),
"building/hammer_nail": (1100, 0.3),
"building/repair": (880, 1.0),
# Misc (2)
"misc/coin_collect": (1760, 0.3),
"misc/level_up": (1320, 1.5),
}
for name, (freq, duration) in sfx_sounds.items():
# Create subfolder if needed
sfx_path = OUTPUT_DIR_SFX / name.split('/')[0]
sfx_path.mkdir(parents=True, exist_ok=True)
filename = name.split('/')[1] + ".wav"
output_path = sfx_path / filename
print(f"\n🔊 Generating: {name}.wav")
print(f" Frequency: {freq}Hz, Duration: {duration}s")
audio = generate_tone(freq, duration)
wavfile.write(output_path, SAMPLE_RATE, audio)
size = output_path.stat().st_size
print(f" ✅ Saved: {size:,} bytes")
print(f"\n✅ Created {len(sfx_sounds)} SFX placeholders")
def main():
"""Generate all placeholders"""
print("="*60)
print("🎨 AUDIO PLACEHOLDER GENERATOR")
print("="*60)
print("\nGenerating simple tone-based placeholders for testing...")
print("Replace these with real audio later!")
create_music_placeholders()
create_sfx_placeholders()
print("\n" + "="*60)
print("✅ ALL PLACEHOLDERS GENERATED!")
print("="*60)
print("\nTotal files created: 30 (7 music + 23 SFX)")
print("\n⚠️ NOTE: These are simple BEEP PLACEHOLDERS for testing!")
print("Replace with real audio from Freesound.org or AI generators.")
if __name__ == "__main__":
main()