"""Gera os 9 efeitos sonoros do Rusty's Mini Golf (substituem os do autor, sem credito de origem). Sintese propria, deterministica (PRNG com semente fixa), dedicada ao dominio publico (CC0). Escreve WAV estereo de 16 bits a 44,1 kHz e, se passado um codificador, converte em .ogg com o wav2ogg do projeto (Builds/pygame-music/wav2ogg.c, Ogg Vorbis com numero de serie fixo: mesma entrada, mesmos bytes). python3 -I sounds.py [caminho-do-wav2ogg] """ 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(' pasta dentro do projeto do jogo (Src/) DEST = {'BallHit': 'GameObjects/Ball', 'BallBounce': 'GameObjects/Ball', 'BallEnterHole': 'GameObjects/Ball', 'Splash': 'GameObjects/Ball', 'ClickSound': 'UI/Sounds', 'StarPop': 'UI/Sounds', 'Win1Star': 'UI/Sounds', 'Win2Stars': 'UI/Sounds', 'Win3Stars': 'UI/Sounds'} if __name__ == '__main__': out = sys.argv[1] enc = sys.argv[2] if len(sys.argv) > 2 else None for name, mono in make_all().items(): d = os.path.join(out, DEST[name]) os.makedirs(d, exist_ok=True) wav = os.path.join(d, name + '.wav') finish(mono, wav) if enc: subprocess.run([enc, wav, os.path.join(d, name + '.ogg'), '0.4'], check=True) os.remove(wav)