#!/usr/bin/env python3 """Generates the game's sound effects, from scratch. Forgejo #146 asked for free SFX sources, and the ones worth using are listed in that ticket - Kenney's CC0 packs, OpenGameArt's CC0 sets, Freesound filtered to CC0. What ships here is synthesised instead, for one reason: a generated sound has no licence, no attribution to keep track of, and no binary in the repository whose provenance nobody can check a year from now. It also means the sounds are DATA rather than assets. If a shot is too sharp or an explosion too short, the fix is a number in this file and a re-run, not a hunt through a sound library. #150 and #151 are why the first pass was thrown away. "Shot sounds sound like a toy" and "death sounds from ship are really cheap", and both were fair: the shot was a bare descending sine, which is the sound every toy ray gun has ever made, and the death was one band of filtered noise with a sine under it - thin, and gone before the eye had finished with the explosion. What the rewrite adds, and why each part is there: * LAYERS, not a waveform. A real bang is a crack, then a body, then a tail, and they have different lengths. One envelope over one source cannot be any of those things. * A sub. Below about 80Hz is where "big" lives; without it an explosion is a hiss however loud it is played. * SATURATION. Soft-clipping folds in harmonics and stops the peak normalisation below from turning everything into the same quiet mush. * Detuned partials on the shot, so it is a machine rather than a flute - the single sine was the whole of the toy problem. Run: python3 audio/make_sfx.py """ import math import random import struct import wave RATE = 44100 def _write(name, samples): peak = max(1e-9, max(abs(s) for s in samples)) frames = b"".join(struct.pack("