"""Gera os 7 efeitos sonoros do Xeonjia que o autor nao credita (collision, damage, dialog, explosion, money, punch, snowball); os tres que o README dele credita ao Yubatake (gameover, item, win) ficam como estao. Sintese propria, deterministica (PRNG com semente fixa), dedicada ao dominio publico (CC0). Escreve WAV estereo de 16 bits a 44,1 kHz e converte em .oga (Ogg Vorbis) com o wav2ogg do projeto (Builds/pygame-music/wav2ogg.c, numero de serie fixo: mesma entrada, mesmos bytes). Mesmos nomes de arquivo do jogo. python3 -I sounds.py """ import math, os, random, struct, subprocess, sys SR = 44100 def buf(seconds): return [0.0] * int(SR * seconds) def add(dst, src, at=0.0, gain=1.0): o = int(at * SR) for i, v in enumerate(src): if o + i < len(dst): dst[o + i] += v * gain def env(t, attack, decay): return min(1.0, t / attack) * math.exp(-t / decay) if attack else math.exp(-t / decay) def tone(freq, dur, decay, attack=0.004, shape='sine', f_end=None): out, ph = [], 0.0 n = int(SR * dur) for i in range(n): t = i / SR f = freq if f_end is None else freq + (f_end - freq) * (t / dur) ph += 2 * math.pi * f / SR s = math.sin(ph) if shape == 'tri': s = 2 / math.pi * math.asin(s) elif shape == 'soft': # seno com um pouco de harmonicos s = s + 0.25 * math.sin(2 * ph) + 0.1 * math.sin(3 * ph) out.append(s * env(t, attack, decay)) return out def noise(dur, decay, rng, lp=1.0, attack=0.0005): out, y = [], 0.0 for i in range(int(SR * dur)): t = i / SR y += lp * (rng.uniform(-1, 1) - y) out.append(y * env(t, attack, decay)) return out def sweep_noise(dur, rng, f0, f1, decay): out, y = [], 0.0 n = int(SR * dur) for i in range(n): t = i / SR a = 1 - math.exp(-2 * math.pi * (f0 + (f1 - f0) * t / dur) / SR) y += a * (rng.uniform(-1, 1) - y) out.append(y * env(t, 0.003, decay)) return out def clap(rng, gain=1.0): n = noise(0.09, 0.018, rng, lp=0.55, attack=0.0008) # passa-altas simples para tirar o grave out, prev = [], 0.0 for v in n: out.append((v - prev * 0.6) * gain) prev = v return out def finish(mono, path, pan=None): peak = max(1e-9, max(abs(v) for v in mono)) scale = 0.85 / peak n = len(mono) fade = int(0.005 * SR) data = bytearray() for i, v in enumerate(mono): if i > n - fade: v *= (n - i) / fade s = max(-32767, min(32767, int(v * scale * 32767))) data += struct.pack('