update 2
This commit is contained in:
parent
bf22e5a326
commit
4437abc01d
10 changed files with 21 additions and 42 deletions
|
@ -45,7 +45,7 @@ def test_filter(ff, A=toA(12), Q=toQ(1), **kwargs):
|
|||
|
||||
npc = [makemag(*f) for f in cascades['raw']]
|
||||
def neonpink(xs):
|
||||
print("neonpink(): DEPRECATED")
|
||||
lament("neonpink(): DEPRECATED.")
|
||||
combined = np.zeros(len(xs))
|
||||
for f in npc:
|
||||
combined += f(xs)
|
||||
|
|
|
@ -12,6 +12,7 @@ HP1 = lambda A, Q: ((1,0),(1,1))
|
|||
LS1 = lambda A, Q: ((1,A),(1,1/A))
|
||||
HS1 = lambda A, Q: ((A,1),(1/A,1))
|
||||
|
||||
# patterns observed, in case some simplification could be done:
|
||||
# a always gets divided by A instead of multiplied
|
||||
# b1 and a1 always /= Q
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import numpy as np
|
||||
|
||||
def LPB(n):
|
||||
# crap ripped from https://github.com/vinniefalco/DSPFilters/blob/master/shared/DSPFilters/source
|
||||
# via https://github.com/vinniefalco/DSPFilters/blob/master/shared/DSPFilters/source
|
||||
"""n-th degree butterworth low-pass filter cascade
|
||||
|
||||
-3 dB at center frequency."""
|
||||
|
@ -23,7 +23,7 @@ def LPB(n):
|
|||
return series
|
||||
|
||||
def LPC(n, ripple, type=1):
|
||||
# crap ripped from https://github.com/vinniefalco/DSPFilters/blob/master/shared/DSPFilters/source
|
||||
# via https://github.com/vinniefalco/DSPFilters/blob/master/shared/DSPFilters/source
|
||||
# FIXME: type 2 has wrong center frequency?
|
||||
"""n-th degree chebyshev low-pass filter cascade
|
||||
|
||||
|
@ -84,4 +84,3 @@ def LPC(n, ripple, type=1):
|
|||
den = (1/-real, 1)
|
||||
series += [(num, den)]
|
||||
return series
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ from .bq import *
|
|||
|
||||
import numpy as np
|
||||
|
||||
# as calculated by LPB in butterworth.py
|
||||
_bq2a = 1/.76536686473017945
|
||||
_bq2b = 1/1.8477590650225735
|
||||
_bq2a_bw = isqrt2/_bq2a
|
||||
|
@ -17,6 +18,7 @@ cascades = {
|
|||
'raw': [
|
||||
nf(LP1, 20, 0, 1, 29),
|
||||
nf(HS1, 800, 12, 1, 0),
|
||||
# i don't use the exact _bq2 coeffecients here for legacy reasons
|
||||
( 45, HP2( 0, 1.32), 0.5), # roughly estimates
|
||||
( 45, HP2( 0, 0.54), 0.5), # a 4-pole butterworth highpass
|
||||
nf(LP2, 14000, 0, 1.33, 0),
|
||||
|
@ -41,7 +43,7 @@ cascades = {
|
|||
],
|
||||
# here's the ideas written out:
|
||||
# low (<40) freqs dont contribute much to ears (feel doesnt count.)
|
||||
# high (>14000) freqs are mostly unheard. 14000 is the top for someone with bad hearing.
|
||||
# high (>14000) freqs are mostly unheard.
|
||||
# 750 Hz isn't too painful to the ears, but cutting them would give
|
||||
# overly-produced songs not enough gain to hear vocals, so keep it flat.
|
||||
# we're supposedly less sensitive to 1400 Hz, but i need to
|
||||
|
@ -60,7 +62,7 @@ cascades = {
|
|||
( 40, HP2(0, toQ(1.00)), 0.0),
|
||||
(10000, LP1(0, 0), 0.0),
|
||||
],
|
||||
# tested against your 227 top-rated songs
|
||||
# average curve of my 227 favorite songs
|
||||
'np2': [
|
||||
nf(LP1, 20, 0, 1, 32),
|
||||
nf(HS1, 800, 9, 1, -4.5),
|
||||
|
@ -70,7 +72,7 @@ cascades = {
|
|||
nf(LS2, 38, -9, 1.00, 0),
|
||||
nf(PE2, 64, 4.5, 1.20, 0),
|
||||
],
|
||||
# side channel
|
||||
# same but for the side channel
|
||||
'np2s': [
|
||||
nf(LP1, 20, 0, 1, 32),
|
||||
nf(HS1, 800, 9, 1, -4.5),
|
||||
|
|
|
@ -30,11 +30,11 @@ def magnitudes(s, size=8192):
|
|||
for i in range(0, L - 1, int(step)):
|
||||
windowed = s[i:i+win_size]*win
|
||||
power = np.abs(rfft(windowed, size))**2
|
||||
# this scraps the nyquist value to get exactly size outputs
|
||||
# this scraps the nyquist value to get exactly 'size' outputs
|
||||
yield power[0:size]
|
||||
count += 1
|
||||
|
||||
#assert(segs == count)
|
||||
#assert(segs == count) # this is probably no good in a generator
|
||||
|
||||
def averfft(s, size=8192):
|
||||
"""calculates frequency magnitudes by fft and averages them together."""
|
||||
|
|
|
@ -5,6 +5,8 @@ import sympy as sym
|
|||
|
||||
def zcgen_py(n, d):
|
||||
zcs = np.zeros(d + 1)
|
||||
|
||||
# expanded from the equation in zcgen_sym
|
||||
zcs[0] = 1
|
||||
for _ in range(n):
|
||||
for i in range(d, 0, -1):
|
||||
|
|
|
@ -4,7 +4,6 @@ from matplotlib import ticker
|
|||
def response_setup(ax, ymin=-24, ymax=24, yL=ticker.AutoMinorLocator(3)):
|
||||
ax.set_xlim(20, 20000)
|
||||
ax.set_ylim(ymin, ymax)
|
||||
#ax.set_yticks(np.arange(ymin, ymax + 1, 6))
|
||||
ax.set_yticks(tuple(range(ymin, ymax + 1, 6)))
|
||||
ax.yaxis.set_minor_locator(yL)
|
||||
ax.grid(True, 'both')
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
from . import xsp
|
||||
from . import xsp, lament
|
||||
import numpy as np
|
||||
|
||||
def smoothfft(xs, ys, bw=1, precision=512):
|
||||
"""performs log-lin smoothing on magnitude data,
|
||||
generally from the output of averfft."""
|
||||
# TODO: option to extrapolate (pad) fft data
|
||||
lament("smoothfft(): DEPRECATED; use smoothfft2 instead.")
|
||||
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))
|
||||
# at this point you could probably
|
||||
# at this point we could probably
|
||||
# normalize our *triangular* window to 0-1
|
||||
# and transform it into *another* windowing function
|
||||
wsum = np.sum(window)
|
||||
|
@ -25,7 +25,7 @@ def smoothfft2(xs, ys, bw=1, precision=512, compensate=True):
|
|||
ys2 = np.zeros(precision)
|
||||
log2_xs2 = np.log2(xs2)
|
||||
for i, x in enumerate(xs):
|
||||
#dist = np.abs(np.log2(xs2/(x + 1e-35)))/bw
|
||||
# before optimizations: dist = np.abs(np.log2(xs2/(x + 1e-35)))/bw
|
||||
dist = np.abs(log2_xs2 - np.log2(x + 1e-35))/bw
|
||||
#window = np.maximum(0, 1 - dist) # triangle window
|
||||
window = np.exp(-dist**2/(0.5/2)) # gaussian function (non-truncated)
|
||||
|
@ -34,27 +34,3 @@ def smoothfft2(xs, ys, bw=1, precision=512, compensate=True):
|
|||
_, temp = smoothfft2(xs, np.ones(len(xs)), bw=bw, precision=precision, compensate=False)
|
||||
ys2 /= temp
|
||||
return xs2, ys2
|
||||
|
||||
def smoothfft3(xs, ys, bw=1, precision=1024):
|
||||
# actually this will never work...
|
||||
# you need to go back to smoothfft2,
|
||||
# which technically works as-designed,
|
||||
# and fix the compensation to work with widely-spaced data.
|
||||
raise Exception("smoothfft3 is broken.")
|
||||
xs2 = xsp(precision)
|
||||
ys2 = np.zeros(precision)
|
||||
step = (xs[1] - xs[0])
|
||||
if True:
|
||||
for i, x in enumerate(xs):
|
||||
dist = np.abs(xs2 - x)
|
||||
bw2 = x*bw/2
|
||||
window = np.maximum(0, 1 - dist/bw2)
|
||||
#window = np.minimum(1, np.maximum(0, 1 - (dist - bw)))
|
||||
ys2 += ys[i]*window
|
||||
else:
|
||||
for i, x2 in enumerate(xs2):
|
||||
dist = np.abs(xs - x2)
|
||||
window = np.maximum(0, 1 - (dist/step/bw))
|
||||
wsum = np.sum(window)
|
||||
ys2[i] = np.sum(ys*window/wsum)
|
||||
return xs2, ys2
|
||||
|
|
|
@ -31,7 +31,7 @@ def tsp(N, m=0.5):
|
|||
# http://www.sound.sie.dendai.ac.jp/dsp/e-21.html
|
||||
|
||||
if m < 0 or m > 1:
|
||||
raise Exception("sdfgsdfgsdg")
|
||||
raise Exception("what are you doinggg")
|
||||
|
||||
if N < 0:
|
||||
raise Exception("The number of length must be the positive number")
|
||||
|
|
|
@ -6,7 +6,7 @@ import scipy.io.wavfile as wav
|
|||
import ewave
|
||||
|
||||
def wav_smart_read(fn):
|
||||
lament('DEPRECATED: wav_smart_read; use wav_read instead')
|
||||
lament('wav_smart_read(): DEPRECATED; use wav_read instead.')
|
||||
srate, s = wav.read(fn)
|
||||
if s.dtype != np.float64:
|
||||
bits = s.dtype.itemsize*8
|
||||
|
@ -14,7 +14,7 @@ def wav_smart_read(fn):
|
|||
return srate, s
|
||||
|
||||
def wav_smart_write(fn, srate, s):
|
||||
lament('DEPRECATED: wav_smart_write')
|
||||
lament('wav_smart_write(): DEPRECATED; use ewave instead.')
|
||||
si = np.zeros_like(s, dtype='int16')
|
||||
bits = si.dtype.itemsize*8
|
||||
si += np.clip(s*2**(bits - 1), -32768, 32767)
|
||||
|
|
Loading…
Reference in a new issue