update 10
This commit is contained in:
parent
9c5825a4b1
commit
034d8632f5
4 changed files with 67 additions and 131 deletions
|
@ -1,7 +1,3 @@
|
|||
import numpy as np
|
||||
#from IPython.display import display
|
||||
from matplotlib.pylab import show
|
||||
|
||||
from .util import *
|
||||
from .bq import *
|
||||
from .data import *
|
||||
|
@ -14,6 +10,9 @@ from .planes import *
|
|||
from .fft import *
|
||||
from .bs import *
|
||||
|
||||
import numpy as np
|
||||
from matplotlib.pylab import show
|
||||
|
||||
def analog(b, a):
|
||||
import sympy as sym
|
||||
w,s = sym.symbols('w s')
|
||||
|
@ -35,27 +34,18 @@ def test_filter_raw(ba, fc=1000, gain=0, precision=4096):
|
|||
fig, ax = new_response(ymin=-24, ymax=24)
|
||||
xs = xsp(precision)
|
||||
ax.semilogx(xs, makemag(fc, ba, gain)(xs))
|
||||
show(fig)
|
||||
|
||||
def test_filter(ff, A=toA(12), Q=toQ(1), **kwargs):
|
||||
test_filter_raw(ff(A, Q), **kwargs)
|
||||
|
||||
npc = [makemag(*f) for f in cascades['raw']]
|
||||
def neonpink(xs):
|
||||
lament("neonpink(): DEPRECATED; use tilter2(xs, 'raw') instead.")
|
||||
combined = np.zeros(len(xs))
|
||||
for f in npc:
|
||||
combined += f(xs)
|
||||
return combined
|
||||
return tilter2(xs, 'raw')
|
||||
|
||||
def c_render(cascade, precision=4096):
|
||||
# TODO: deprecate in favor of tilter2 (which also needs to be renamed)
|
||||
xs = xsp(precision)
|
||||
ys = np.zeros_like(xs)
|
||||
c = [makemag(*f) for f in cascade]
|
||||
for f in c:
|
||||
ys += f(xs)
|
||||
return xs, ys
|
||||
return xs, tilter2(xs, cascade)
|
||||
|
||||
def c_render2(xs, cascade, phase=False):
|
||||
"""c_render optimized and specifically for first/second-order filters"""
|
||||
|
@ -87,10 +77,10 @@ def c_render2(xs, cascade, phase=False):
|
|||
ys = degrees_clamped(ys)
|
||||
return ys
|
||||
|
||||
def firize(xs, ys, n=4096, srate=44100, plot=None):
|
||||
def firize(xs, ys, n=4096, srate=44100, ax=None):
|
||||
import scipy.signal as sig
|
||||
if plot:
|
||||
plot.semilogx(xs, ys, label='desired')
|
||||
if ax:
|
||||
ax.semilogx(xs, ys, label='desired')
|
||||
xf = xs/srate*2
|
||||
yg = 10**(ys/20)
|
||||
|
||||
|
@ -99,40 +89,29 @@ def firize(xs, ys, n=4096, srate=44100, plot=None):
|
|||
|
||||
b = sig.firwin2(n, xf, yg, antisymmetric=True)
|
||||
|
||||
if plot:
|
||||
if ax:
|
||||
_, ys = sig.freqz(b, worN=xs/srate*tau)
|
||||
ys = 20*np.log10(np.abs(ys))
|
||||
plot.semilogx(xs, ys, label='FIR ({} taps)'.format(n))
|
||||
plot.legend(loc=8)
|
||||
ax.semilogx(xs, ys, label='FIR ({} taps)'.format(n))
|
||||
ax.legend(loc=8)
|
||||
|
||||
return b
|
||||
|
||||
def tilter(xs, ys, tilt):
|
||||
"""tilts a magnitude plot by some decibels, or by equalizer curve."""
|
||||
lament("tilter(): DEPRECATED; use ys -= tilter2(xs, tilt) instead.")
|
||||
if tilt == 'neon':
|
||||
noise = neonpink(xs)
|
||||
elif type(tilt) is str:
|
||||
noise = np.zeros(len(xs))
|
||||
c = [makemag(*f) for f in cascades[tilt]]
|
||||
for f in c:
|
||||
noise += f(xs)
|
||||
elif isinstance(tilt, int) or isinstance(tilt, float):
|
||||
noise = tilt*(np.log2(1000) - np.log2(xs))
|
||||
else:
|
||||
noise = np.zeros(xs.shape)
|
||||
return xs, ys - noise
|
||||
return xs, ys - tilter2(xs, tilt)
|
||||
|
||||
def tilter2(xs, tilt):
|
||||
if type(tilt) is str:
|
||||
noise = np.zeros(len(xs))
|
||||
c = [makemag(*f) for f in cascades[tilt]]
|
||||
noise = np.zeros(xs.shape)
|
||||
if isinstance(tilt, str) and tilt in cascades:
|
||||
tilt = cascades[tilt]
|
||||
if isinstance(tilt, list):
|
||||
c = [makemag(*f) for f in tilt]
|
||||
for f in c:
|
||||
noise += f(xs)
|
||||
elif isinstance(tilt, int) or isinstance(tilt, float):
|
||||
noise = tilt*(np.log2(1000) - np.log2(xs + 1e-35))
|
||||
else:
|
||||
noise = np.zeros(xs.shape)
|
||||
return noise
|
||||
|
||||
from .plotwav import *
|
||||
|
|
|
@ -2,6 +2,7 @@ import numpy as np
|
|||
import scipy.signal as sig
|
||||
|
||||
from .util import *
|
||||
from .planes import s2z
|
||||
|
||||
bq_run = lambda bq, xs: sig.lfilter(*bq, x=xs, axis=0)
|
||||
|
||||
|
|
|
@ -55,7 +55,6 @@ def BS_plot(ys, g10=None, g70=None, threshold=None, fig=None, ax=None):
|
|||
ax.xlabel('loudness (LKFS)')
|
||||
ax.ylabel('probability')
|
||||
fig.set_size_inches(10,4)
|
||||
show()
|
||||
|
||||
xs = np.arange(len(ys))
|
||||
#ax.plot(xs, ys, color='#066ACF', linestyle=':', marker='d', markersize=2)
|
||||
|
|
141
lib/plotwav.py
141
lib/plotwav.py
|
@ -1,45 +1,11 @@
|
|||
# this is a bunch of crap that should really be reduced to one or two functions
|
||||
|
||||
from . import wav_read, normalize, averfft, tilter2, smoothfft2, firize
|
||||
from . import new_response, show, convolve_each, monoize, count_channels
|
||||
from . import new_response, convolve_each, monoize, count_channels
|
||||
|
||||
import numpy as np
|
||||
|
||||
def plotwavsmooth(fn, ax, tilt=None, bw=1, size=8192, raw=False, fix=False, smoother=smoothfft2, **kwargs):
|
||||
s, srate = wav_read(fn)
|
||||
|
||||
s, rms = normalize(s, srate)
|
||||
sm = monoize(s)
|
||||
ss = monoize(s*np.array((1, -1)))
|
||||
|
||||
xs_raw = np.arange(0, srate/2, srate/2/size)
|
||||
ys_raw = averfft(sm, size=size)
|
||||
|
||||
# tilting beforehand is negligible besides lowest frequencies, but eh
|
||||
if tilt is not None:
|
||||
ys_raw -= tilter2(xs_raw, tilt)
|
||||
|
||||
xs, ys = smoother(xs_raw, ys_raw, bw=bw)
|
||||
|
||||
if not 'label' in kwargs:
|
||||
kwargs['label'] = fn
|
||||
|
||||
if raw:
|
||||
ax.semilogx(xs_raw, ys_raw, **kwargs)
|
||||
ax.semilogx(xs, ys, **kwargs)
|
||||
|
||||
if not fix: return
|
||||
|
||||
fno = fn[:-4]+"-proc.wav"
|
||||
fir = firize(xs, -ys, srate=srate)
|
||||
sf = convolve_each(s/8, fir, mode='same')
|
||||
|
||||
import ewave
|
||||
with ewave.open(fno, 'w', sampling_rate=srate, nchannels=count_channels(sf)) as f:
|
||||
f.write(sf)
|
||||
print('wrote '+fno)
|
||||
|
||||
def plotfftsmooth(s, srate, ax, bw=1, tilt=None, size=8192, window=0, raw=False, **kwargs):
|
||||
def plotfftsmooth(s, srate, ax=None, bw=1, tilt=None, size=8192, window=0, raw=False, **kwargs):
|
||||
sm = monoize(s)
|
||||
|
||||
xs_raw = np.arange(0, srate/2, srate/2/size)
|
||||
|
@ -49,78 +15,69 @@ def plotfftsmooth(s, srate, ax, bw=1, tilt=None, size=8192, window=0, raw=False,
|
|||
|
||||
xs, ys = smoothfft(xs_raw, ys_raw, bw=bw)
|
||||
|
||||
if raw: ax.semilogx(xs_raw, ys_raw, **kwargs)
|
||||
ax.semilogx(xs, ys, **kwargs)
|
||||
if ax:
|
||||
if raw: ax.semilogx(xs_raw, ys_raw, **kwargs)
|
||||
ax.semilogx(xs, ys, **kwargs)
|
||||
|
||||
return xs, ys
|
||||
|
||||
def plotwav2(fn, ax, bw=1, size=8192, raw=False, fix=False,
|
||||
smoother=smoothfft2, side_compensate=9, **kwargs):
|
||||
def plotwavinternal(sm, ss, srate, bw=1, size=8192, smoother=smoothfft2):
|
||||
xs_raw = np.arange(0, srate/2, srate/2/size)
|
||||
ys_raw_m = averfft(sm, size=size)
|
||||
ys_raw_s = averfft(ss, size=size)
|
||||
|
||||
# tilting beforehand is negligible besides lowest frequencies, but eh
|
||||
ys_raw_m -= tilter2(xs_raw, 'np2')
|
||||
ys_raw_s -= tilter2(xs_raw, 'np2s')
|
||||
|
||||
if bw <= 0:
|
||||
return xs_raw, xs_raw_m, xs_raw_s
|
||||
|
||||
xs, ys_m = smoother(xs_raw, ys_raw_m, bw=bw)
|
||||
xs, ys_s = smoother(xs_raw, ys_raw_s, bw=bw)
|
||||
|
||||
return xs, ys_m, ys_s
|
||||
|
||||
def plotwav2(fn, bw=1, size=8192, fix=False,
|
||||
smoother=smoothfft2, **kwargs):
|
||||
s, srate = wav_read(fn)
|
||||
|
||||
s, rms = normalize(s, srate)
|
||||
sm = monoize(s)
|
||||
ss = monoize(s*np.array((1, -1)))
|
||||
if s.shape[1] == 2:
|
||||
ss = monoize(s*np.array((1, -1)))
|
||||
else:
|
||||
ss = np.zeros(len(s))
|
||||
|
||||
xs_raw = np.arange(0, srate/2, srate/2/size)
|
||||
ys_raw = averfft(sm, size=size)
|
||||
ys_raw_side = averfft(ss, size=size)
|
||||
xs, ys_m, ys_s = plotwavinternal(sm, ss, srate, bw, size, smoother)
|
||||
|
||||
# tilting beforehand is negligible besides lowest frequencies, but eh
|
||||
ys_raw -= tilter2(xs_raw, 'np2')
|
||||
ys_raw_side -= tilter2(xs_raw, 'np2s')
|
||||
side_gain = np.average(ys_s) - np.average(ys_m)
|
||||
|
||||
xs, ys = smoother(xs_raw, ys_raw, bw=bw)
|
||||
xs, ys_side = smoother(xs_raw, ys_raw_side, bw=bw)
|
||||
if fix:
|
||||
fno = fn[:-4]+"-proc.wav"
|
||||
|
||||
if not 'label' in kwargs:
|
||||
kwargs['label'] = fn
|
||||
fir_m = firize(xs, -ys_m, srate=srate)
|
||||
fir_s = firize(xs, -ys_s, srate=srate)
|
||||
smf = convolve_each(sm/8, fir_m, mode='same')
|
||||
ssf = convolve_each(ss/8, fir_s, mode='same')
|
||||
ssf *= 10**(side_gain/20)
|
||||
sf = np.array((smf + ssf, smf - ssf)).T
|
||||
|
||||
if raw:
|
||||
ax.semilogx(xs_raw, ys_raw, **kwargs)
|
||||
ax.semilogx(xs_raw, ys_raw_side + side_compensate, **kwargs)
|
||||
ax.semilogx(xs, ys, **kwargs)
|
||||
ax.semilogx(xs, ys_side + side_compensate, **kwargs)
|
||||
import ewave
|
||||
with ewave.open(fno, 'w', sampling_rate=srate, nchannels=count_channels(sf)) as f:
|
||||
f.write(sf)
|
||||
print('wrote '+fno)
|
||||
|
||||
side_gain = np.average(ys_raw_side) - np.average(ys_raw)
|
||||
print("side gain:", side_gain)
|
||||
return xs, ys_m, ys_s
|
||||
|
||||
if not fix: return
|
||||
def pw2(fn, label=None, bw=1/6, **kwargs):
|
||||
fno = fn[:-4]+"-proc.wav"
|
||||
xs, ys_m, ys_s = plotwav2(fn, fix=True, bw=bw, **kwargs)
|
||||
xs, ys_m, ys_s = plotwav2(fno, fix=False, bw=bw, **kwargs)
|
||||
|
||||
fir = firize(xs, -ys, srate=srate)
|
||||
smf = convolve_each(sm/8, fir, mode='same')
|
||||
fir = firize(xs, -ys_side, srate=srate)
|
||||
ssf = convolve_each(ss/8, fir, mode='same')
|
||||
ssf *= 10**(side_gain/20)
|
||||
sf = np.array((smf + ssf, smf - ssf)).T
|
||||
|
||||
import ewave
|
||||
with ewave.open(fno, 'w', sampling_rate=srate, nchannels=count_channels(sf)) as f:
|
||||
f.write(sf)
|
||||
print('wrote '+fno)
|
||||
|
||||
def pw(fn, ax, **kwargs):
|
||||
plotwavsmooth(fn, ax, tilt='np2', bw=1/6, **kwargs)
|
||||
|
||||
def pwc(fn, **kwargs):
|
||||
fig, ax = new_response(-18, 18)
|
||||
ax.set_title('averaged magnitudes of normalized songs with tilt and smoothing')
|
||||
|
||||
pw(fn, ax, fix=True, **kwargs)
|
||||
fno = fn[:-4]+"-proc.wav"
|
||||
pw(fno, ax, fix=False, **kwargs)
|
||||
|
||||
label = label or fn
|
||||
ax.semilogx(xs, ys_m + 0, label=label+' (mid)')
|
||||
ax.semilogx(xs, ys_s + 9, label=label+' (side)')
|
||||
ax.legend(loc=8)
|
||||
show(fig)
|
||||
|
||||
def pw2(fn, **kwargs):
|
||||
fig, ax = new_response(-18, 18)
|
||||
ax.set_title('averaged magnitudes of normalized songs with tilt and smoothing')
|
||||
|
||||
plotwav2(fn, ax, fix=True, bw=1/6, **kwargs)
|
||||
fno = fn[:-4]+"-proc.wav"
|
||||
plotwav2(fno, ax, fix=False, bw=1/6, **kwargs)
|
||||
|
||||
ax.legend(loc=8)
|
||||
show(fig)
|
||||
|
|
Loading…
Reference in a new issue