2015-10-18 23:06:39 -07:00
|
|
|
from . import blocks, convolve_each, gen_filters, cascades, bq_run, toLK
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
2017-09-21 04:04:22 -07:00
|
|
|
|
2017-09-07 04:04:26 -07:00
|
|
|
def BS1770_3(s, srate, filters=None, window=0.4, overlap=0.75,
|
|
|
|
gate=10, absolute_gate=70, detail=False):
|
2015-10-18 23:06:39 -07:00
|
|
|
if filters is None:
|
|
|
|
filters = gen_filters(cascades['1770'], srate)
|
|
|
|
|
|
|
|
sf = np.copy(s)
|
|
|
|
for f in filters:
|
2017-09-21 04:04:22 -07:00
|
|
|
if len(f) is 2: # dumb way to tell what type we're given.
|
2015-10-18 23:06:39 -07:00
|
|
|
sf = bq_run(f, sf)
|
|
|
|
else:
|
|
|
|
sf = convolve_each(sf, f, 'same')
|
|
|
|
|
|
|
|
stepsize = round(window*srate*(1 - overlap))
|
|
|
|
blocksize = int(stepsize/(1 - overlap))
|
|
|
|
|
|
|
|
means = np.array([
|
|
|
|
np.sum(np.mean(b**2, axis=0)) for b in blocks(sf, stepsize, blocksize)
|
|
|
|
])
|
|
|
|
LKs = toLK(means)
|
|
|
|
|
2017-09-07 04:04:26 -07:00
|
|
|
gated = LKs > -absolute_gate
|
|
|
|
means_g70 = means[gated]
|
2015-10-18 23:06:39 -07:00
|
|
|
avg_g70 = np.average(means_g70)
|
|
|
|
threshold = toLK(avg_g70) - gate
|
2017-09-07 04:04:26 -07:00
|
|
|
means_g10 = means[gated | (LKs > threshold)]
|
2015-10-18 23:06:39 -07:00
|
|
|
avg_g10 = np.average(means_g10)
|
|
|
|
|
|
|
|
if detail is False:
|
|
|
|
return toLK(avg_g10)
|
|
|
|
else:
|
|
|
|
return toLK(avg_g10), toLK(avg_g70), LKs, threshold
|
|
|
|
|
2017-09-21 04:04:22 -07:00
|
|
|
|
2015-10-18 23:06:39 -07:00
|
|
|
def BS_plot(ys, g10=None, g70=None, threshold=None, fig=None, ax=None):
|
|
|
|
if g10:
|
|
|
|
center = np.round(g10)
|
|
|
|
bins = np.arange(center - 10, center + 10.01, 0.25)
|
|
|
|
else:
|
|
|
|
bins = np.arange(-70, 0.1, 1)
|
|
|
|
|
|
|
|
if fig is None:
|
|
|
|
fig = plt.figure()
|
|
|
|
if ax is None:
|
|
|
|
ax = fig.gca()
|
|
|
|
|
2017-09-21 04:04:22 -07:00
|
|
|
if False: # histogram
|
2015-10-18 23:06:39 -07:00
|
|
|
ax.hist(ys, bins=bins, normed=True, facecolor='g', alpha=0.5)
|
|
|
|
ax.xlim(bins[0], bins[-1])
|
|
|
|
ax.ylim(0, 1)
|
|
|
|
ax.grid(True, 'both')
|
|
|
|
ax.xlabel('loudness (LKFS)')
|
|
|
|
ax.ylabel('probability')
|
2017-09-21 04:04:22 -07:00
|
|
|
fig.set_size_inches(10, 4)
|
2015-10-18 23:06:39 -07:00
|
|
|
|
|
|
|
xs = np.arange(len(ys))
|
2017-09-21 04:04:22 -07:00
|
|
|
# ax.plot(xs, ys, color='#066ACF', linestyle=':', marker='d', markersize=2)
|
2015-10-18 23:06:39 -07:00
|
|
|
ax.plot(xs, ys, color='#1459E0')
|
|
|
|
ax.set_xlim(xs[0], xs[-1])
|
|
|
|
ax.set_ylim(-70, 0)
|
|
|
|
ax.grid(True, 'both', 'y')
|
|
|
|
ax.set_xlabel('bin')
|
|
|
|
ax.set_ylabel('loudness (LKFS)')
|
2017-09-21 04:04:22 -07:00
|
|
|
fig.set_size_inches(12, 5)
|
|
|
|
# _, _, ymin, _ = ax.axis()
|
2015-10-18 23:06:39 -07:00
|
|
|
if threshold:
|
|
|
|
ax.axhspan(-70, threshold, facecolor='r', alpha=1/5)
|
|
|
|
if g10:
|
|
|
|
ax.axhline(g10, color='g')
|
|
|
|
if g70:
|
|
|
|
ax.axhline(g70, color='0.3')
|
|
|
|
|
|
|
|
return fig, ax
|
|
|
|
|
2017-09-21 04:04:22 -07:00
|
|
|
|
2015-10-18 23:06:39 -07:00
|
|
|
def normalize(s, srate):
|
|
|
|
"""performs BS.1770-3 normalization and returns inverted gain."""
|
|
|
|
db = BS1770_3(s, srate)
|
|
|
|
rms = 10**(db/20)
|
|
|
|
return s/rms, rms
|