def compare_tf(a, b, ax=None, fs=44100, to_file=None): if not ax: fig = plt.figure(figsize=(8, 4)) ax = plt.gca() # convert eq params to second order sections sosA = params2sos(denormalize_params(a), fs) sosB = params2sos(denormalize_params(b), fs) # calcuate filter responses fA, hA = sg.sosfreqz(sosA, worN=1024, fs=fs) fB, hB = sg.sosfreqz(sosB, worN=1024, fs=fs) mse = np.mean((np.abs(hA) - np.abs(hB))**2) # plot the magnitude respose plt.title(f"MSE: {mse:0.5f}") original, = plt.semilogx(fA, 20 * np.log10(abs(hA)), 'r--') reconstructed, = plt.semilogx(fB, 20 * np.log10(abs(hB)), 'b') ax.legend(handles=[original, reconstructed], labels=['Original', 'Reconstructed']) ax.set_ylabel('Amplitude [dB]', color='b') ax.set_xlabel('Frequency [Hz]') locmaj = ticker.LogLocator(base=10, numticks=12) ax.xaxis.set_major_locator(locmaj) ax.set_xlim([22.0, 20000.0]) ax.set_ylim([-20, 20]) plt.grid() # note: make this look prettier if to_file: plt.savefig(to_file) return fig
def main(): #SET FS = 44100 sampleRate, inputArray = wavfile.read("test.wav") #GET FROM USER print("LPF================================") F0 = 4000 Q = 3 W0 = 2 * math.pi * (F0 / FS) sos1 = lowpass(W0, Q) inputArray2 = signal.sosfilt(sos1, inputArray) print("Low Shelf================================") F0 = 3000 Q = 3 A = 1 W0 = 2 * math.pi * (F0 / FS) sos2 = lowShelf(W0, Q, A) inputArray3 = signal.sosfilt(sos2, inputArray2) print("Peaking EQ================================") F0 = 1000 Q = 3 A = 1 W0 = 2 * math.pi * (F0 / FS) sos3 = peaking(W0, Q, A) inputArray4 = signal.sosfilt(sos3, inputArray3) print("High Shelf================================") F0 = 250 Q = 3 A = 1 W0 = 2 * math.pi * (F0 / FS) sos4 = highShelf(W0, Q, A) inputArray5 = signal.sosfilt(sos4, inputArray4) print("HPF================================") F0 = 20 Q = 3 W0 = 2 * math.pi * (F0 / FS) sos5 = highpass(W0, Q) outputArray = signal.sosfilt(sos5, inputArray5) w, h1 = signal.sosfreqz(sos1) w, h2 = signal.sosfreqz(sos2) w, h3 = signal.sosfreqz(sos3) w, h4 = signal.sosfreqz(sos4) w, h5 = signal.sosfreqz(sos5) db = 20 * np.log10(np.maximum(np.abs(h1 * h2 * h3 * h3 * h4 * h5), 1e-5)) plt.plot(w / np.pi, db) plt.show() #CALCULATE #READ IN AN AUDIO FILE to a np array inputArray wavfile.write("processed.wav", sampleRate, outputArray)
def mse_tf(a, b, fs=44100): # convert eq params to second order sections sosA = params2sos(denormalize_params(a), fs) sosB = params2sos(denormalize_params(b), fs) # calcuate filter responses fA, hA = sg.sosfreqz(sosA, worN=512, fs=fs) fB, hB = sg.sosfreqz(sosB, worN=512, fs=fs) return np.mean((np.abs(hA) - np.abs(hB))**2)
def make_digital_filter(N, rp, rs, Wn, btype='low'): finish = False WnAdd = Wn rpAdd = rp rsAdd = rs fullArray = [] try: while (finish == False): if (WnAdd < 0.5): WnAdd = WnAdd + 0.001 elif (abs(rpAdd - rp) / rp < 0.05): rpAdd = rpAdd + 0.01 elif (abs(rsAdd - rs) / rs < 0.05): rsAdd = rsAdd + 0.01 else: raise Exception( "There is no filters with these characteristics.") b, a = signal.ellip(N, rpAdd, rsAdd, WnAdd, btype, analog=False) sos = signal.tf2sos(b, a) #print sos w, h = signal.sosfreqz(sos, worN=1000000) #plot_2nd_order_from_sos(sos) makeCallibration(sos) #plot_2nd_order_from_sos(sos) #print "sos" print sos w, h = signal.sosfreqz(sos, worN=1000000) #plot_sosfreqz(w,h) #fullArray = getCoefficientsForElliptic(sos, True) fullArray = getCoefficients(sos) #print fullArray try: new_sos = getSosFromCoefficients(fullArray) #new_sos = getSosFromCoefficientsForElliptic(fullArray) finish = True except ValueError as e: pass except Exception as e: print e print "There is no filters with these characteristics." return w, h = signal.sosfreqz(sos, worN=1000000) #plot_sosfreqz(w,h) print "new_sos" print new_sos print "general_coefficients" fullArrayRounded = getRoundCoefficients(fullArray) getKeysFromKoefArray(fullArrayRounded) w, h = signal.sosfreqz(new_sos, worN=1000000) plot_sosfreqz(w, h)
def butter_bandpass_filter(data, low_cut_freq, high_cut_freq, Fs=params.Fs, order=5): """ :param data: the samples to filter :param low_cut_freq: the low cut frequency :param high_cut_freq: the high cut frequency :param Fs: the sampling frequency :param order: the order of the filter :return: the filtered samples """ sos = butter_bandpass(low_cut_freq, high_cut_freq, Fs, order=order) y = sosfilt(sos, data) if params.plots: w, h = sosfreqz(sos, worN=2000) plt.plot((Fs * 0.5 / np.pi) * w, abs(h), label="order = %d" % order) plt.title("Output of butter bandpass") plt.xlabel('Frequency (Hz)') plt.ylabel('Gain') plt.grid(True) plt.legend(loc='best') plt.show() return y
def butter_highpass_fs(sig, lowcut, fs, order=5, output='ba'): sos = signal.butter(order, [lowcut], btype='highpass', output=output, fs=fs) filtered = signal.sosfreqz(sos, worN=sig) return filtered
def D_Filter(l_F, h_F, fs, o_filt): # Ambos filtros son digitales #b, a = signal.iirfilter(o_filt, Wn=[l_F/fs, h_F/fs], btype='bandpass', analog=False, ftype='butter', output='ba') ### Diseño utilizando las frecuencias normalizadas, no se le especifica Frecuencias de sampling sos = signal.iirfilter(o_filt, Wn=[l_F, h_F], btype='bandpass', ftype='butter', analog=False, output='sos', fs=fs) ## Se manda a graficar utilizando sosfreqz w, h = signal.sosfreqz(sos, 2000, fs=fs) plt.figure(1) Fig_Filtro = plt.subplot(2, 1, 1) Fig_Filtro.set_title('Digital filter frequency response') Fig_Filtro.semilogx(w, 20 * np.log10(np.maximum(abs(h), 1e-5))) Fig_Filtro.set_ylabel('Amplitude Response [dB]') Fig_Filtro.set_xlabel('Frequency [Hz]') Fig_Filtro.grid() Fig_Filtro = plt.subplot(2, 1, 2) Fig_Filtro.semilogx(w, np.angle(h)) Fig_Filtro.set_ylabel('Phase [Degrees]') Fig_Filtro.set_xlabel('Frequency [Hz]') return sos
def _recv_decode_init(self, recv_f): self._filters = [] for i in range(2): f = recv_f[i] filter_bp = signal.iirfilter(4, [f / 1.05, f * 1.05], rs=40, btype='bandpass', analog=False, ftype='butter', fs=sample_f, output='sos') self._filters.append(filter_bp) if not plot_spectrum: return import matplotlib.pyplot as plt plt.figure() plt.ylim(-100, 5) plt.xlim(0, 5500) plt.grid(True) plt.xlabel('Frequency (Hz)') plt.ylabel('Gain (dB)') plt.title('{}Hz, {}Hz'.format(recv_f[0], recv_f[1])) for i in range(2): f = recv_f[i] w, h = signal.sosfreqz(self._filters[i], 2000, fs=sample_f) plt.plot(w, 20 * np.log10(np.abs(h)), label=str(f) + 'Hz') plt.plot((f, f), (10, -100), color='red', linestyle='dashed') plt.plot((500, 500), (10, -100), color='blue', linestyle='dashed') plt.plot((700, 700), (10, -100), color='blue', linestyle='dashed') plt.show()
def filt(data, fs, cutoff_low=None, cutoff_high=None, filt_type='low', order=5): nyq = 0.5 * fs if cutoff_low is not None: norm_cutoff_low = cutoff_low / nyq if cutoff_high is not None: norm_cutoff_high = cutoff_high / nyq if filt_type is 'low': #b, a = butter(order, norm_cutoff_high, btype='low', analog=False) sos = butter(order, norm_cutoff_high, btype='low', output='sos', analog=False) elif filt_type is 'band': # b, a = butter(order, # [norm_cutoff_low, norm_cutoff_high], # btype='band', # analog=False) sos = butter(order, [norm_cutoff_low, norm_cutoff_high], btype='band', output='sos', analog=False) #data_filt = lfilter(b, a, data) # note that the order is twice as passed since filter applied 2 directions data_filt = sosfiltfilt(sos, data) # w, h = freqz(b, a) #for showing freq response w, h = sosfreqz(sos, fs=fs, worN=2000) return data_filt, (w, h)
def BandPassFilter(data, lowcut, highcut, fs, order, bWindowData): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq b, a = butter(order, [low, high], btype='band') b = b / a[0] a = a / a[0] #For higher order filters use second order signal sos = butter(6, [low, high], btype='bandpass', output='sos') w, h = sosfreqz(sos, round(fs / 2)) if bWindowData == True: #Uss a blackman window accross the data window = blackman(len(data)) data = data * window #w, h = freqz(b, a, round(fs/2)) plt.plot((fs * 0.5 / np.pi) * w, abs(h), label="order = %d" % order) plt.plot([0, 0.5 * fs], [np.sqrt(0.5), np.sqrt(0.5)], '--', label='sqrt(0.5)') plt.xlabel('Frequency (Hz)') plt.ylabel('Gain') plt.grid(True) plt.legend(loc='best') plt.show() fData = lfilter(b, a, data) return fData
def makefiltersos(sr,fp,fs,gp=3,gs=20): """ Wrapper function around scipy filter functions. Makes it convenient by providing frequency parameters in terms of frequencies in Hz. INPUT: sr - sampling rate in Hz. fp - pass frequency in Hz fs - stop frequency in Hz gp - pass band ripple in dB, default 3 dB gs - stop band attenuation in dB, default 20 dB doPlot - make a plot of filter gain versus frequency, default 'no' OUTPUT: sos filter coefficients. w,h for making bode plot Automatically detects the type of filter. if fp < fs the filter is low pass but if fp > fs the filter is highpass. """ # #set up filter parameters fn = sr/2 wp = fp/fn ws = fs/fn #get the filter order n,wn = signal.buttord(wp,ws,gp,gs); #design the filter #lowpass if fp < fs: sos = signal.butter(n,wn,btype='lowpass',output='sos') #highpass if fs < fp: sos = signal.butter(n,wn,btype='highpass',output='sos') #get filter respons function w,h = signal.sosfreqz(sos,fs=sr) return sos,w,h
def plotSos(sos, oversample, fs, worN=2048): fig, ax = plt.subplots(3, 1) fig.set_size_inches(6, 8) fig.set_tight_layout(True) ax[0].set_title("Amplitude Response") ax[0].set_ylabel("Amplitude [dB]") ax[1].set_title("Phase Response") ax[1].set_ylabel("Phase [rad]") ax[2].set_title("Group Delay") ax[2].set_ylabel("Group Delay [sample]") ax[2].set_xlabel("Frequency [rad/sample]") cmap = plt.get_cmap("plasma") freq, h0 = signal.sosfreqz(sos, worN=worN, fs=oversample * fs) b, a = signal.sos2tf(sos) _, gd = signal.group_delay((b, a), w=worN) ax[0].plot(freq, ampToDecibel(h0), alpha=0.75, color="black") ax[0].set_ylim((-140, 5)) ax[1].plot(freq, np.unwrap(np.angle(h0)), alpha=0.75, color="black") ax[2].plot(freq, gd, alpha=0.75, color="black") for axis in ax: # axis.set_xscale("log") axis.grid(which="both") plt.show()
def _showfilter(sos, freq, freq_u, freq_d, fs, factor): wn = 8192 w = np.zeros([wn, len(freq)]) h = np.zeros([wn, len(freq)], dtype=np.complex_) for idx in range(len(freq)): fsd = fs / factor[idx] # New sampling rate w[:, idx], h[:, idx] = signal.sosfreqz(sos[idx], worN=wn, whole=False, fs=fsd) fig, ax = plt.subplots() ax.semilogx(w, 20 * np.log10(abs(h) + np.finfo(float).eps), 'b') ax.grid(which='major') ax.grid(which='minor', linestyle=':') ax.set_xlabel(r'Frequency [Hz]') ax.set_ylabel('Amplitude [dB]') ax.set_title('Second-Order Sections - Butterworth Filter') plt.xlim(freq_d[0] * 0.8, freq_u[-1] * 1.2) plt.ylim(-4, 1) ax.set_xticks([16, 31.5, 63, 125, 250, 500, 1000, 2000, 4000, 8000, 16000]) ax.set_xticklabels([ '16', '31.5', '63', '125', '250', '500', '1k', '2k', '4k', '8k', '16k' ]) plt.show()
def butter_bandpass(sig, lowcut, highcut, fs, order=5, output='ob'): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq sos = signal.butter(order, [low, high], btype='bandpass', output=output) filtered = signal.sosfreqz(sos, sig) return filtered
def subplot_tf(x, fs, ax, zeroline=True, ticks=False, denorm=True): if denorm: x = denormalize_params(x) # convert eq params to second order sections sos = params2sos(x, fs) # calculate filter response f, h = sg.sosfreqz(sos, worN=2048, fs=fs) # plot the magnitude respose ax.plot(f, 20 * np.log10(abs(h)), 'b') ax.set_xscale('log') ax.set_xlim([20.0, 20000.0]) ax.set_ylim([-20, 20]) if ticks: ocmaj = ticker.LogLocator(base=10, numticks=12) ax.xaxis.set_major_locator(locmaj) else: ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False) if zeroline: ax.axhline(linewidth=0.5, color='gray', zorder=0) ax.tick_params(labelbottom=False, labelleft=False) plt.grid(False, which='both')
def plot_tf(x, fs=44100, plot_title=None, to_file=""): if not plot_title: plot_title = 'Digital filter frequency response' # convert eq params to second order sections sos = params2sos(x, fs) # calculate filter response f, h = sg.sosfreqz(sos, worN=2048, fs=fs) # plot the magnitude respose fig, ax1 = plt.subplots() ax1.set_title(plot_title) ax1.semilogx(f, 20 * np.log10(abs(h)), 'b') ax1.set_ylabel('Amplitude [dB]', color='b') ax1.set_xlabel('Frequency [Hz]') ax1.set_xlim([22.0, 20000.0]) ax1.set_ylim([-20, 20]) ax1.grid() # note: make this look prettier if to_file: plt.savefig(to_file) else: plt.show() plt.close()
def test_bandpass_filterbank(): f0 = 125.0 / 2.0 fs = 16000 bands, fc = pra.octave_bands(f0) filters = pra.bandpass_filterbank(bands, fs=fs, order=16) res = None for sos, f in zip(filters, fc): w, h = sosfreqz(sos, worN=4096, whole=False) # inspect the cumulative response if res is None: res = np.abs(h)**2 else: res += np.abs(h)**2 # check automatically that the cumulative response is (nearly) flat freq = w / np.pi * fs / 2 I = np.where( np.logical_and(freq > fc[0], freq < np.minimum(fc[-1], 0.95 * fs / 2)))[0] err = np.max(np.abs(10 * np.log10(res[I]))) assert err <= tol, "Bandpass filterbank test fails (err {} > tol {})".format( err, tol)
def envelope_modifier_spread(env, m): #env = np.array(env) nt = len(env[0]) new_env = np.zeros((len(env), nt)) if m['synthesis']['carrier'] != 'sin': raise ValueError( "[vocoder] Envelope modifier 'spread' only works with sinewave carriers." ) f = m['synthesis']['f'] nf = len(f) for i, e in enumerate(env): _, h = signal.sosfreqz(m['synthesis_filters']['filters'][i], worN=f, whole=False, fs=m['fs']) h = np.abs(h) if m['synthesis_filters']['method']['zero-phase']: h = h**2. new_env += np.tile(h.reshape(-1, 1), (1, nt)) * np.tile(e.reshape(1, -1), (nf, 1)) return new_env
def getRRInterval(data): x=data for order in [1, 2, 4, 6, 8]: sos = qrs_detection.butter_bandpass(LOWCUT, HIGHCUT, FS, order=order) w, h = sosfreqz(sos, worN=2000) # Calculate time values in seconds #times = np.arange(x.shape[0], dtype='float') / fs y = qrs_detection.butter_bandpass_forward_backward_filter(x, LOWCUT, HIGHCUT, FS, order=4) # Derivative - provides QRS slope information. differentiated_ecg_measurements = np.ediff1d(y) # Squaring - intensifies values received in derivative. # This helps restrict false positives caused by T waves with higher than usual spectral energies.. squared_ecg_measurements = differentiated_ecg_measurements ** 2 # Moving-window integration. integration_window = 50 # Change proportionally when adjusting frequency (in samples) integrated_ecg_measurements = np.convolve(squared_ecg_measurements, np.ones(integration_window)) # Fiducial mark - peak detection on integrated measurements. rpeaks = qrs_detection.pan_tompkins_detector(data, integrated_ecg_measurements, FS, integration_window) # RR Interval rr = np.diff(rpeaks) / FS * 1000 # in miliseconds #hr = 60 * 1000 / rr return rr
def butter_lowpass(sig, lowcut, highcut, fs, order=5, output='ob'): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq sos = signal.butter(order, [high], btype='lowpass', output='ba') filtered = signal.sosfreqz(sos, sig) # pp = plt.semilogx((fs * 0.5 / np.pi) * w, abs(h), label=label) return filtered
def update_frequency_response(self): self.sos = self.get_second_order_sections() w, h = signal.sosfreqz(self.sos, self.normalized_frequencies * np.pi * 2) magnitude = np.abs(h) self.total_response_magnitude.setData(x=self.normalized_frequencies * SAMPLERATE, y=magnitude)
def get_plot_data(self, plot_type): if plot_type == "Original Data": if type(self.app_data.data) == np.ndarray: return self.app_data.data else: raise ValueError("Error: Must import data first.") elif plot_type == "Filtered Data": if self.app_data.filter_applied: return self.app_data.filtered_data else: raise ValueError("Must apply a filter first.") elif plot_type == "FFT": if type(self.app_data.data) == np.ndarray: if self.app_data.filter_type == "FIR Filter" or self.app_data.filter_type == "Butterworth": fft_values = np.abs(np.fft.fft(self.app_data.data)) fft_freq = np.zeros(len(fft_values)) for i in range(len(fft_freq)): fft_freq[i] = i / (len(fft_freq) * self.app_data.filter.Ts) return np.array([fft_freq, fft_values]) else: return np.abs(np.fft.fft(self.app_data.data)) else: raise ValueError("Error: Must import data first.") elif plot_type == "Filter Response": if self.app_data.filter_applied: if self.app_data.filter_type == "Butterworth": sos = np.zeros([len(self.app_data.filter.IIR_filters), 6]) idx = 0 for filter in self.app_data.filter.IIR_filters: if filter.P_order == 2: sos[idx] = [ filter.P_coeff[0], filter.P_coeff[1], filter.P_coeff[2], 1, filter.Q_coeff[0], filter.Q_coeff[1] ] idx += 1 elif filter.P_order == 1: sos[idx] = [ 0, filter.P_coeff[0], filter.P_coeff[1], 1, filter.Q_coeff[0], 0 ] idx += 1 w, h = sc.sosfreqz(sos, worN=None, whole=False) w = w / (2 * np.pi * self.app_data.filter.Ts) return np.array([w, np.abs(h)]) elif self.app_data.filter_type == "IIR Filter": b = self.app_data.filter.P_coeff a = np.concatenate([[1], self.app_data.filter.Q_coeff]) w, h = sc.freqz(b=b, a=a) return np.array([w, np.abs(h)]) elif self.app_data.filter_type == "FIR Filter": w, h = sc.freqz(b=self.app_data.filter.filter_coeffs) w = w / (2 * np.pi * self.app_data.filter.Ts) return np.array([w, np.abs(h)]) else: raise ValueError("Must apply a filter first.")
def test_spatial_filter(lats_grid): """Test creation and frequency response of a latitude-dependent filter.""" f = lats_grid * 0.1 filt = filtering.filter.SpatialFilter(f.flatten(), 1) for freq, filter_obj in zip(f, filt._filter): w, h = signal.sosfreqz(filter_obj) assert np.all(abs(h)[w < freq] < 0.1)
def plot_response(name, sos_real, sos_imag): _, h_real = signal.sosfreqz(sos_real, whole=True) w, h_imag = signal.sosfreqz(sos_imag, whole=True) h = h_real / h_imag # h = h_imag fig, ax1 = pyplot.subplots() ax1.set_title(f"Frequency response ({name})") ax1.plot(w, abs(h), "b", alpha=0.2) ax1.set_ylabel("Amplitude", color="b") ax1.set_xlabel("Frequency [rad/sample]") ax2 = ax1.twinx() angles = numpy.unwrap(numpy.angle(h)) ax2.plot(w, angles, "g") ax2.set_ylabel("Angle (radians)", color="g") ax2.grid() ax2.axis("tight")
def bandpass_filter(data, lowcut, highcut, sampling_frequency, order=5, plot_on=0): """ Bandpass filter signal between locut and highcut frequencies Uses butterworth second order section. Wrapper for scipy.signal.butter Adapted from: https://stackoverflow.com/a/48677312/1886357 Inputs: data (1d numpy array) lowcut: low cutoff frequency highcut: high cutoff frequency sampling_frequency: frequency (Hz) at which data was sampled order: order of filter (higher is sharper corners) (5) plot_on (int): 0 no plot, 1 to plot filter, original, and filtered signals Outputs: data_filtered (1d numpy array) -- same size as data, but filtered butter_sos: butterworth bandpass filter (second order section) """ nyq = 0.5 * sampling_frequency low = lowcut / nyq high = highcut / nyq butter_sos = signal.butter(order, [low, high], analog=False, btype='band', output='sos') filtered_data = signal.sosfiltfilt(butter_sos, data) if plot_on: print("Plotting") # Filter w, h = signal.sosfreqz(butter_sos, worN=2000) plt.subplot(2, 1, 1) plt.plot((sampling_frequency * 0.5 / np.pi) * w, abs(h)) plt.axvline(lowcut, color='r', linewidth=0.5) plt.axvline(highcut, color='r', linewidth=0.5) plt.ylabel('Gain') plt.xlabel('Frequency') plt.autoscale(enable=True, axis='x', tight=True) # Data: original and filtered plt.subplot(2, 1, 2) plt.plot(data, color=(0.7, 0.7, 0.7), linewidth=0.5) plt.plot(filtered_data, color='r', linewidth=1) plt.xlabel('Sample') plt.ylabel('Value') plt.autoscale(enable=True, axis='x', tight=True) plt.tight_layout() return filtered_data, butter_sos
def comp_dac_resp(dpe_fb, sim_len, rrc_beta, PAPR=9, prms_dac=(16e9, 2, 'sos', 6), os=2): """ Compensate frequency response of a simulated digital-to-analog converter(DAC). Parameters ---------- dpe_fb : int symbol rate to compensate for sim_len : int length of the oversampled signal array rrc_beta : float root-raised cosine roll-off factor of the simulated signal PAPR: int (optional) peak to average power ratio of the signal prms_dac: tuple(float, int, str, int) DAC filer parameters for calculating the filter response using scipy.signal os: int (optional) oversampling factor of the signal """ dpe_fs = dpe_fb * os # Derive RRC filter frequency response np.sqrt(n_f) T_rrc = 1 / dpe_fb fre_rrc = np.fft.fftfreq(sim_len) * dpe_fs rrc_f = rrcos_freq(fre_rrc, rrc_beta, T_rrc) rrc_f /= rrc_f.max() n_f = rrc_f**2 # Derive bessel filter (DAC) frequency response d_f cutoff, order, frmt, enob = prms_dac system_dig = signal.bessel(order, cutoff, 'low', analog=False, output=frmt, norm='mag', fs=dpe_fs) # w_bes=np.linspace(0,fs-fs/worN,worN) w_bes, d_f = signal.sosfreqz(system_dig, worN=sim_len, whole=True, fs=dpe_fs) # Calculate dpe filter p_f df = dpe_fs / sim_len alpha = 10**(PAPR / 10) / (6 * dpe_fb * 2**(2 * enob)) * np.sum( abs(d_f)**2 * n_f * df) p_f = n_f * np.conj(d_f) / (n_f * abs(d_f)**2 + alpha) return p_f
def third_octave(speech): ## Filtering of the time series sampleRate = 44100.0 nyquistRate = sampleRate/2.0 # 0.5 times the sampling frequency centerFrequency_Hz = np.array([39, 50, 63, 79, 99, 125, 157, 198, 250, 315, 397, 500, 630, 794, 1000, 1260, 1588, 2000, 2520, 3176, 4000, 5040, 6352, 8000, 10080, 12704, 16000]) G = 2 #base-2 rules factor = np.power(G, 1.0/6.0) lowerCutoffFrequency_Hz=centerFrequency_Hz/factor upperCutoffFrequency_Hz=centerFrequency_Hz*factor all_filter = [] # ##fig=plt.figure() # ##plt.title('Speech Signal') # ##plt.plot(speech) # ##plt.show() # plt.figure() # plt.ylabel('Magnitude [dB]') # plt.xlabel('Frequency [rad/sample]') # plt.title('Digital filter frequency response') # plt.grid() # plt.axis([-0.2, 3.2, -80, 20]) for lower,upper in zip(lowerCutoffFrequency_Hz, upperCutoffFrequency_Hz): # Design filter sos = signal.butter( N=4, Wn=np.array([lower, upper])/nyquistRate, btype='bandpass', analog=False, output='sos'); # # Compute frequency response of the filter. w, h = signal.sosfreqz(sos) # ## for i in range(len(h)): ## if h[i] == 0j: ## h[i] = min(j for j in h if j > 0) ## # plt.plot(w, 20 * np.log10(abs(h)/max(h)), 'b') # Filter signal filteredSpeech = signal.sosfiltfilt(sos, speech) for i in filteredSpeech: all_filter.append(i) # plt.plot(all_filter) # plt.figure() # plt.title('Third Octave-band Filtered Speech') # plt.plot(filteredSpeech) # new = np.round(all_filter).astype('int16') # new_sound = sound._spawn(new) # new_sound.export("music/clicks.mp3", format="mp3") # print(all_filter) return all_filter
def compute_frequency_response(filter_coefs, a_vals, fs): """Compute the frequency response of a filter. Parameters ---------- filter_coefs : 1d or 2d array If 1d, interpreted as the B-value filter coefficients. If 2d, interpreted as the second-order (sos) filter coefficients. a_vals : 1d array or None The A-value filter coefficients for a filter. If second-order filter coefficients are provided in `filter_coefs`, must be None. fs : float Sampling rate, in Hz. Returns ------- f_db : 1d array Frequency vector corresponding to attenuation decibels, in Hz. db : 1d array Degree of attenuation for each frequency specified in `f_db`, in dB. Examples -------- Compute the frequency response for an FIR filter: >>> from neurodsp.filt.fir import design_fir_filter >>> filter_coefs = design_fir_filter(fs=500, pass_type='bandpass', f_range=(8, 12)) >>> f_db, db = compute_frequency_response(filter_coefs, 1, fs=500) Compute the frequency response for an IIR filter, which uses SOS coefficients: >>> from neurodsp.filt.iir import design_iir_filter >>> sos_coefs = design_iir_filter(fs=500, pass_type='bandpass', ... f_range=(8, 12), butterworth_order=3) >>> f_db, db = compute_frequency_response(sos_coefs, None, fs=500) """ if filter_coefs.ndim == 1 and a_vals is not None: # Compute response for B & A value filter coefficient inputs w_vals, h_vals = freqz(filter_coefs, a_vals, worN=int(fs * 2)) elif filter_coefs.ndim == 2 and a_vals is None: # Compute response for sos filter coefficient inputs w_vals, h_vals = sosfreqz(filter_coefs, worN=int(fs * 2)) else: raise ValueError( "The organization of the filter coefficient inputs is not understood." ) f_db = w_vals * fs / (2. * np.pi) db = 20 * np.log10(abs(h_vals)) return f_db, db
def response(self, freqs=None, num_points=1024): if freqs is not None: freqs = np.array(freqs) w = 2 * np.pi * freqs / self.sample_rate else: w = num_points w2, h = signal.sosfreqz(self.sos, w) return data.Spectrum(h, self.sample_rate, freqs=(self.sample_rate * w2 / (2 * np.pi)))
def designFilters(freqDict, fs=48000, plot=False): """ Design octave band filters :param freqDict: filter specification dict :param fs: sample rate :param plot: bool if filters should be plotted :return: filter coefficients """ freqs = freqDict["f"] b = freqDict["b"] G = freqDict["G"] order = 4 filters = np.empty((0, 6)) for index in range(np.size(freqs, axis=0)): lowCutoff = 2 * freqs[index, 0] / fs highCutoff = 2 * freqs[index, 2] / fs sos = signal.butter(order, [lowCutoff, highCutoff], btype="bandpass", output="sos") filters = np.append(filters, sos, axis=0) if plot is True: # Requirements maskLevelmax = -np.array( [0.15, 0.2, 0.4, 1.1, 4.5, 4.5, 200, 200, 200, 200]) maskLevelmin = -np.array( [-0.15, -0.15, -0.15, -0.15, -0.15, 2.3, 18, 42.5, 62, 75]) breakpoints = np.array( [0, 1 / 8, 1 / 4, 3 / 8, 1 / 2, 1 / 2, 1, 2, 3, 4]) freqH = 1 + ((G**(1 / (2 * b)) - 1) / (G**(1 / 2) - 1)) * (G**(breakpoints) - 1) freqL = 1 / freqH plt.figure("Filter responses with {} bands from {} Hz to {} Hz".format( np.size(freqs, 0), np.int(freqs[0, 0]), np.int(freqs[-1, 2]))) for index in range(np.size(freqs, axis=0)): # Plot w, h = signal.sosfreqz(filters[(order * index):(order * index + order), :], worN=fs) plt.semilogx(freqH * freqs[index, 1], maskLevelmax, "k--") plt.semilogx(freqH * freqs[index, 1], maskLevelmin, "k--") plt.semilogx(freqL * freqs[index, 1], maskLevelmax, "k--") plt.semilogx(freqL * freqs[index, 1], maskLevelmin, "k--") plt.semilogx((fs * 0.5 / np.pi) * w, 20 * np.log10(abs(h))) plt.ylim([-100, 1]) plt.show() return filters
def test_freq_resp_sos(self): # Test that frequency response meets tolerance from ITU-R BS.468-4 fs = 400000 sos = ITU_R_468_weighting(fs, output='sos') w, h = signal.sosfreqz(sos, 2*pi*frequencies/fs) levels = 20 * np.log10(abs(h)) if mpl: plt.figure('468') plt.semilogx(frequencies, levels, alpha=0.7, label='sos') plt.legend() assert all(np.less_equal(levels, responses + upper_limits)) assert all(np.greater_equal(levels, responses + lower_limits))
from __future__ import division, print_function import numpy as np from scipy.signal import butter, sosfreqz, sosfilt import matplotlib.pyplot as plt sos = butter(10, [0.04, 0.16], btype="bandpass", output="sos") w, h = sosfreqz(sos, worN=8000) # Plot the magnitude and phase of the frequency response. plt.figure(figsize=(4.0, 4.0)) plt.subplot(211) plt.plot(w/np.pi, np.abs(h)) plt.grid(alpha=0.25) plt.ylabel('Gain') plt.subplot(212) plt.plot(w/np.pi, np.angle(h)) yaxis = plt.gca().yaxis yaxis.set_ticks([-np.pi, -0.5*np.pi, 0, 0.5*np.pi, np.pi]) yaxis.set_ticklabels([r'$-\pi$', r'$-\pi/2$', '0', r'$\pi/2$', r'$\pi$']) plt.xlabel('Normalized frequency') plt.grid(alpha=0.25) plt.ylabel('Phase') plt.tight_layout() plt.savefig("sos_bandpass_response_freq.pdf") # Plot the step response. x = np.ones(200) y = sosfilt(sos, x)
# Sample rate and desired cutoff frequencies (in Hz). fs = 4800.0 lowcut = 400.0 highcut = 1200.0 # Plot the frequency response for a few different orders. plt.figure(figsize=(4.0, 4.0)) # First plot the desired ideal response as a green(ish) rectangle. rect = plt.Rectangle((lowcut, 0), highcut - lowcut, 1.0, facecolor="#60ff60", edgecolor='k', alpha=0.15) plt.gca().add_patch(rect) for order in [3, 6, 12]: sos = butter_bandpass(lowcut, highcut, fs, order) w, h = sosfreqz(sos, worN=2000) plt.plot((fs*0.5/np.pi)*w, abs(h), 'k', alpha=(order+1)/13, label="order = %d" % order) plt.plot([0, 0.5 * fs], [np.sqrt(0.5), np.sqrt(0.5)], 'k--', alpha=0.6, linewidth=1, label=r'$\sqrt{2}/2$') plt.xlim(0, 0.5*fs) plt.xlabel('Frequency (Hz)') plt.ylabel('Gain') plt.grid(alpha=0.5) plt.legend(framealpha=1, shadow=True, loc='best') plt.title("Amplitude response for\nButterworth bandpass filters", fontsize=10) plt.text(430, 0.07, "lowcut: %4g Hz\nhighcut: %4g Hz" % (lowcut, highcut), fontsize=8) plt.tight_layout() plt.savefig("bandpass_example_response.pdf")