103 lines
2.5 KiB
Python
103 lines
2.5 KiB
Python
import numpy as np
|
|
|
|
|
|
def _deco_win(f):
|
|
# gives scipy compatibility
|
|
def deco(N, *args, sym=True, **kwargs):
|
|
if N < 1:
|
|
return np.array([])
|
|
if N == 1:
|
|
return np.ones(1)
|
|
odd = N % 2
|
|
if not sym and not odd:
|
|
N = N + 1
|
|
|
|
w = f(N, *args, **kwargs)
|
|
|
|
if not sym and not odd:
|
|
return w[:-1]
|
|
return w
|
|
return deco
|
|
|
|
|
|
def _gen_hamming(*a):
|
|
L = len(a)
|
|
a += (0, 0, 0, 0, 0) # pad so orders definition doesn't error
|
|
orders = [
|
|
lambda fac: 0,
|
|
lambda fac: a[0],
|
|
lambda fac: a[0] - a[1]*np.cos(1*fac),
|
|
lambda fac: a[0] - a[1]*np.cos(1*fac) + a[2]*np.cos(2*fac),
|
|
lambda fac: a[0] - a[1]*np.cos(1*fac) + a[2]*np.cos(2*fac)
|
|
- a[3]*np.cos(3*fac),
|
|
lambda fac: a[0] - a[1]*np.cos(1*fac) + a[2]*np.cos(2*fac)
|
|
- a[3]*np.cos(3*fac) + a[4]*np.cos(4*fac),
|
|
]
|
|
f = orders[L]
|
|
return lambda N: f(np.arange(0, N)*2*np.pi/(N - 1))
|
|
|
|
|
|
def _normalize(*args):
|
|
a = np.asfarray(args)
|
|
return a/np.sum(a)
|
|
|
|
|
|
def _h(*args):
|
|
return _deco_win(_gen_hamming(*args))
|
|
|
|
|
|
blackman_inexact = _h(0.42, 0.5, 0.08)
|
|
blackman = _h(0.42659, 0.49656, 0.076849)
|
|
blackman_nuttall = _h(0.3635819, 0.4891775, 0.1365995, 0.0106411)
|
|
blackman_harris = _h(0.35875, 0.48829, 0.14128, 0.01168)
|
|
nuttall = _h(0.355768, 0.487396, 0.144232, 0.012604)
|
|
flattop = _h(*_normalize(1, 1.93, 1.29, 0.388, 0.028)) # FTSRS
|
|
# flattop_weird = _h(*_normalize(1, 1.93, 1.29, 0.388, 0.032)) # ??? wtf
|
|
flattop_weird = _h(0.2156, 0.4160, 0.2781, 0.0836, 0.0069) # ??? scipy crap
|
|
hann = _h(0.5, 0.5)
|
|
hamming_inexact = _h(0.54, 0.46)
|
|
hamming = _h(0.53836, 0.46164)
|
|
|
|
|
|
@_deco_win
|
|
def triangular(N):
|
|
if N % 2 == 0:
|
|
return 1 - np.abs((2*np.arange(N) + 1)/N - 1)
|
|
else:
|
|
return 1 - np.abs(2*(np.arange(N) + 1)/(N + 1) - 1)
|
|
|
|
|
|
@_deco_win
|
|
def parzen(N):
|
|
odd = N % 2
|
|
n = np.arange(N/2)
|
|
if not odd:
|
|
n += 0.5
|
|
center = 1 - 6*(2*n/N)**2*(1 - 2*n/N)
|
|
outer = 2*(1 - 2*n/N)**3
|
|
center = center[:len(center)//2]
|
|
outer = outer[len(outer)//2:]
|
|
if not odd:
|
|
return np.r_[outer[::-1], center[::-1], center, outer]
|
|
else:
|
|
return np.r_[outer[::-1], center[::-1], center[1:], outer]
|
|
|
|
|
|
@_deco_win
|
|
def cosine(N):
|
|
return np.sin(np.pi*(np.arange(N) + 0.5)/N)
|
|
|
|
|
|
@_deco_win
|
|
def welch(N):
|
|
return 1 - (2*np.arange(N)/(N - 1) - 1)**2
|
|
|
|
|
|
# TODO: rename or something
|
|
@_deco_win
|
|
def sinc(N):
|
|
return np.sinc((np.arange(N) - (N - 1)/2)/2)
|
|
|
|
|
|
def winmod(f):
|
|
return lambda N: f(N + 2)[1:-1]
|