dsp/lib/nsf.py

93 lines
2.2 KiB
Python
Raw Normal View History

2015-10-28 04:04:31 -07:00
# network synthesis filters
2015-10-18 23:06:39 -07:00
import numpy as np
2017-09-21 04:04:22 -07:00
2015-10-18 23:06:39 -07:00
def LPB(n):
2017-09-21 04:04:22 -07:00
# via:
# https://github.com/vinniefalco/DSPFilters/blob/master/shared/DSPFilters/source
2016-06-01 04:04:46 -07:00
"""n-th order butterworth low-pass filter cascade
2015-10-18 23:06:39 -07:00
-3 dB at center frequency."""
series = []
pi2 = np.pi/2
pairs = int(n/2)
for i in range(pairs):
# magnitude = 1
theta = pi2*(1 + (2*i + 1)/n)
real = np.cos(theta)
imag = np.sin(theta)
num = (0, 0, 1)
den = (1, -2*real, real*real + imag*imag)
series += [(num, den)]
if n % 2:
num = (0, 1)
den = (1, 1)
series += [(num, den)]
return series
2017-09-21 04:04:22 -07:00
2015-10-18 23:06:39 -07:00
def LPC(n, ripple, type=1):
2017-09-21 04:04:22 -07:00
# via:
# https://github.com/vinniefalco/DSPFilters/blob/master/shared/DSPFilters/source
2015-10-18 23:06:39 -07:00
# FIXME: type 2 has wrong center frequency?
2016-06-01 04:04:46 -07:00
"""n-th order chebyshev low-pass filter cascade
2015-10-18 23:06:39 -07:00
0 dB at center frequency for type 1.
-ripple dB at center frequency for type 2.
when ripple=0 and type=1, acts as butterworth."""
series = []
ripple = np.abs(ripple)
lin = np.exp(ripple*0.1*np.log(10))
if ripple != 0:
if type == 2:
eps = np.sqrt(1/(lin - 1))
else:
eps = np.sqrt(lin - 1)
v0 = np.arcsinh(1/eps)/n
else:
if type == 2:
2017-09-21 04:04:22 -07:00
v0 = 0 # allpass?
2015-10-18 23:06:39 -07:00
else:
2017-09-21 04:04:22 -07:00
v0 = 1 # butterworth
2015-10-18 23:06:39 -07:00
sinh_v0 = -np.sinh(v0)
cosh_v0 = np.cosh(v0)
fn = np.pi/(2*n)
pairs = int(n/2)
for i in range(pairs):
k = 2*i + 1
theta = (k - n)*fn
real = sinh_v0*np.cos(theta)
imag = cosh_v0*np.sin(theta)
if type == 2:
d2 = real*real + imag*imag
im = 1/np.cos(k*fn)
real = real/d2
imag = imag/d2
num = (1, 0, im*im)
else:
num = (0, 0, 1)
den = (1, -2*real, real*real + imag*imag)
# normalize such that 0 Hz is 0 dB
den = np.array(den)
gain = den[2]/num[2]
den /= gain
series += [(num, den)]
if n % 2:
real = sinh_v0
if type == 2:
real = 1/real
num = (0, 1)
den = (1/-real, 1)
series += [(num, den)]
return series