Vectorscope/source/generate_wavetables.py

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)