import math
import struct
import sys
import wave
SR = 44100
DURATION = 1.6
PARTIALS = [
(1.00, 1.6, 0.55),
(2.00, 2.7, 0.20),
(3.01, 4.0, 0.10),
(4.50, 5.5, 0.05),
]
FUNDAMENTAL = 1046.5
def synth(t):
s = 0.0
for ratio, decay, amp in PARTIALS:
s += amp * math.exp(-t * decay) * math.sin(2 * math.pi * FUNDAMENTAL * ratio * t)
attack = min(1.0, t / 0.004)
return s * attack
def main(path):
with wave.open(path, "wb") as w:
w.setnchannels(1)
w.setsampwidth(2)
w.setframerate(SR)
n = int(SR * DURATION)
frames = bytearray()
for i in range(n):
v = synth(i / SR)
v = max(-0.95, min(0.95, v))
frames += struct.pack("<h", int(v * 32767))
w.writeframes(bytes(frames))
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"usage: {sys.argv[0]} <out.wav>", file=sys.stderr)
sys.exit(1)
main(sys.argv[1])