Files
AIGame/Tools/generate_skill_slice_sfx.py

33 lines
1.7 KiB
Python

"""Five TangoFlux one-shots for the FireCat/RockBall skill slice; retain original jobs."""
import json
from concurrent.futures import ThreadPoolExecutor
from pathlib import Path
import numpy as np
import requests
from scipy.io import wavfile
import generate_enemy_sfx as audio
ROOT = Path(__file__).resolve().parents[1]
DESIGN = ROOT / 'Doc/Design/Sound/BattleSkills/Slice'
audio.OUT = ROOT / 'Tools/output/skill_slice_sfx'
audio.BUNDLE = ROOT / 'AIClient/Assets/Bundles/Sound/SFX/BattleSkills'
manifest = json.loads((ROOT/'Doc/Design/Sound/BattleSkills/manifest.json').read_text(encoding='utf-8'))
lengths = {'Sfx_FireCharge': .48, 'Sfx_FireLaunch': .28, 'Sfx_FireHit': .4, 'Sfx_RockHit': .32, 'Sfx_Shield': .65}
if __name__ == '__main__':
status = requests.get(audio.BASE+'/api/status', timeout=15).json()
if not status.get('ready') or status.get('error'):
raise RuntimeError('TangoFlux not ready: '+str(status))
for folder in (DESIGN, audio.OUT, audio.BUNDLE): folder.mkdir(parents=True, exist_ok=True)
# The shared generator records its actual seed and request hash, not the planning manifest seed.
rows = [(r['id'], r['prompt'], lengths[r['id']]) for r in manifest['items'] if r['id'] in lengths]
with ThreadPoolExecutor(max_workers=2) as pool:
items = list(pool.map(audio.generate, enumerate(rows)))
(DESIGN/'generation.json').write_text(json.dumps({'status': 'generated', 'service': audio.BASE, 'guide': manifest['guide'], 'items': items}, indent=2), encoding='utf-8')
preview = []
for item in items:
_, samples = wavfile.read(ROOT/item['output'])
preview.extend((samples, np.zeros((13230, 2), dtype=np.int16)))
wavfile.write(DESIGN/'preview.wav', 44100, np.concatenate(preview))