Created
November 6, 2019 22:34
-
-
Save phooky/92c9b1501d0ef68c4836c5436c8c0e20 to your computer and use it in GitHub Desktop.
terrible fm synthesis, it's just awful
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import wave | |
import sys | |
import struct | |
import math | |
outpath=sys.argv[0].rsplit('.',1)[0]+".wav" | |
print("Writing to {}".format(outpath)) | |
samp_rate = 44100. | |
w = wave.open(outpath,'wb') | |
w.setframerate(samp_rate) | |
w.setsampwidth(2) | |
w.setnchannels(2) | |
SCALE=2**14 | |
TIMESTEP=1./samp_rate | |
def wf_saw(phi): | |
mphi = phi % (2*math.pi) | |
return -1. + (mphi / math.pi) | |
def wf_tri(phi): | |
mphi = phi % (2*math.pi) | |
if mphi < math.pi: | |
return -1. + 2*(mphi / math.pi) | |
else: | |
return -1. + 2*((2*math.pi-mphi) / math.pi) | |
def ramp(v1,v2,t1,t2): | |
delta = (v2-v1) / ((t2-t1)/TIMESTEP) | |
while t1 > 0.: | |
yield v1 | |
t1 -= TIMESTEP | |
t2 -= TIMESTEP | |
while t2 > 0.: | |
v1 += delta | |
yield v1 | |
t2 -= TIMESTEP | |
while True: | |
yield v2 | |
def osc(freq,phi=0.,wf=math.sin): | |
delta = TIMESTEP*2*math.pi*freq | |
while True: | |
yield wf(phi) | |
phi += delta | |
def vosc(vfreq,phi=0.,wf=math.sin): | |
while True: | |
yield wf(phi) | |
phi += TIMESTEP*2*math.pi*next(vfreq) | |
def switch(f1,f2,time): | |
while time > 0.: | |
yield next(f1) | |
time -= TIMESTEP | |
while True: | |
yield next(f2) | |
def alternate(f1,f2,t1,t2): | |
while True: | |
time = t1 | |
while time > 0.: | |
yield next(f1) | |
time -= TIMESTEP | |
time = t2 | |
while time > 0.: | |
yield next(f2) | |
time -= TIMESTEP | |
def generate(l,r,duration): | |
time = 0. | |
while time < duration: | |
yield (next(l),next(r)) | |
time += TIMESTEP | |
dat = bytearray() | |
l = alternate(osc(500),osc(500,wf=wf_tri),.5,.5) | |
r = vosc(ramp(60,200,1,3)) | |
for (left,right) in generate(l,r,5): | |
dat.extend(struct.pack('hh',int(left*SCALE),int(right*SCALE))) | |
w.writeframes(dat) | |
w.close() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment