71 lines
2.1 KiB
Python
71 lines
2.1 KiB
Python
|
## This file generates headers with lookup tables for various waveforms
|
||
|
## Add your own.
|
||
|
|
||
|
import math
|
||
|
|
||
|
## phase is in degrees: 360 is a full cycle, and this is probably what you want
|
||
|
|
||
|
def phaseSteps(maxPhase, length=256):
|
||
|
steps = range(0, length)
|
||
|
steps = [1.0*x/length * 2.0*math.pi * (maxPhase/360.0) for x in steps]
|
||
|
return steps
|
||
|
|
||
|
def sine(maxPhase=360, length=256):
|
||
|
wave = [math.sin(x) for x in phaseSteps(maxPhase, length)]
|
||
|
return scaleAndRound(wave)
|
||
|
|
||
|
def sawtooth(maxPhase=360, length=256):
|
||
|
wave = [x for x in range(length)]
|
||
|
return scaleAndRound(wave)
|
||
|
|
||
|
def square(maxPhase=360, length=256):
|
||
|
wave = [0]*(length//2)
|
||
|
wave.extend([1]*(length//2))
|
||
|
return scaleAndRound(wave)
|
||
|
|
||
|
def triangle(maxPhase=360, length=256):
|
||
|
wave = [x for x in range(length//2)]
|
||
|
wave.extend([length//2 - x for x in range(length//2)])
|
||
|
return scaleAndRound(wave)
|
||
|
|
||
|
def bandlimitedSawtooth(numberPartials, maxPhase=360, length=256):
|
||
|
wave = [0]*length
|
||
|
sign = 1.0
|
||
|
for k in range(1, numberPartials+1):
|
||
|
phases = phaseSteps(maxPhase*k, length)
|
||
|
for i in range(length):
|
||
|
wave[i] += sign * math.sin(phases[i]) / k
|
||
|
sign = sign * -1
|
||
|
return scaleAndRound(wave)
|
||
|
|
||
|
def bandlimitedSquare(numberPartials, maxPhase=360, length=256):
|
||
|
wave = [0]*length
|
||
|
for k in range(1, numberPartials*2, 2):
|
||
|
phases = phaseSteps(maxPhase*k, length)
|
||
|
for i in range(length):
|
||
|
wave[i] += math.sin(phases[i]) / k
|
||
|
return scaleAndRound(wave)
|
||
|
|
||
|
def bandlimitedTriangle(numberPartials, maxPhase=360, length=256):
|
||
|
wave = [0]*length
|
||
|
sign = 1.0
|
||
|
for k in range(1, numberPartials*2, 2):
|
||
|
phases = phaseSteps(maxPhase*k, length)
|
||
|
for i in range(length):
|
||
|
wave[i] += sign * math.sin(phases[i]) / k**2
|
||
|
sign = sign * -1
|
||
|
return scaleAndRound(wave)
|
||
|
|
||
|
def scaleAndRound(data, scale=2**16-1, signedInt=True):
|
||
|
data = [0.0+x-min(data) for x in data]
|
||
|
data = [1.0*x/max(data)*scale for x in data]
|
||
|
data = [int(round(x)) for x in data]
|
||
|
if signedInt:
|
||
|
data = [int(x-(scale+1)//2) for x in data]
|
||
|
return(data)
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
|
||
|
sawtooth_sample = sawtooth(7)
|