def hsll(wnd, res=20, neighbors=2): """ Highest Side Lobe Level (dB). Parameters ---------- res : Zero-padding factor. 1 for no zero-padding, 2 for twice the length, etc.. neighbors : Number of neighbors needed by ``get_peaks`` to define a peak. """ spectrum = dB20(rfft(wnd, res * len(wnd))) first_peak = next(get_peaks(spectrum, neighbors=neighbors)) return max(spectrum[first_peak:]) - spectrum[0]
def find_xdb_bin(wnd, power=.5, res=1500): """ A not so fast way to find the x-dB cutoff frequency "bin" index. Parameters ---------- wnd: The window itself as an iterable. power: The power value (squared amplitude) where the x-dB value should lie, using ``x = dB10(power)``. res : Zero-padding factor. 1 for no zero-padding, 2 for twice the length, etc.. """ spectrum = dB20(rfft(wnd, res * len(wnd))) root_at_xdb = spectrum - spectrum[0] - dB10(power) return next(i for i, el in enumerate(zcross(root_at_xdb)) if el) / res
plt.xlabel("Frequency (Hz)") plt.ylabel("Gain (dB)") plt.figure(2) plt.subplot(2, ceil(len(plot_freq_time) / 2), idx) plt.title("Impulse response - {0} Hz".format(fc)) plt.xlabel("Time (ms)") plt.ylabel("Amplitude") # Plots each filter frequency and impulse response for gt, config in zip(gammatone, ["b-", "g--", "r-.", "k:"]): filt = gt(fc * Hz, bw) plt.figure(1) plt.plot(freq, dB20(filt.freq_response(freq * Hz)), config, label=gt.__name__) plt.figure(2) plt.plot(time_scale, filt(impulse()).take(num_samples), config, label=gt.__name__) # Finish for graph in fig1.axes + fig2.axes: graph.grid() graph.legend(loc="best") fig1.tight_layout()
def scalloping_loss(wnd): """ Positive number with the scalloping loss in dB. """ return -dB20(abs(sum(wnd * cexp(line(len(wnd), 0, -1j * pi)))) / sum(wnd))
def slfo(wnd, res=50, neighbors=2, max_miss=.7, start_delta=1e-4): """ Side Lobe Fall Off (dB/oct). Finds the side lobe peak fall off numerically in dB/octave by using the ``scipy.optimize.fmin`` function. Hint ---- Originally, Harris rounded the results he found to a multiple of -6, you can use the AudioLazy ``rint`` function for that: ``rint(falloff, 6)``. Parameters ---------- res : Zero-padding factor. 1 for no zero-padding, 2 for twice the length, etc.. neighbors : Number of neighbors needed by ``get_peaks`` to define a peak. max_miss : Maximum percent of peaks that might be missed when approximating them by a line. start_delta : Minimum acceptable value for an orthogonal deviation from the approximation line to include a peak. """ # Finds all side lobe peaks, to find the "best" line for it afterwards spectrum = dB20(rfft(wnd, res * len(wnd))) peak_indices = list(get_peaks(spectrum, neighbors=neighbors)) log2_peak_indices = np.log2( peak_indices) # Base 2 ensures result in dB/oct peaks = spectrum[peak_indices] npeaks = len(peak_indices) # This length (actually, twice the length) is the "weight" of each peak lengths = np.array([0] + (1 - z**-2)(log2_peak_indices).skip(2).take(inf) + [0]) # Extreme values weights to zero max_length = sum(lengths) # First guess for the polynomial "a*x + b" is at the center idx = np.searchsorted(log2_peak_indices, .5 * (log2_peak_indices[-1] + log2_peak_indices[0])) a = ((peaks[idx + 1] - peaks[idx]) / (log2_peak_indices[idx + 1] - log2_peak_indices[idx])) b = peaks[idx] - a * log2_peak_indices[idx] # Scoring for the optimization function def score(vect, show=False): a, b = vect h = start_delta * (1 + a**2)**.5 # Vertical deviation while True: pdelta = peaks - (a * log2_peak_indices + b) peaks_idx_included = np.nonzero((pdelta < h) & (pdelta > -h)) missing = npeaks - len(peaks_idx_included[0]) if missing < npeaks * max_miss: break h *= 2 pdelta_included = pdelta[peaks_idx_included] real_delta = max(pdelta_included) - min(pdelta_included) total_length = sum(lengths[peaks_idx_included]) if show: # For debug print(real_delta, len(peaks_idx_included[0])) return -total_length / max_length + 4 * real_delta**.5 a, b = so.fmin(score, [a, b], xtol=1e-12, ftol=1e-12, disp=False) # # For Debug only # score([a, b], show=True) # plt.figure() # plt.plot(log2_peak_indices, peaks, "x-") # plt.plot(log2_peak_indices, a * log2_peak_indices + b) # plt.show() return a
("scallop", "Scallop loss (dB)"), # ("wcpl", "Worst case process loss (dB)"), # ("bw6", "25% power bandwidth (bins)"), # ("ol75", "75% overlap correlation (percent)"), # ("ol50", "50% overlap correlation (percent)"), # ]) size = 50 # Must be even! full_size = 20 * size table = [] for name, wnd_func in iteritems(table_wnds): if name in has_separator_before: table.append([".."] + [""] * (len(schema) - 1)) wnd = wnd_func(size) spectrum = dB20(rfft(wnd, full_size)) wnd_full = wnd_func(full_size) wnd_data = { "name": name, "hsll": hsll(wnd_full), "slfo": slfo(wnd_full), "cg": coherent_gain(wnd_full), "enbw": enbw(wnd_full), "bw3": 2 * find_xdb_bin(wnd, .5), "scallop": scalloping_loss(wnd_full), "wcpl": worst_case_processing_loss(wnd_full), "bw6": 2 * find_xdb_bin(wnd, .25), "ol75": overlap_correlation(wnd_full, .25 * full_size) * 100, "ol50": overlap_correlation(wnd_full, .5 * full_size) * 100, }
def find_xdb_bin(wnd, power=.5, res=1500): """ A not so fast way to find the x-dB cutoff frequency "bin" index """ spectrum = dB20(rfft(wnd, res * len(wnd))) root_at_xdb = spectrum - spectrum[0] - dB10(power) return next(i for i, el in enumerate(zcross(root_at_xdb)) if el) / res
from matplotlib import pyplot as plt import numpy as np from audiolazy import lazy_lpc as lpc from audiolazy import dB20 from audiolazy.lazy_synth import line from math import pi data = eval(file("inputbufferdata.txt").read()) #plt.plot(data) # see http://stackoverflow.com/questions/22328920/extract-numerical-values-from-zfilter-object-in-python-in-audiolazy-library gain = 1e-2 # Gain just for alignment with DFT samples = 1024 min_freq = 0 max_freq = pi new_data = gain / lpc.lpc(data, order=20) freqs = list(line(samples, min_freq, max_freq, finish=True)) data = new_data.freq_response(freqs) print dB20(data) plt.plot(dB20(data)) plt.show()
def slfo(wnd, res=50, neighbors=2, max_miss=.7, start_delta=1e-4): """ Side Lobe Fall Off (dB/oct). Finds the side lobe peak fall off numerically in dB/octave by using the ``scipy.optimize.fmin`` function. Hint ---- Originally, Harris rounded the results he found to a multiple of -6, you can use the AudioLazy ``rint`` function for that: ``rint(falloff, 6)``. Parameters ---------- res : Zero-padding factor. 1 for no zero-padding, 2 for twice the length, etc.. neighbors : Number of neighbors needed by ``get_peaks`` to define a peak. max_miss : Maximum percent of peaks that might be missed when approximating them by a line. start_delta : Minimum acceptable value for an orthogonal deviation from the approximation line to include a peak. """ # Finds all side lobe peaks, to find the "best" line for it afterwards spectrum = dB20(rfft(wnd, res * len(wnd))) peak_indices = list(get_peaks(spectrum, neighbors=neighbors)) log2_peak_indices = np.log2(peak_indices) # Base 2 ensures result in dB/oct peaks = spectrum[peak_indices] npeaks = len(peak_indices) # This length (actually, twice the length) is the "weight" of each peak lengths = np.array([0] + (1 - z **-2)(log2_peak_indices).skip(2).take(inf) + [0]) # Extreme values weights to zero max_length = sum(lengths) # First guess for the polynomial "a*x + b" is at the center idx = np.searchsorted(log2_peak_indices, .5 * (log2_peak_indices[-1] + log2_peak_indices[0])) a = ((peaks[idx+1] - peaks[idx]) / (log2_peak_indices[idx+1] - log2_peak_indices[idx])) b = peaks[idx] - a * log2_peak_indices[idx] # Scoring for the optimization function def score(vect, show=False): a, b = vect h = start_delta * (1 + a ** 2) ** .5 # Vertical deviation while True: pdelta = peaks - (a * log2_peak_indices + b) peaks_idx_included = np.nonzero((pdelta < h) & (pdelta > -h)) missing = npeaks - len(peaks_idx_included[0]) if missing < npeaks * max_miss: break h *= 2 pdelta_included = pdelta[peaks_idx_included] real_delta = max(pdelta_included) - min(pdelta_included) total_length = sum(lengths[peaks_idx_included]) if show: # For debug print(real_delta, len(peaks_idx_included[0])) return -total_length / max_length + 4 * real_delta ** .5 a, b = so.fmin(score, [a, b], xtol=1e-12, ftol=1e-12, disp=False) # # For Debug only # score([a, b], show=True) # plt.figure() # plt.plot(log2_peak_indices, peaks, "x-") # plt.plot(log2_peak_indices, a * log2_peak_indices + b) # plt.show() return a
plt.title("Frequency response - {0} Hz".format(fc)) plt.xlabel("Frequency (Hz)") plt.ylabel("Gain (dB)") plt.figure(2) plt.subplot(2, ceil(len(plot_freq_time) / 2), idx) plt.title("Impulse response - {0} Hz".format(fc)) plt.xlabel("Time (ms)") plt.ylabel("Amplitude") # Plots each filter frequency and impulse response for gt, config in zip(gammatone, ["b-", "g--", "r-.", "k:"]): filt = gt(fc * Hz, bw) plt.figure(1) plt.plot(freq, dB20(filt.freq_response(freq * Hz)), config, label=gt.__name__) plt.figure(2) plt.plot(time_scale, filt(impulse()).take(num_samples), config, label=gt.__name__) # Finish for graph in fig1.axes + fig2.axes: graph.grid() graph.legend(loc="best") fig1.tight_layout() fig2.tight_layout() plt.show()
plt.title("Frequency response - {0} Hz".format(fc)) plt.xlabel("Frequency (Hz)") plt.ylabel("Gain (dB)") plt.figure(2) plt.subplot(2, ceil(len(plot_freq_time) / 2), idx) plt.title("Impulse response - {0} Hz".format(fc)) plt.xlabel("Time (ms)") plt.ylabel("Amplitude") # Plots each filter frequency and impulse response for gt, config in zip(gammatone, ["b-", "g--", "r-.", "k:"]): filt = gt(fc * Hz, bw) plt.figure(1) plt.plot(freq, dB20(filt.freq_response(freq * Hz)), config, label=gt.__name__) plt.figure(2) plt.plot(time_scale, filt(impulse()).take(num_samples), config, label=gt.__name__) # Finish for graph in fig1.axes + fig2.axes: graph.grid() graph.legend(loc="best") fig1.tight_layout() fig2.tight_layout() plt.ioff() plt.show()
from matplotlib import pyplot as plt import numpy as np from audiolazy import lazy_lpc as lpc from audiolazy import dB20 from audiolazy.lazy_synth import line from math import pi data = eval(file("inputbufferdata.txt").read()) #plt.plot(data) # see http://stackoverflow.com/questions/22328920/extract-numerical-values-from-zfilter-object-in-python-in-audiolazy-library gain = 1e-2 # Gain just for alignment with DFT samples = 1024 min_freq = 0 max_freq = pi new_data = gain/lpc.lpc(data, order=20) freqs = list(line(samples, min_freq, max_freq, finish=True)) data = new_data.freq_response(freqs) print dB20(data) plt.plot(dB20(data)) plt.show()