#!/usr/bin/env python3 """Gera os nove efeitos sonoros do Monk Tower para o fredygames.com. Os .wav do repositorio (maciekglowka/tower-rl) nao tem autoria declarada; este script os substitui por sons sinteticos (ondas quadrada, triangular e seno, envelopes e ruido com semente fixa), mesmos nomes de arquivo, 44,1 kHz, 16 bits, mono. Dedicado ao dominio publico (CC0 1.0) por FredyGames. Saida identica a cada execucao. Uso: python3 -I gen-sfx.py """ import math import random import struct import sys import wave RATE = 44100 def tone(freq_fn, dur, shape="square", vol=0.5, attack=0.004, release=0.05, vibrato=(0, 0)): """freq_fn(t) devolve a frequencia (Hz) no instante t; envelope com ataque e queda lineares.""" n = int(dur * RATE) out = [] phase = 0.0 for i in range(n): t = i / RATE f = freq_fn(t) if vibrato[0]: f *= 1 + vibrato[1] * math.sin(2 * math.pi * vibrato[0] * t) phase += f / RATE p = phase % 1.0 if shape == "square": s = 1.0 if p < 0.5 else -1.0 elif shape == "pulse": s = 1.0 if p < 0.25 else -1.0 elif shape == "tri": s = 4 * abs(p - 0.5) - 1 elif shape == "saw": s = 2 * p - 1 else: s = math.sin(2 * math.pi * p) env = min(1.0, t / attack) * min(1.0, (dur - t) / release) out.append(s * env * vol) return out def noise(dur, vol=0.5, seed=1, lowpass=0.0, decay=6.0): rng = random.Random(seed) n = int(dur * RATE) out = [] y = 0.0 for i in range(n): x = rng.uniform(-1, 1) y = y + (x - y) * (1 - lowpass) if lowpass else x out.append(y * vol * math.exp(-decay * i / n)) return out def mix(*tracks): n = max(len(t) for t in tracks) out = [0.0] * n for t in tracks: for i, v in enumerate(t): out[i] += v return out def seq(*parts, gap=0.0): out = [] for p in parts: out += p + [0.0] * int(gap * RATE) return out def at(track, offset): return [0.0] * int(offset * RATE) + track def note(n): # semitons a partir do la 440 (n=0) return 440.0 * 2 ** (n / 12) def sweep(a, b, dur): return lambda t: a * (b / a) ** (t / dur) def write(path, samples): peak = max(1e-9, max(abs(s) for s in samples)) scale = min(1.0, 0.9 / peak) with wave.open(path, "wb") as w: w.setnchannels(1) w.setsampwidth(2) w.setframerate(RATE) w.writeframes(b"".join(struct.pack("