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
from audiolazy import sHz, dB10, ZFilter, pi, ControlStream, white_noise, chunks, AudioIO, xrange, z from scipy.signal import butter, buttord import numpy as np from time import sleep import sys rate = 44100 s, Hz = sHz(rate) kHz = 1e3 * Hz tol = 100 * Hz freq = 2 * kHz wp = freq - tol # Bandpass frequency in rad/sample (from zero) ws = freq + tol # Bandstop frequency in rad/sample (up to Nyquist frequency) order, new_wp_divpi = buttord(wp / pi, ws / pi, gpass=dB10(0.6), gstop=dB10(0.4)) ssfilt = butter(order, new_wp_divpi, btype="lowpass") filt_low = ZFilter(ssfilt[0].tolist(), ssfilt[1].tolist()) ## That can be done without scipy using the equation directly: # filt_low = ((2.90e-4 + 1.16e-3 * z ** -1 + 1.74e-3 * z ** -2 # + 1.16e-3 * z ** -3 + 2.90e-4 * z ** -4) / # (1 - 3.26 * z ** -1 + 4.04 * z ** -2 # - 2.25 * z ** -3 + .474 * z ** -4)) wp = np.array([freq + tol, 2 * freq - tol]) # Bandpass range in rad/sample ws = np.array([freq - tol, 2 * freq + tol]) # Bandstop range in rad/sample order, new_wp_divpi = buttord(wp / pi, ws / pi, gpass=dB10(0.6), gstop=dB10(0.4)) ssfilt = butter(order, new_wp_divpi, btype="bandpass") filt_high = ZFilter(ssfilt[0].tolist(), ssfilt[1].tolist())
1 (DC level) and -1 (Nyquist). """ from __future__ import print_function from audiolazy import sHz, ZFilter, dB10, resonator, pi from scipy.signal import butter, buttord import pylab # Example rate = 44100 s, Hz = sHz(rate) wp = pylab.array([100 * Hz, 240 * Hz]) # Bandpass range in rad/sample ws = pylab.array([80 * Hz, 260 * Hz]) # Bandstop range in rad/sample # Let's use wp/pi since SciPy defaults freq from 0 to 1 (Nyquist frequency) order, new_wp_divpi = buttord(wp / pi, ws / pi, gpass=dB10(.6), gstop=dB10(.4)) ssfilt = butter(order, new_wp_divpi, btype="bandpass") filt_butter = ZFilter(ssfilt[0].tolist(), ssfilt[1].tolist()) # Some debug information new_wp = new_wp_divpi * pi print("Butterworth filter order:", order) # Should be 3 print("Bandpass ~3dB range (in Hz):", new_wp / Hz) # Resonator using only the frequency and bandwidth from the Butterworth filter freq = new_wp.mean() bw = new_wp[1] - new_wp[0] filt_reson = resonator.z_exp(freq, bw) # Plots with MatPlotLib kwargs = {
def processing_loss(wnd): """ Positive number with the ENBW (processing loss) in dB. """ return dB10(enbw(wnd))
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