dsp/lib/util.py

71 lines
2.1 KiB
Python
Raw Normal View History

2015-10-18 23:06:39 -07:00
import sys
import numpy as np
import scipy.signal as sig
dummy = lambda *args, **kwargs: None
lament = lambda *args, **kwargs: print(*args, file=sys.stderr, **kwargs)
toLK = lambda x: -0.691 + 10*np.log10(x)
isqrt2 = 1/np.sqrt(2)
toQ = lambda bw: isqrt2/bw
toA = lambda db: 10**(db/40)
tau = 2*np.pi
unwarp = lambda w: np.tan(w/2)
warp = lambda w: np.arctan(w)*2
2015-10-27 04:04:29 -07:00
ceil2 = lambda x: np.power(2, np.ceil(np.log2(x)))
2015-11-10 04:04:41 -08:00
pad2 = lambda x: np.r_[x, np.zeros(ceil2(len(x)) - len(x))]
2015-10-27 04:04:29 -07:00
2015-10-18 23:06:39 -07:00
rfft = lambda src, size: np.fft.rfft(src, size*2)
magnitude = lambda src, size: 10*np.log10(np.abs(rfft(src, size))**2)[0:size]
2015-10-30 04:04:36 -07:00
# x axis for plotting above magnitude
magnitude_x = lambda srate, size: np.arange(0, srate/2, srate/2/size)
2015-10-18 23:06:39 -07:00
2015-10-19 05:39:37 -07:00
degrees_clamped = lambda x: ((x*180/np.pi + 180) % 360) - 180
2015-10-18 23:06:39 -07:00
def xsp(precision=4096):
"""create #precision log-spaced points from 20 to 20480 Hz"""
# i opt not to use steps or linspace here,
# as the current method is less error-prone for me.
xs = np.arange(0,precision)/precision
return 20*1024**xs
def blocks(a, step, size=None):
"""break an iterable into chunks"""
if size is None:
size = step
for start in range(0, len(a), step):
end = start + size
if end > len(a):
break
yield a[start:end]
2015-10-30 04:04:36 -07:00
def convolve_each(s, fir, mode='same', axis=0):
2015-10-18 23:06:39 -07:00
return np.apply_along_axis(lambda s: sig.fftconvolve(s, fir, mode), axis, s)
def count_channels(s):
if len(s.shape) < 2:
return 1
return s.shape[1]
def monoize(s):
"""mixes an n-channel signal down to one channel.
technically, it averages a 2D array to be 1D.
existing mono signals are passed through unmodified."""
channels = count_channels(s)
if channels != 1:
s = np.sum(s, 1)
s /= channels
return s
2016-11-03 04:04:22 -07:00
def div0(a, b):
"""division, whereby division by zero equals zero"""
# http://stackoverflow.com/a/35696047
a = np.asanyarray(a)
b = np.asanyarray(b)
with np.errstate(divide='ignore', invalid='ignore'):
c = np.true_divide(a, b)
c[~np.isfinite(c)] = 0 # -inf inf NaN
return c