2015-10-18 23:33:46 -07:00
|
|
|
from . import xsp, lament
|
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 smoothfft(xs, ys, bw=1, precision=512):
|
|
|
|
"""performs log-lin smoothing on magnitude data,
|
|
|
|
generally from the output of averfft."""
|
2015-10-18 23:33:46 -07:00
|
|
|
lament("smoothfft(): DEPRECATED; use smoothfft2 instead.")
|
2015-10-18 23:06:39 -07:00
|
|
|
xs2 = xsp(precision)
|
|
|
|
ys2 = np.zeros(precision)
|
|
|
|
log_xs = np.log(xs)
|
|
|
|
for i, x in enumerate(xs2):
|
|
|
|
dist = np.exp(np.abs(log_xs - np.log(x + 1e-35)))
|
|
|
|
window = np.maximum(0, 1 - (dist - bw))
|
2015-10-18 23:33:46 -07:00
|
|
|
# at this point we could probably
|
2015-10-18 23:06:39 -07:00
|
|
|
# normalize our *triangular* window to 0-1
|
|
|
|
# and transform it into *another* windowing function
|
|
|
|
wsum = np.sum(window)
|
|
|
|
ys2[i] = np.sum(ys*window/wsum)
|
|
|
|
return xs2, ys2
|
|
|
|
|
2017-09-21 04:04:22 -07:00
|
|
|
|
2015-10-18 23:06:39 -07:00
|
|
|
def smoothfft2(xs, ys, bw=1, precision=512, compensate=True):
|
|
|
|
"""performs log-lin smoothing on magnitude data,
|
|
|
|
generally from the output of averfft."""
|
2015-10-30 04:04:36 -07:00
|
|
|
# this is probably implementable with FFTs now that i think about it
|
2015-10-18 23:06:39 -07:00
|
|
|
xs2 = xsp(precision)
|
|
|
|
ys2 = np.zeros(precision)
|
|
|
|
log2_xs2 = np.log2(xs2)
|
|
|
|
for i, x in enumerate(xs):
|
2015-10-18 23:33:46 -07:00
|
|
|
# before optimizations: dist = np.abs(np.log2(xs2/(x + 1e-35)))/bw
|
2015-10-18 23:06:39 -07:00
|
|
|
dist = np.abs(log2_xs2 - np.log2(x + 1e-35))/bw
|
2018-02-20 04:04:25 -08:00
|
|
|
# window = np.maximum(0, 1 - dist) # triangular
|
|
|
|
window = np.exp(-dist**2/(0.5/2)) # gaussian (untruncated)
|
2015-10-18 23:06:39 -07:00
|
|
|
ys2 += ys[i]*window
|
|
|
|
if compensate:
|
2017-09-21 04:04:22 -07:00
|
|
|
_, temp = smoothfft2(xs, np.ones(len(xs)),
|
|
|
|
bw=bw, precision=precision, compensate=False)
|
2015-10-18 23:06:39 -07:00
|
|
|
ys2 /= temp
|
|
|
|
return xs2, ys2
|
2018-02-19 04:04:28 -08:00
|
|
|
|
|
|
|
|
|
|
|
def smoothfft3(ys, bw=1, precision=512):
|
|
|
|
"""performs log-lin smoothing on magnitude data"""
|
|
|
|
size = len(ys)
|
|
|
|
xs = np.arange(0, 1, 1/size)
|
|
|
|
|
2018-02-20 04:04:25 -08:00
|
|
|
xs2 = np.logspace(-np.log2(size), 0, precision, base=2)
|
2018-02-19 04:04:28 -08:00
|
|
|
ys2 = np.zeros(precision)
|
|
|
|
comp = np.zeros(precision)
|
|
|
|
|
|
|
|
log2_xs2 = np.log2(xs2)
|
|
|
|
for i, x in enumerate(xs):
|
|
|
|
dist = np.abs(log2_xs2 - np.log2(x + 1e-35)) / bw
|
2018-02-20 04:04:25 -08:00
|
|
|
window = np.exp(-dist**2 * 4) # gaussian (untruncated)
|
2018-02-19 04:04:28 -08:00
|
|
|
comp += window
|
|
|
|
ys2 += ys[i] * window
|
|
|
|
|
|
|
|
return xs2, ys2 / comp
|