KAZIK/tools/generators/generate_game_sfx.py
Artvasil09 3ad5bf4c9d Develop assembly-only casino scenes and native games
Add native Durak, poker, blackjack, roulette, Buckshot and billiards scenes with animation assets and regression tests. Improve arrival, city, hall, profiles, shops, audio and exit handling; remove the portable C game core and refresh shipping executables.
2026-10-08 22:39:19 +03:00

56 lines
2.1 KiB
Python

"""Small original PCM effects for UI, dice and skill checks; offline only."""
import math
from pathlib import Path
import random
import struct
import wave
RATE = 44100
TARGET = Path(__file__).resolve().parents[2] / "assets/audio/generated"
def save(name, samples):
with wave.open(str(TARGET / name), "wb") as output:
output.setparams((1, 2, RATE, 0, "NONE", "not compressed"))
output.writeframes(b"".join(struct.pack("<h", round(max(-1, min(1, v)) * 28000)) for v in samples))
def tones(name, notes, spacing, duration, gain=0.2):
samples = [0.0] * round(duration * RATE)
for step, frequency in enumerate(notes):
start = round(step * spacing * RATE)
for index in range(start, len(samples)):
t = (index - start) / RATE
envelope = min(1, t / 0.003) * math.exp(-t * 26)
samples[index] += gain * envelope * math.sin(2 * math.pi * frequency * t)
save(name, samples)
def main():
TARGET.mkdir(parents=True, exist_ok=True)
tones("ui-tick.wav", [1300], 0, 0.075, 0.07)
tones("round-win.wav", [523, 659, 784], 0.09, 0.5)
tones("round-loss.wav", [392, 311], 0.10, 0.35, 0.14)
tones("skill-hit.wav", [740, 988], 0.04, 0.20, 0.12)
tones("skill-perfect.wav", [880, 1175, 1568], 0.04, 0.26, 0.15)
tones("skill-miss.wav", [185, 147], 0.04, 0.20, 0.13)
rng = random.Random(4619)
samples = [0.0] * round(1.6 * RATE)
for hit, start in enumerate([0.03, 0.18, 0.48, 0.51, 0.73, 0.94, 0.97, 1.11, 1.29, 1.32]):
amplitude = 0.24 * (1 - start / 2)
offset = round(start * RATE)
pitch = rng.randrange(850, 1600)
for index in range(round(0.16 * RATE)):
if offset + index >= len(samples):
break
t = index / RATE
attack = min(1, t / 0.0007)
click = rng.uniform(-1, 1) * math.exp(-t * 130)
knock = math.sin(2 * math.pi * pitch * t) * math.exp(-t * 60)
samples[offset + index] += amplitude * attack * (click + 0.4 * knock)
save("dice-roll.wav", samples)
print("Generated 7 short game effects; original recordings unchanged.")
if __name__ == "__main__":
main()