def estimate(rg, filt, para, impulse, fs): aa = zeros(len(rg)) Q = zeros(len(rg)) maxh = zeros(len(rg)) for i, freq in enumerate(rg): filt[para] = freq filt.compute(zeros(10000, dtype=float32)) w, h = freqz(filt.compute(impulse), worN=15000) k1 = int(round(len(h) * 100.0 / fs)) k2 = int(round(len(h) * 10000.0 / fs)) B, A = invfreqz(w[k1 : k2 + 1], h[k1 : k2 + 1]) R = sqrt(A[2]) theta = math.acos(A[1] / (-2 * R)) aa[i] = fs * theta frn = theta / (2 * pi) Q[i] = (pi * frn) / (1 - R) print "Pole frequency = %f Hz" % (aa[i] / (2 * pi)) # print 'Q = %f' % Q[i] # print "R =", R # print "frn =", frn, "theta =", theta A = array((1, -2 * R * cos(theta), R * R)) w1, h1 = freqz(Bconst, A, worN=15000) maxh[i] = max(abs(h)) # print "gain =", gain[i] return aa, Q, maxh
def plot_response(self, ax): # Plot the designed filter response if self.n_section == 1: fw, fh = signal.freqz(self.b, self.a, worN=self.Nfft) ax.plot(fw, 20*log10(np.abs(fh)), linewidth=2, alpha=.75) fxw, fxh = signal.freqz(self.fxb, self.fxa, worN=self.Nfft) ax.plot(fxw, 20*log10(np.abs(fxh)), linestyle='--', linewidth=3, alpha=.75) # plot the simulated response, if simulated data exists if self.xfavg is None or self.yfavg is None or self.pfavg is None: pass else: # -- Fixed Point Sim -- xa = 2*pi * np.arange(self.Nfft)/self.Nfft h = self.yfavg / self.xfavg ax.plot(xa, 20*log10(h), linewidth=4, alpha=.5) # -- Floating Point Sim -- hp = self.pfavg / self.xfavg ax.plot(xa, 20*log10(hp), color='k', linestyle=':', linewidth=2, alpha=.75) ax.set_ylim(-80, 10) ax.set_xlim(0, np.pi) ax.set_ylabel('Magnitude dB'); ax.set_xlabel('Frequency Normalized Radians') ax.legend(('Ideal', 'Quant. Coeff.', 'Fixed-P. Sim', 'Floating-P. Sim'))
def diffplot(freq, B, A, B2, A2): w, h = sps.freqz(B, A) w2, h2 = sps.freqz(B2, A2) # h = h - h2 dabs = abs(h2) / abs(h) dphase = np.unwrap(np.angle(h2)) - np.unwrap(np.angle(h)) fig = plt.figure() plt.title('Difference between digital filter frequency responses') ax1 = fig.add_subplot(111) plt.plot(w * (freq/np.pi) / 2.0, 20 * np.log10(dabs), 'b') plt.ylabel('Amplitude [dB]', color='b') plt.xlabel('Frequency [rad/sample]') ax2 = ax1.twinx() angles = np.unwrap(np.angle(h)) angles = dphase plt.plot(w * (freq/np.pi) / 2.0, angles, 'g') plt.ylabel('Angle (radians)', color='g') plt.grid() plt.axis('tight') plt.show()
def freqz(b, a=1, fs=1, xlim=None, N=1000, xlog=False): """Calculate the frequency response of a discrete time system over the range xlim, over a log or linear interval. Parameters ---------- b : array-like Numerator coefficients of discrete time system a : array-like, optional Denominator coefficients of discrete time system fs : float, optional Sampling frequency; use to scale the output frequency array xlim : tuple of (x_min, x_max), optional Calculate the response from x_min to x_max. If omitted, the entire digital frequency axis is used N : int, optional The number of points to calculate the system response at xlog : bool, optional Calculate the frequency response at a log (True) or linearly spaced set of points""" # Squeeze arrays to deal with cont2discrete array issues b = np.squeeze(b) a = np.squeeze(a) if xlim is None: w, resp = signal.freqz(b, a) w = lin_or_logspace(w[w > 0][0], w[-1], N, True) _, resp = signal.freqz(b, a, w) else: w = 2 * np.pi * lin_or_logspace(xlim[0], xlim[1], N, xlog) / fs _, resp = signal.freqz(b, a, worN=w) freq = w * fs / (2 * np.pi) return freq, resp
def plot_filter(h, title, freq, gain, show=True): if h.ndim == 2: # second-order sections sos = h n = mne.filter.estimate_ringing_samples(sos) h = np.zeros(n) h[0] = 1 h = signal.sosfilt(sos, h) H = np.ones(512, np.complex128) for section in sos: f, this_H = signal.freqz(section[:3], section[3:]) H *= this_H else: f, H = signal.freqz(h) fig, axs = plt.subplots(2) t = np.arange(len(h)) / sfreq axs[0].plot(t, h, color=blue) axs[0].set(xlim=t[[0, -1]], xlabel='Time (sec)', ylabel='Amplitude h(n)', title=title) box_off(axs[0]) f *= sfreq / (2 * np.pi) axs[1].semilogx(f, 10 * np.log10((H * H.conj()).real), color=blue, linewidth=2, zorder=4) plot_ideal(freq, gain, axs[1]) mne.viz.tight_layout() if show: plt.show()
def _find_min_max(self, f_start, f_stop, unit = 'dB'): """ Find minimum and maximum magnitude and the corresponding frequencies for the filter defined in the filter dict in a given frequency band [f_start, f_stop]. """ w = np.linspace(f_start, f_stop, params['N_FFT'])*2*np.pi [w, H] = sig.freqz(bb, aa, worN = w) # add antiCausals if we have them if (antiC): # # Evaluate transfer function of anticausal half on the same freq grid. # wa, ha = sig.freqz(bbA, aaA, worN = w) ha = ha.conjugate() # # Total transfer function is the product # H = H*ha f = w / (2.0 * pi) # frequency normalized to f_S H_abs = abs(H) H_max = max(H_abs) H_min = min(H_abs) F_max = f[np.argmax(H_abs)] # find the frequency where H_abs F_min = f[np.argmin(H_abs)] # becomes max resp. min if unit == 'dB': H_max = 20*log10(H_max) H_min = 20*log10(H_min) return F_min, H_min, F_max, H_max
def compute_frequencies(self, N=None): if hasattr(self, 'sample_rate'): try: self.W, self.H = signal.freqz(self.B, self.A) except: self.W, self.H = signal.freqz(self.B) else: self.W, self.H = signal.freqs(self.B, self.A, N)
def test_plot(self): def plot(w, h): assert_array_almost_equal(w, np.pi * np.arange(8.0) / 8) assert_array_almost_equal(h, np.ones(8)) assert_raises(ZeroDivisionError, freqz, [1.0], worN=8, plot=lambda w, h: 1 / 0) freqz([1.0], worN=8, plot=plot)
def doplot2(B, A, B2, A2, freq = (315.0/88.0) * 8.0): w, h = sps.freqz(B, A) w2, h2 = sps.freqz(B2, A2) # h.real /= C # h2.real /= C2 begin = 0 end = len(w) # end = int(len(w) * (12 / freq)) # chop = len(w) / 20 chop = 0 w = w[begin:end] w2 = w2[begin:end] h = h[begin:end] h2 = h2[begin:end] v = np.empty(len(w)) # print len(w) hm = np.absolute(h) hm2 = np.absolute(h2) v0 = hm[0] / hm2[0] for i in range(0, len(w)): # print i, freq / 2 * (w[i] / pi), hm[i], hm2[i], hm[i] / hm2[i], (hm[i] / hm2[i]) / v0 v[i] = (hm[i] / hm2[i]) / v0 fig = plt.figure() plt.title('Digital filter frequency response') ax1 = fig.add_subplot(111) v = 20 * np.log10(v ) # plt.plot(w * (freq/pi) / 2.0, v) # plt.show() # exit() plt.plot(w * (freq/pi) / 2.0, 20 * np.log10(abs(h)), 'r') plt.plot(w * (freq/pi) / 2.0, 20 * np.log10(abs(h2)), 'b') plt.ylabel('Amplitude [dB]', color='b') plt.xlabel('Frequency [rad/sample]') ax2 = ax1.twinx() angles = np.unwrap(np.angle(h)) angles2 = np.unwrap(np.angle(h2)) plt.plot(w * (freq/pi) / 2.0, angles, 'g') plt.plot(w * (freq/pi) / 2.0, angles2, 'y') plt.ylabel('Angle (radians)', color='g') plt.grid() plt.axis('tight') plt.show()
def lab5_ex4(): # define coefficient arrays b = firwin(20, 0.3) # given 10th degree polynomial a = array([1.0]) # no feedback # define quantized versions of 10th order array at Q3, Q6, Q8, Q16 (second array will always be 1.0) q3 = fix(b * 2 ** 3) * 2 ** ( -3 ) # (convert decimal into integer at N precision, then convert back into float decimal at same precision) q6 = fix(b * 2 ** 6) * 2 ** (-6) q8 = fix(b * 2 ** 8) * 2 ** (-8) q16 = fix(b * 2 ** 16) * 2 ** (-16) # define and plot full precision and quantized frequency responses on linear and dB scales w, h = freqz(b, a) subplot(211) plot(w / pi, abs(h), "k-") subplot(212) plot(w / pi, 20 * log10(abs(h)), "k-") w, h = freqz(q3, a) subplot(211) plot(w / pi, abs(h), "b-") subplot(212) plot(w / pi, 20 * log10(abs(h)), "b-") w, h = freqz(q6, a) subplot(211) plot(w / pi, abs(h), "g-") subplot(212) plot(w / pi, 20 * log10(abs(h)), "g-") w, h = freqz(q8, a) subplot(211) plot(w / pi, abs(h), "c-") subplot(212) plot(w / pi, 20 * log10(abs(h)), "c-") w, h = freqz(q16, a) subplot(211) plot(w / pi, abs(h), "r-") legend(("full precision", "Q3", "Q6", "Q8", "Q16")) title("freq responses of 10th order filter by quantization and scale") ylabel("linear scale") subplot(212) plot(w / pi, 20 * log10(abs(h)), "r-") legend(("full precision", "Q3", "Q6", "Q8", "Q16"), loc=3) ylabel("dB scale") xlabel("normalized frequency") show() print ( "\nFilter's responses are quite different depending on the number of bits used for quantization. When using 3 bits especially, the filter's response is markedly different from it's response to the full precision signal. We can clearly see this effect on the dB scale, where it looks as if the number of bits available for quantization corresponds to the number of zeros/poles in the transfer function." )
def butterfilt(data, sr, passband=(1.0, 50.0), stopband=(59., 61.), order=(5, 5), plotfreqz=False, plotlim=100): """Wrapper for Butterworth filter of sample*channel*trial EEG data Inputs: data - sample*channel*trial EEG data sr - sample rate (samps/sec) Optional Inputs: passband - low and high cutoffs for Butterworth passband stopband - low and high cuttoffs for Butterworth stopband Note that this should be used as a Notch filter For countries w/ 60 Hz power lines (Americas etc.) use (59., 61.) For countries w/ 50 Hz power lines (everywhere else) use (49., 51.) order - Order of both Butterworth filters: (passband, stopband) plotfreqz - Flag for plotting frequency responses of both filters plotlim - Upper limit of frequencies to plot Outputs: filtdata - Filtered sample*channel*trial EEG data """ nyquist = .5 * float(sr) b, a = butter(order[0], [float(passband[0]) / nyquist, float(passband[1]) / nyquist], btype='bandpass') filtdata = filtfilt(b, a, data, axis=0) if plotfreqz: w, h = freqz(b, a) plt.plot((nyquist / np.pi) * w, abs(h)) plt.setp(plt.gca(),XLim=[0,plotlim],YLim=[0,1.1]) plt.plot([0, nyquist], [np.sqrt(0.5), np.sqrt(0.5)], '--') plt.title( 'Butterworth Passband Frequency Response, Order = %d' % order[1]) if not not stopband: B, A = butter(order[1], [float(stopband[0]) / nyquist, float(stopband[1]) / nyquist], btype='bandstop') filtdata = filtfilt(B, A, data, axis=0) if plotfreqz: W, H = freqz(B, A) plt.figure() plt.plot((nyquist / np.pi) * W, abs(H)) plt.setp(plt.gca(),XLim=[0,plotlim],YLim=[0,1.1]) plt.plot([0, nyquist], [np.sqrt(0.5), np.sqrt(0.5)], '--') plt.title( 'Butterworth Stopband Frequency Response, Order = %d' % order[1]) return filtdata
def output_freqz_libcrybaby(): from pluginloader import Plugin filt = Plugin("../build/default/src/plugins/libcrybaby.so") filt['crybaby2.refvolt'] = 0.1 para = 'crybaby2.hotpotz' name = filt.get_var_attr(para)[0] fs = 44100 filt.init(fs) impulse = zeros(10000,dtype=float32) impulse[0] = 1 rg = log10(linspace(*np.power(10,filt.get_range(para)), num=20)) if False: aa, Q, maxh, p1, Bconst, freq_const = estimate(rg, filt, para, impulse, fs) pickle.dump((aa,Q,maxh,p1,Bconst,freq_const), file("p.out","w")) else: aa, Q, maxh, p1, Bconst, freq_const = pickle.load(file("p.out")) z1, z2A, z3A, gcA = estimate_SR(filt, para, freq_const, impulse) off, a1A, qA = fit_param(rg, aa, Q, fs) gain, g_off, gA = make_gain(rg, off, a1A, qA, maxh, p1, Bconst, fs) #show_param(rg, off, g_off, aa, a1A, Q, qA, gain, gA) rg = log10(linspace(*np.power(10,filt.get_range(para)), num=10)) filt.init(fs) for i, freq in enumerate(rg): filt[para] = freq filt.compute(zeros(10000,dtype=float32)) w, h = freqz(filt.compute(impulse), worN=15000) q = polyval(qA, freq) a1 = (off - 1 / polyval(a1A, freq)) / fs g = g_off - 1 / polyval(gA, freq) gc = polyval(gcA, fs) r = 1 - a1/(2*q) A = array((1, -2*r*cos(a1), r*r)) A = poly(list(roots(A))+[p1]) B = poly([polyval(z2A,fs),polyval(z3A,fs),z1]) w1, h1 = freqz(B*g*gc, A, worN=15000) semilogx((w*fs/(2*pi))[1:], 20*log10(abs(h[1:])), "b") semilogx((w1*fs/(2*pi))[1:], 20*log10(abs(h1[1:])), "r") print "theta2pi = (%g - 1000 / (%s)) / SR;" % (off, string_polyval(a1A*1000, "wah")) print "Q = %s;" % string_polyval(qA, "wah") print "g = %g - 1 / (%s);" % (g_off, string_polyval(gA, "wah")) print "gc = %s;" % string_polyval(gcA, "SR") print "p1 = exp(-1000/(%g*SR));" % (-1000/(fs*log(p1))) print "z1 = %g;" % z1 print "z2 = %s;" % string_polyval(z2A, "SR") print "z3 = %s;" % string_polyval(z3A, "SR") show()
def fourier(self,List=None,fs=1): if type(List) is list: indices=self.getInds(List=List) if 0 not in indices: List.append((0,0)) domain=[int(self.getDom(List=List)[0]),int(self.getDom(List=List)[1])] for i in range(domain[0],domain[1]+1,1): if i not in indices: List.append((i,0)) indices=self.getInds(List=List) values=self.getVals(List=List) f_indices,f_values=freqz(values,indices,worN=2000) f_indices=f_indices*(fs * 0.5 / np.pi) f_List=[] f_indices=list(f_indices) values_copy=f_values.copy() values_copy=list(values_copy) f_values=list(f_values) i=0 for value in f_values: f_List.append((f_indices[i],float(np.real(f_values[i])))) i=i+1 return f_List else: List=self.points indices=self.getInds(List=List) if 0 not in indices: List.append((0,0)) domain=[int(self.getDom(List=List)[0]),int(self.getDom(List=List)[1])] for i in range(domain[0],domain[1]+1,1): if i not in indices: List.append((i,0)) indices=self.getInds(List=List) values=self.getVals(List=List) f_indices,f_values=freqz(values,indices,worN=2000) f_indices=f_indices*(fs * 0.5 / np.pi) f_List=[] f_indices=list(f_indices) values_copy=f_values.copy() values_copy=list(values_copy) f_values=list(f_values) i=0 for value in f_values: f_List.append((f_indices[i],float(np.real(f_values[i])))) i=i+1 return f_List
def iir_bandstops(fstops, fs, order=4): """ellip notch filter fstops is a list of entries of the form [frequency (Hz), df, df2] where df is the pass width and df2 is the stop width (narrower than the pass width). Use caution if passing more than one freq at a time, because the filter response might behave in ways you don't expect. """ nyq = 0.5 * fs # Zeros zd, poles pd, and gain kd for the digital filter zd = np.array([]) pd = np.array([]) kd = 1 # Notches for fstopData in fstops: fstop = fstopData[0] df = fstopData[1] df2 = fstopData[2] low = (fstop - df) / nyq high = (fstop + df) / nyq low2 = (fstop - df2) / nyq high2 = (fstop + df2) / nyq z, p, k = iirdesign([low,high], [low2,high2], gpass=1, gstop=6, ftype='ellip', output='zpk') zd = np.append(zd,z) pd = np.append(pd,p) # Set gain to one at 100 Hz...better not notch there bPrelim,aPrelim = zpk2tf(zd, pd, 1) outFreq, outg0 = freqz(bPrelim, aPrelim, 100/nyq) # Return the numerator and denominator of the digital filter b,a = zpk2tf(zd,pd,k) return b, a
def frequency_response(self, n=10000): """ Generate a filter frequency response from a set of filter taps. Returns plottable (x, y) with respect to an actual sampling rate """ w, h = signal.freqz(self.b, self.a, worN=n) return (0.5 * self.fs * w / np.pi, np.abs(h))
def plot_filter_characteristics(self): w, h = freqz(self.freq_filter.num, self.freq_filter.denom) plt.figure(1) plt.subplot(2,1,1) plt.hold(True) powa = plt.plot((self.filter_parameters.sample_rate*0.5/pi)*w, abs(h),'b-', label = 'Char. amplitudowa') plt.title('Charakterystyki filtru') plt.xlabel('Czestotliwosc [Hz]') plt.ylabel('Amplituda') plt.twinx(ax=None) angles = unwrap(angle(h)) plt.znie = plot((self.filter_parameters.sample_rate*0.5/pi)*w,angles, 'g-', label = 'Char. fazowa') plt.ylabel('Faza') plt.grid() tekst = powa + znie wybierz = [l.get_label() for l in tekst] plt.legend(tekst, wybierz, loc='best') ######################################################################################################################## plt.subplot(2,1,2) w2, gd = group_delay((num, denom)) plt.plot((sample_rate*0.5/pi)*w2, gd) plt.grid() plt.xlabel('Czestotliwosc [Hz]') plt.ylabel('Opoznienie grupowe [probki]') plt.title('Opoznienie grupowe filtru') plt.show()
def __init__(self, fir_len, fir_bits, tb_width): tb_ctr = 1/(2*4) pass_corner = tb_ctr - (tb_ctr*tb_width/2) stop_corner = tb_ctr + (tb_ctr*tb_width/2) fir_bands = [0, pass_corner, stop_corner, 0.5] b = signal.remez(fir_len, fir_bands, [1, 0]) coeff_scl = 2**(fir_bits-1) self.fir_coeff = np.floor(b*coeff_scl + 0.5) # Dump Coefficients? if 1: write_meminit("fir4dec_coeff.v", self.fir_coeff) self.fir_coeff = self.fir_coeff/coeff_scl; # plot FIR response? if 1: W, H = signal.freqz(self.fir_coeff) plt.figure() plt.plot(W/(2*np.pi), 20*np.log10(np.abs(H))) plt.grid() plt.xlabel("Freq (normalized)") plt.ylabel("dB") plt.title("fir4dec response (close to continue sim)") plt.show()
def filter_VE(data): f=np.linspace(0,1,50000) a = np.ones(50000) #Switching power supply frequency (~290 KHz) a[2850:2950] =0 #1.49 MHz a[14850:14950]=0 #AM 1.37 MHz a[13650:13750] = 0 #80 m Ham band (3.97 MHz) a[39650:39750] = 0 #80 m Ham band (4 MHz) a[39950:40050]= 0 a[-1]=0 b=sigs.firwin2(3000,f,a) [h, fpoints] = sigs.freqz(b, 1, 50000,10E6) #Run the FIR filter vec = sigs.lfilter(b,1,data) return vec
def main(): edges = [30, 60, 120, 240] corners = zip(edges[:-1], edges[1:]) centres = [(a + b) / 2 for a, b in corners] #c = [get_linkwitz_riley_coeffs(1, b, a, edges[-1] * 2) for b, a in corners] sr = 2000 c = [get_peak_coeffs(-24, i, sr, 1) for i in centres] c.append([[1, 0, 0], [1, 0, 0]]) bm = [BiquadMemory(0, 0) for _ in c] bc = [BiquadCoefficients(b0, b1, b2, a1, a2) for [b0, b1, b2], [a0, a1, a2] in c] c.append(series_coeffs(c)) # c.append(impedance_filter(c[-1])) wh = [signal.freqz(b, a) for b, a in c] plt.subplot(111) plt.title("Frequency response - reflection filter") for w, h in wh: plt.semilogx(w, 20 * np.log10(np.abs(h))) plt.ylabel('Amplitude Response (dB)') plt.xlabel('Frequency (rad/sample)') plt.grid() plt.show()
def test_hilbert(self): N = 11 # number of taps in the filter a = 0.1 # width of the transition band # design an unity gain hilbert bandpass filter from w to 0.5-w h = remez(11, [a, 0.5-a], [1], type='hilbert') # make sure the filter has correct # of taps assert_(len(h) == N, "Number of Taps") # make sure it is type III (anti-symmetric tap coefficients) assert_array_almost_equal(h[:(N-1)//2], -h[:-(N-1)//2-1:-1]) # Since the requested response is symmetric, all even coeffcients # should be zero (or in this case really small) assert_((abs(h[1::2]) < 1e-15).all(), "Even Coefficients Equal Zero") # now check the frequency response w, H = freqz(h, 1) f = w/2/np.pi Hmag = abs(H) # should have a zero at 0 and pi (in this case close to zero) assert_((Hmag[[0, -1]] < 0.02).all(), "Zero at zero and pi") # check that the pass band is close to unity idx = np.logical_and(f > a, f < 0.5-a) assert_((abs(Hmag[idx] - 1) < 0.015).all(), "Pass Band Close To Unity")
def test_firls(self): N = 11 # number of taps in the filter a = 0.1 # width of the transition band # design a halfband symmetric low-pass filter h = firls(11, [0, a, 0.5-a, 0.5], [1, 1, 0, 0], fs=1.0) # make sure the filter has correct # of taps assert_equal(len(h), N) # make sure it is symmetric midx = (N-1) // 2 assert_array_almost_equal(h[:midx], h[:-midx-1:-1]) # make sure the center tap is 0.5 assert_almost_equal(h[midx], 0.5) # For halfband symmetric, odd coefficients (except the center) # should be zero (really small) hodd = np.hstack((h[1:midx:2], h[-midx+1::2])) assert_array_almost_equal(hodd, 0) # now check the frequency response w, H = freqz(h, 1) f = w/2/np.pi Hmag = np.abs(H) # check that the pass band is close to unity idx = np.logical_and(f > 0, f < a) assert_array_almost_equal(Hmag[idx], 1, decimal=3) # check that the stop band is close to zero idx = np.logical_and(f > 0.5-a, f < 0.5) assert_array_almost_equal(Hmag[idx], 0, decimal=3)
def freq_response(b, a=1., n_freqs=1024, sides='onesided'): """ Returns the frequency response of the IIR or FIR filter described by beta and alpha coefficients. Parameters ---------- b : beta sequence (moving average component) a : alpha sequence (autoregressive component) n_freqs : size of frequency grid sides : {'onesided', 'twosided'} compute frequencies between [-PI,PI), or from [0, PI] Returns ------- fgrid, H(e^jw) Notes ----- For a description of the linear constant-coefficient difference equation, see http://en.wikipedia.org/wiki/Z-transform """ # transitioning to scipy freqz real_n = n_freqs // 2 + 1 if sides == 'onesided' else n_freqs return sig.freqz(b, a=a, worN=real_n, whole=sides != 'onesided')
def highpass(signal, Fs, fc=constants.fc_hp, plot=False): ''' Filter out the really low frequencies, default is below 50Hz ''' # have some predefined parameters rp = 5 # minimum ripple in dB in pass-band rs = 60 # minimum attenuation in dB in stop-band n = 4 # order of the filter type = 'butter' # normalized cut-off frequency wc = 2. * fc / Fs # design the filter from scipy.signal import iirfilter, lfilter, freqz b, a = iirfilter(n, Wn=wc, rp=rp, rs=rs, btype='highpass', ftype=type) # plot frequency response of filter if requested if (plot): import matplotlib.pyplot as plt w, h = freqz(b, a) plt.figure() plt.title('Digital filter frequency response') plt.plot(w, 20 * np.log10(np.abs(h))) plt.title('Digital filter frequency response') plt.ylabel('Amplitude Response [dB]') plt.xlabel('Frequency (rad/sample)') plt.grid() # apply the filter signal = lfilter(b, a, signal.copy()) return signal
def _filter_resp(b, a, sampling_rate=1000., nfreqs=512): """Compute the filter frequency response. Parameters ---------- b : array Numerator coefficients. a : array Denominator coefficients. sampling_rate : int, float, optional Sampling frequency (Hz). nfreqs : int, optional Number of frequency points to compute. Returns ------- freqs : array Array of frequencies (Hz) at which the response was computed. resp : array Frequency response. """ w, resp = ss.freqz(b, a, nfreqs) # convert frequencies freqs = w * sampling_rate / (2. * np.pi) return freqs, resp
def plot_response(self, filename=None): """ Plot frequency response. .. note:: The follow phase response is obtained in case :meth:`lfilter` is used. The method :meth:`filtfilt` results in a zero-phase response. """ fs = self.sample_frequency fig = plt.figure() ax1 = fig.add_subplot(211) ax2 = fig.add_subplot(212) for f, fc in zip(self.filters, self.frequencies.center): w, h = freqz(f[0], f[1], int(fs/2))#np.arange(fs/2.0)) ax1.semilogx(w / (2.0*np.pi) * fs, 20.0 * np.log10(np.abs(h)), label=str(int(fc))) ax2.semilogx(w / (2.0*np.pi) * fs, np.angle(h), label=str(int(fc))) ax1.set_xlabel(r'$f$ in Hz') ax1.set_ylabel(r'$|H|$ in dB re. 1') ax2.set_xlabel(r'$f$ in Hz') ax2.set_ylabel(r'$\angle H$ in rad') ax1.legend(loc=5) ax2.legend(loc=5) ax1.set_ylim(-60.0, +10.0) if filename: fig.savefig(filename) else: return fig
def lock(self, f0=None, bw_ratio=0.5, coeff_ratio=9., bw=None, coeffs=None, window='blackman'): """Standard, windowed finite impulse response filter. """ t = self.t fs = self.fs if f0 is None: self.f0 = f0 = self.f0_est else: self.f0 = f0 if bw is None: bw = bw_ratio * f0 / (self.fs/2) else: bw = bw / (self.fs/2) if coeffs is None: coeffs = round(coeff_ratio / bw, 0) if coeffs > self.x.size: raise ValueError( """No valid output when 'coeffs' > t.size (coeffs: {}, t.size: {}). Reduce coeffs by increasing bw, bw_ratio, or decreasing coeff_ratio, or provide more data.""".format(coeffs, t.size)) self.fir = b = signal.firwin(coeffs, bw, window=window) w, rep = signal.freqz(b, worN=np.pi*np.array([0., bw/2, bw, f0/self.fs, f0/(self.fs/2.), 1.])) print("Response:") _print_magnitude_data(w, rep, fs) self.run(f0=f0)
def lock_butter(self, N, f3dB, t_exclude=0, f0=None, print_response=True): t = self.t fs = self.fs nyq = fs / 2. f3dB = f3dB / nyq self.iir = ba = signal.iirfilter(N, f3dB, btype='low') if f0 is None: self.f0 = f0 = self.f0_est self.z = z = signal.lfilter(self.iir[0], self.iir[1], self.z) # TODO: Fix accounting on final / initial point m = self.m self.m = self.m & (t >= (t[m][0] + t_exclude)) & (t < (t[m][-1] - t_exclude)) self.A = abs(self.z) self.phi = np.angle(self.z) if print_response: w, rep = signal.freqz(self.iir[0], self.iir[1], worN=np.pi*np.array([0., f3dB/2, f3dB, 0.5*f0/nyq, f0/nyq, 1.])) print("Response:") _print_magnitude_data(w, rep, fs)
def lab3_ex4(): # assign pre-defined (arbitrary) variables To = 125.0*(10**-6) #signal period = 125 microseconds L = 1*(10**-6) #inductance = 1 microHenry C = 4*(10**-6) #capacitance = 4 microFarads # calculate oscillator frequency Fo = 1/To print("\nAssuming signal period is is 125 microseconds, oscillator frequency is 1/T:\n" + str(Fo) + " Hz") # calculate sampling frequency (should be at least 2x, but using 10x here since best practice) and sample period Fs = Fo*10 Ts = 1/Fs # assign pre-defined variables and their functional relationship to a constant 'm' m = ((2*L*C)-(Ts**2)/(L*C)) # describe system as a difference equation print("\nDescribing the system as a difference equation, we have:\n y[n] = m*y[n-1] - y[n-2] \nwhere m = (2*L*C-Ts^2)/(L*C)") print("\nor:\n a0*y[n] = b0*x[n] - a1*y[n-1] - a2*y[n-2]\nwhere b0 = 1.0, a0 = 1.0, a1 = -m, and a2 = 1.0") # create input from unit impulse function index = arange(0,10*Ts,Ts) x = unit_impulse(index) # assign coefficient arrays for input b = array([1.0]) a = array([1.0, -1.0*m, 1.0]) y = lfilter(b, a, x) # format and plot graph of unit impulse response stem(index, y) grid() xlabel('n (sampling period = 12.5 microseconds)') ylabel('Impulse response') title('Impulse response of a discrete LC system') print "\nIf sampling period Ts = 12.5 microseconds, Inductance L = 1 microHenry, and capacitance C = 4 microFarads, then" print "m = ((2*L*C)-(Ts**2)/(L*C)) = " + str(m) print "\nand impulse response y[n] for 1st 10 sampling periods (beginning with y[0]) = " + str(y) show() # calculate and assign angular frequency response using system coefficients w,h = freqz(b,a) #w = sample frequency array, h = frequency response array # format and plot graph of frequency response by sample frequency plot(w/pi*(Fs/2), abs(h)) grid() xlabel('Frequency (Hz)') ylabel('Amplitude') title('Frequency response of a discrete LC system') show()
def doplot(B, A, freq = (315.0/88.0) * 8.0): w, h = sps.freqz(B, A) fig = plt.figure() plt.title('Digital filter frequency response') db = 20 * np.log10(abs(h)) for i in range(1, len(w)): if (db[i] >= -10) and (db[i - 1] < -10): print(">-10db crossing at ", w[i] * (freq/pi) / 2.0) if (db[i] >= -3) and (db[i - 1] < -3): print(">-3db crossing at ", w[i] * (freq/pi) / 2.0) if (db[i] < -3) and (db[i - 1] >= -3): print("<-3db crossing at ", w[i] * (freq/pi) / 2.0) ax1 = fig.add_subplot(111) plt.plot(w * (freq/pi) / 2.0, 20 * np.log10(abs(h)), 'b') plt.ylabel('Amplitude [dB]', color='b') plt.xlabel('Frequency [rad/sample]') ax2 = ax1.twinx() angles = np.unwrap(np.angle(h)) plt.plot(w * (freq/pi) / 2.0, angles, 'g') plt.ylabel('Angle (radians)', color='g') plt.grid() plt.axis('tight') plt.show()
def dosplot(B, A, freq = (315.0/88.0) * 8.0): w, h = sps.freqz(B, A) fig = plt.figure() plt.title('Digital filter frequency response') ax1 = fig.add_subplot(111) db = 20 * np.log10(abs(h)) for i in range(1, len(w)): if (db[i] >= -10) and (db[i - 1] < -10): print(">-10db crossing at ", w[i] * (freq/pi) / 2.0) if (db[i] >= -3) and (db[i - 1] < -3): print("-3db crossing at ", w[i] * (freq/pi) / 2.0) if (db[i] < -3) and (db[i - 1] >= -3): print("<-3db crossing at ", w[i] * (freq/pi) / 2.0) if (db[i] < -10) and (db[i - 1] >= -10): print("<-10db crossing at ", w[i] * (freq/pi) / 2.0) if (db[i] < -20) and (db[i - 1] >= -20): print("<-20db crossing at ", w[i] * (freq/pi) / 2.0) plt.plot(w * (freq/pi) / 2.0, 20 * np.log10(abs(h)), 'b') plt.ylabel('Amplitude [dB]', color='b') plt.xlabel('Frequency [rad/sample]') plt.show()
x1 = -1 x2 = 1 dx = (x2 - x1) / (nw - 1) w = zeros(nw) for i in range(nw): w[i] = 2.0 * pi * pow(10, x1 + i * dx) [win, h] = signal.freqs(b, a, w) hr = real(h) hi = imag(h) for i in range(len(h)): print(" href1[%d] = std::complex<double> (%+.14lf,%+.14lf);" % (i, hr[i], hi[i])) nw = 41 f = linspace(0, pi, nw) bz = asarray([ 0.056340000000000, -0.000935244000000, -0.000935244000000, 0.056340000000000 ]) az = asarray([ 1.000000000000000, -2.129100000000000, 1.783386300000000, -0.543463100000000 ]) [fin, hz] = signal.freqz(bz, az, f) hr = real(hz) hi = imag(hz) for i in range(len(fin)): print(" href2[%d] = std::complex<double> (%+.14lf,%+.14lf);" % (i, hr[i], hi[i]))
def generate_third_stage(header, body, third_stage_configs, combined_response, points, input_sample_rate, stop_band_atten): max_coefs_per_phase = 32 for config in third_stage_configs: divider = config[0] passband = config[1] stopband = config[2] name = config[3] coefs_per_phase = config[4] #if is_custom then use the PDM rate for making the graphs is_custom = config[5] pbw = passband / divider sbw = stopband / divider a = [1, 1, 0] w = [1, 1, 1] thing1 = (00.0 / 48000.0) / divider thing2 = (200.0 / 48000.0) / divider bands = [0, 0, thing2, pbw, sbw, 0.5] third_stage_response, coefs = generate_stage( coefs_per_phase * divider, bands, a, w, stopband_attenuation=stop_band_atten) #ensure the there is never any overflow coefs /= sum(abs(coefs)) body.write("const int g_third_stage_" + name + "_fir[" + str(divider * (2 * max_coefs_per_phase - 1)) + "] = {\n") header.write("extern const int g_third_stage_" + name + "_fir[" + str(divider * (2 * max_coefs_per_phase - 1)) + "];\n") total_abs_sum = 0 for phase in reversed(range(divider)): body.write("//Phase " + str(phase) + "\n\t") for i in range(coefs_per_phase): index = coefs_per_phase * divider - divider - (i * divider - phase) if coefs[i] > 0.5: print "Single coefficient too big in third stage FIR" d_int = int(coefs[index] * 2147483647.0 * 2.0) total_abs_sum += abs(d_int) body.write("0x{:08x}, ".format(ctypes.c_uint(d_int).value)) if (i % 8) == 7: body.write("\n\t") for i in range(coefs_per_phase, max_coefs_per_phase): body.write("0x{:08x}, ".format(ctypes.c_uint(0).value)) if (i % 8) == 7: body.write("\n\t") for i in range(coefs_per_phase - 1): index = coefs_per_phase * divider - divider - (i * divider - phase) d_int = int(coefs[index] * 2147483647.0 * 2.0) body.write("0x{:08x}, ".format(ctypes.c_uint(d_int).value)) if (i % 8) == 7: body.write("\n\t") for i in range(coefs_per_phase - 1, max_coefs_per_phase - 1): body.write("0x{:08x}, ".format(ctypes.c_uint(0).value)) if (i % 8) == 7: body.write("\n\t") body.write("\n") body.write("};\n") #print str(total_abs_sum) + "(" + str(abs(total_abs_sum - 2147483647.0*2.0)) + ")" if abs(total_abs_sum - 2147483647.0 * 2.0) > 32 * divider: print "Warning: error in third stage too large" body.write("const int fir3_" + name + "_debug[" + str(max_coefs_per_phase * divider) + "] = {\n\t") header.write("extern const int fir3_" + name + "_debug[" + str(max_coefs_per_phase * divider) + "];\n") for i in range(coefs_per_phase * divider): body.write("{:10d}, ".format(int(2147483647.0 * coefs[i]))) if (i % 8) == 7: body.write("\n\t") for i in range(coefs_per_phase * divider, max_coefs_per_phase * divider): body.write("{:10d}, ".format(int(0))) if (i % 8) == 7: body.write("\n\t") body.write("};\n") (_, H) = signal.freqz(coefs, worN=points) plot_response(H, 'third_stage_' + str(name)) passband_max = float('-inf') passband_min = float('inf') magnitude_response = [] input_freq = [] for i in range(points): mag = combined_response[i] * abs(H[i]) freq = 0.5 * i / points if freq < 0.5 / divider: magnitude_response.append(mag) if is_custom: input_freq.append(freq * input_sample_rate) else: input_freq.append(freq * divider) if freq < passband / divider: passband_max = max(passband_max, mag) passband_min = min(passband_min, mag) magnitude_response /= passband_max magnitude_response = 20 * numpy.log10(magnitude_response) plt.clf() plt.plot(input_freq, magnitude_response) plt.ylabel('Magnitude Response') if is_custom: plt.xlabel('Frequency (kHz)') else: plt.xlabel('Normalised Output Freq') plt.savefig("output_" + name + '.pdf', format='pdf', dpi=1000) print "Filter name: " + name print "Final stage divider: " + str(divider) print "Output sample rate: " + str(input_sample_rate / divider) + "kHz" print "Pass bandwidth: " + str( input_sample_rate * passband / divider) + "kHz of " + str( input_sample_rate / (divider * 2)) + "kHz total bandwidth." print "Pass bandwidth(normalised): " + str( passband * 2) + " of Nyquist." print "Stop band start: " + str( input_sample_rate * stopband / divider) + "kHz of " + str( input_sample_rate / (divider * 2)) + "kHz total bandwidth." print "Stop band start(normalised): " + str( stopband * 2) + " of Nyquist." print "Stop band attenuation: " + str(stop_band_atten) + "dB." # print "(3.072MHz) Passband:" + str(48000*2*passband/divider) + "Hz Stopband:"+ str(48000*2*stopband/divider) + "Hz" # print "(2.822MHz) Passband:" + str(44100*2*passband/divider) + "Hz Stopband:"+ str(44100*2*stopband/divider) + "Hz" if 1.0 / passband_max > 8.0: print "Error: Compensation factor is too large" #The compensation factor should be in Q(5.27) format comp_factor = ((1 << 27) - 1) / passband_max header.write("#define FIR_COMPENSATOR_" + name.upper() + " (" + str(int(comp_factor)) + ")\n") header.write("\n") print "Passband ripple = " + str( abs(20.0 * numpy.log10(passband_min / passband_max))) + " dB\n" return
def freqz_resp_list(b, a=np.array([1]), mode='dB', fs=1.0, Npts=1024, fsize=(6, 4)): """ A method for displaying digital filter frequency response magnitude, phase, and group delay. A plot is produced using matplotlib freq_resp(self,mode = 'dB',Npts = 1024) A method for displaying the filter frequency response magnitude, phase, and group delay. A plot is produced using matplotlib freqz_resp(b,a=[1],mode = 'dB',Npts = 1024,fsize=(6,4)) b = ndarray of numerator coefficients a = ndarray of denominator coefficents mode = display mode: 'dB' magnitude, 'phase' in radians, or 'groupdelay_s' in samples and 'groupdelay_t' in sec, all versus frequency in Hz Npts = number of points to plot; default is 1024 fsize = figure size; defult is (6,4) inches Mark Wickert, January 2015 """ if type(b) == list: # We have a list of filters N_filt = len(b) f = np.arange(0, Npts) / (2.0 * Npts) for n in range(N_filt): w, H = signal.freqz(b[n], a[n], 2 * np.pi * f) if n == 0: plt.figure(figsize=fsize) if mode.lower() == 'db': plt.plot(f * fs, 20 * np.log10(np.abs(H))) if n == N_filt - 1: plt.xlabel('Frequency (Hz)') plt.ylabel('Gain (dB)') plt.title('Frequency Response - Magnitude') elif mode.lower() == 'phase': plt.plot(f * fs, np.angle(H)) if n == N_filt - 1: plt.xlabel('Frequency (Hz)') plt.ylabel('Phase (rad)') plt.title('Frequency Response - Phase') elif (mode.lower() == 'groupdelay_s') or (mode.lower() == 'groupdelay_t'): """ Notes ----- Since this calculation involves finding the derivative of the phase response, care must be taken at phase wrapping points and when the phase jumps by +/-pi, which occurs when the amplitude response changes sign. Since the amplitude response is zero when the sign changes, the jumps do not alter the group delay results. """ theta = np.unwrap(np.angle(H)) # Since theta for an FIR filter is likely to have many pi phase # jumps too, we unwrap a second time 2*theta and divide by 2 theta2 = np.unwrap(2 * theta) / 2. theta_dif = np.diff(theta2) f_diff = np.diff(f) Tg = -np.diff(theta2) / np.diff(w) # For gain almost zero set groupdelay = 0 idx = pylab.find(20 * np.log10(H[:-1]) < -400) Tg[idx] = np.zeros(len(idx)) max_Tg = np.max(Tg) #print(max_Tg) if mode.lower() == 'groupdelay_t': max_Tg /= fs plt.plot(f[:-1] * fs, Tg / fs) plt.ylim([0, 1.2 * max_Tg]) else: plt.plot(f[:-1] * fs, Tg) plt.ylim([0, 1.2 * max_Tg]) if n == N_filt - 1: plt.xlabel('Frequency (Hz)') if mode.lower() == 'groupdelay_t': plt.ylabel('Group Delay (s)') else: plt.ylabel('Group Delay (samples)') plt.title('Frequency Response - Group Delay') else: s1 = 'Error, mode must be "dB", "phase, ' s2 = '"groupdelay_s", or "groupdelay_t"' print(s1 + s2)
kHz = 1000.0 # kHz # time for creating sin wave time = arange(0, 1, 1.0 / num_samples) # Create frequencies to use for Signal Processing f1 = 15000 # 15kHz f2 = 30000 # 30kHz # Create a Bandpass filter numtaps = 2048 low_cutoff = 43500 # 43.5kHz high_cutoff = 46500 # 46.5kHz nyq_rate = sampling_rate / 2 bpf = firwin(numtaps, [low_cutoff / nyq_rate, high_cutoff / nyq_rate], pass_zero=False) w, h = freqz(bpf) # Plot bandpass filter response # plt.subplot(221) # plot(w / (2 * pi), 20 * log10(abs(h))) # plt.title('FIR Bandpass Filter Response') # plt.ylabel('Magnitude (dB)') # plt.xlabel('Frequency Coefficient') class Prompt(cmd.Cmd): def do_send(self, msg): print("Sending: <", msg, ">") sock.sendto(str.encode(msg), (host, port)) def default(self, msg):
# wpass: la frecuencia de paso normalizada # wstop: la frecuencia de corte normalizada # gpass: máxima atenuación tolerable en la banda de paso (en dB) # gstop: mínima atenuación tolerable en la banda de rechazo (en dB) # rp: amplitud de ripple tolerable en las transiciones (en dB) orden, wn = sg.cheb1ord(wp=wpass, ws=wstop, gpass=3, gstop=40) [coef_numerador_b, coef_denominador_a] = sg.cheby1(N=orden, rp=3, Wn=wn, btype='lowpass', output='ba') ''' Diagrama de Bode ''' # Le pasamos la frecuencia de muestreo para que el resultado lo ponga en escala de 0 a fs/2. Si no se la pasamos, # lo devolvería normalizado y tenemos que arreglarlo luego f, h = sg.freqz(coef_numerador_b, coef_denominador_a, fs=fs) fig, ax1 = plt.subplots() ax1.set_title('Filtro Chebyshev Tipo I pasa bajos') ax1.plot(f, 20 * np.log10(abs(h))) ax1.set_xlabel('Frecuencia [Hz]') ax1.set_ylabel('Amplitud [dB]') ax1.margins(0, 0.1) ax1.grid(which='both', axis='both') ax2 = ax1.twinx() ax2.plot(f, np.unwrap(np.angle(h)), 'g') ax2.set_ylabel('Fase (rad)', color='g') senal_filtrada_ideal = filtrar_pasa_bajos_ideal(senal_ruidosa, fs, 800)
def generate_first_stage(header, body, points, pbw, sbw, first_stage_num_taps): nulls = 1.0 / 8.0 a = [1, 0, 0, 0, 0] w = [1, 1, 1, 1, 1] bands = [ 0, pbw, nulls * 1 - sbw, nulls * 1 + sbw, nulls * 2 - sbw, nulls * 2 + sbw, nulls * 3 - sbw, nulls * 3 + sbw, nulls * 4 - sbw, 0.5 ] first_stage_response, coefs = generate_stage(first_stage_num_taps, bands, a, w) #ensure the there is never any overflow coefs /= sum(abs(coefs)) total_abs_sum = 0 for t in range(0, len(coefs) / (8 * 2)): header.write("extern const int g_first_stage_fir_" + str(t) + "[256];\n") body.write("const int g_first_stage_fir_" + str(t) + "[256] = {\n\t") max_for_block = 0 for x in range(0, 256): d = 0.0 for b in range(0, 8): if (((x >> (7 - b)) & 1) == 1): d = d + coefs[t * 8 + b] else: d = d - coefs[t * 8 + b] d_int = int(d * 2147483647.0) max_for_block = max(max_for_block, d_int) body.write("0x{:08x}, ".format(ctypes.c_uint(d_int).value)) if (x & 7) == 7: body.write("\n\t") body.write("};\n\n") total_abs_sum = total_abs_sum + max_for_block * 2 #print str(total_abs_sum) + "(" + str(abs(total_abs_sum - 2147483647.0)) + ")" if abs(total_abs_sum - 2147483647.0) > 6: print "Warning: error in first stage too large" body.write("const int fir1_debug[" + str(first_stage_num_taps) + "] = {\n\n") header.write("extern const int fir1_debug[" + str(first_stage_num_taps) + "];\n") for i in range(0, len(coefs)): body.write("{:10d}, ".format(int(2147483647.0 * coefs[i]))) if ((i & 7) == 7): body.write("\n") body.write("};\n") (_, H) = signal.freqz(coefs, worN=points) plot_response(H, 'first_stage') [stop, passband_min, passband_max] = measure_stopband_and_ripple(bands, a, H) max_passband_output = int(2147483647.0 * 10.0**(passband_max / 20.0) + 1) header.write("#define FIRST_STAGE_MAX_PASSBAND_OUTPUT (" + str(max_passband_output) + ")\n") header.write("\n") return H
for i in range(2): qz.append(z[i]) qp.append(p[i]) qk.append(k) pylab.subplot2grid((2, 2), (1, 0), colspan=2) pylab.title("Frequency response") pylab.ylabel("Gain (dB)") pylab.xlabel("Frequency (Hz)") pylab.minorticks_on() pylab.grid(b=True, which='major', color='b') pylab.grid(b=True, which='minor') (b, a) = signal.zpk2tf(original_z, original_p, original_k) (w, h) = signal.freqz(b, a) pylab.plot(w * fs0 / (2 * np.pi), 20 * np.log10(h)) print("A: ") print(a) print("B: ") print(b) print("qz: ") print(qz) print("qp: ") print(qp) qb, qa = signal.zpk2tf(qz, qp, np.prod(qk)) (qw, qh) = signal.freqz(qb, qa) pylab.plot(qw * fs0 / (2 * np.pi), 20 * np.log10(qh)) pylab.show()
def preview(args): import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from scipy.io.wavfile import write as wavwrite from scipy.signal import freqz preview_dir = os.path.join(args.train_dir, 'preview') if not os.path.isdir(preview_dir): os.makedirs(preview_dir) # Load graph infer_metagraph_fp = os.path.join(args.train_dir, 'infer', 'infer.meta') graph = tf.get_default_graph() saver = tf.train.import_meta_graph(infer_metagraph_fp) # Generate or restore z_i and z_o z_fp = os.path.join(preview_dir, 'z.pkl') if os.path.exists(z_fp): with open(z_fp, 'rb') as f: _zs = pickle.load(f) else: # Sample z samp_feeds = {} samp_feeds[graph.get_tensor_by_name('samp_z_n:0')] = args.preview_n samp_fetches = {} samp_fetches['zs'] = graph.get_tensor_by_name('samp_z:0') with tf.Session() as sess: _samp_fetches = sess.run(samp_fetches, samp_feeds) _zs = _samp_fetches['zs'] # Save z with open(z_fp, 'wb') as f: pickle.dump(_zs, f) # Create labels sample_n = 20 _zs = _zs[:sample_n] _ys = np.zeros([sample_n]) for i in range(10): # one-hot vector # _ys[2 * i + 1][i] = 1 # _ys[2 * i][i] = 1 # integer labels _ys[2 * i] = 10 + i _ys[2 * i + 1] = 10 + i _ys = np.expand_dims(_ys, axis=1) # Set up graph for generating preview images feeds = {} feeds[graph.get_tensor_by_name('z:0')] = _zs feeds[graph.get_tensor_by_name('y:0')] = _ys feeds[graph.get_tensor_by_name('flat_pad:0')] = _WINDOW_LEN // 2 fetches = {} fetches['step'] = tf.train.get_or_create_global_step() fetches['G_z'] = graph.get_tensor_by_name('G_z:0') fetches['G_z_flat_int16'] = graph.get_tensor_by_name('G_z_flat_int16:0') if args.wavegan_genr_pp: fetches['pp_filter'] = graph.get_tensor_by_name( 'G/pp_filt/conv1d/kernel:0')[:, 0, 0] # Summarize G_z = graph.get_tensor_by_name('G_z_flat:0') summaries = [ tf.summary.audio('preview', tf.expand_dims(G_z, axis=0), _FS, max_outputs=1) ] fetches['summaries'] = tf.summary.merge(summaries) summary_writer = tf.summary.FileWriter(preview_dir) # PP Summarize if args.wavegan_genr_pp: pp_fp = tf.placeholder(tf.string, []) pp_bin = tf.read_file(pp_fp) pp_png = tf.image.decode_png(pp_bin) pp_summary = tf.summary.image('pp_filt', tf.expand_dims(pp_png, axis=0)) # Loop, waiting for checkpoints ckpt_fp = None while True: latest_ckpt_fp = tf.train.latest_checkpoint(args.train_dir) if latest_ckpt_fp != ckpt_fp: print('Preview: {}'.format(latest_ckpt_fp)) with tf.Session() as sess: saver.restore(sess, latest_ckpt_fp) _fetches = sess.run(fetches, feeds) _step = _fetches['step'] gen_speech = _fetches['G_z_flat_int16'] gen_len = int(len(gen_speech) / sample_n) for i in range(sample_n): label = int(i / 2) start = i * gen_len end = start + gen_len preview_fp = os.path.join( preview_dir, '{}_{}_{}.wav'.format(str(label), str(_step), str(i))) wavwrite(preview_fp, _FS, gen_speech[start:end]) summary_writer.add_summary(_fetches['summaries'], _step) if args.wavegan_genr_pp: w, h = freqz(_fetches['pp_filter']) fig = plt.figure() plt.title('Digital filter frequncy response') ax1 = fig.add_subplot(111) plt.plot(w, 20 * np.log10(abs(h)), 'b') plt.ylabel('Amplitude [dB]', color='b') plt.xlabel('Frequency [rad/sample]') ax2 = ax1.twinx() angles = np.unwrap(np.angle(h)) plt.plot(w, angles, 'g') plt.ylabel('Angle (radians)', color='g') plt.grid() plt.axis('tight') _pp_fp = os.path.join( preview_dir, '{}_ppfilt.png'.format(str(_step).zfill(8))) plt.savefig(_pp_fp) with tf.Session() as sess: _summary = sess.run(pp_summary, {pp_fp: _pp_fp}) summary_writer.add_summary(_summary, _step) print('Done') ckpt_fp = latest_ckpt_fp time.sleep(1)
def main(): t = np.arange(0, 0.01, 1 / fs) # %% noisy sinusoid xc = np.exp( 1j * 2 * np.pi * F * t) + 0.01 * (np.random.randn(t.size) + 1j * np.random.randn(t.size)) xr = np.cos(2 * np.pi * F * t) + 0.01 * np.random.randn(t.size) # %% estimate sinusoid frequency festc, sigmac = subspace.subspace.esprit_c(xc, Ntone // 2, M, fs) print('complex') print(festc) print(sigmac) # %% real # design filter coeff (offline, one-time) b = remez(L, [0, 0.1, 0.15, 0.35, 0.4, 0.5], [0, 1, 0]) tic = time() yrpy = lfilter(b, 1, xr) tscipy = time() - tic tic = time() yrfort = subspace.filters.fircircfilter(xr.astype(np.float32), b)[0] tfort = time() - tic np.testing.assert_allclose(yrfort, yrpy, rtol=1e-4) # single prec vs double prec tic = time() yr = fircirc(b, xr) print('{:.6f} sec. using circular buffer FIR filter'.format(time() - tic)) np.testing.assert_allclose(yr, yrpy) # %% estimations festr, sigmar = subspace.subspace.esprit_r(yr, Ntone, M, fs) print('real') print(festr) print(sigmar) fg, axs = subplots(2, 4, sharey=False) plotperiodogram(t, xr, fs, axs[:, 0], 'noisy input signal X') axs[0, 0].set_ylabel('amplitude [dB]') axs[1, 0].set_ylabel('amplitude') plotperiodogram(t, yrpy, fs, axs[:, 1], 'Scipy lfilter() signal, {:.3f} ms'.format(tscipy * 1000)) plotperiodogram(t, yrfort, fs, axs[:, 2], 'Fortran filtered signal, {:.3f} ms'.format(tfort * 1000)) for a in axs[0, :]: a.set_xlabel('frequency [Hz]') a.autoscale(True, axis='x', tight=True) a.set_ylim(-100, -20) freq, response = freqz(b) axs[0, -1].plot(freq * fs / (2 * np.pi), 10 * np.log10(abs(response))) axs[0, -1].set_title(f'filter response L={L}') axs[0, -1].set_ylim(-40, 2) impulse = np.repeat(0., L) impulse[0] = 1. response = lfilter(b, 1, impulse) axs[1, -1].plot(response) axs[1, -1].set_xlabel('sample number') show()
from scipy import signal import csv import matplotlib.pyplot as plt import numpy as np with open('/home/pruthvirg/Downloads/h.csv', 'r') as f: reader = csv.reader(f) your_list = list(reader) w, h = signal.freqz(your_list) fig, ax1 = plt.subplots() ax1.set_title('Digital filter frequency response') ax1.plot(w, abs(h), 'b') ax1.set_ylabel('Amplitude [dB]', color='b') ax1.set_xlabel('Frequency [rad/sample]') ax2 = ax1.twinx() angles = np.unwrap(np.angle(h)) ax2.plot(w, angles, 'g') ax2.set_ylabel('Angle (radians)', color='g') ax2.grid() ax2.axis('tight') plt.show() x = np.linspace(1, 2**10, 2**10) y = np.cos(0.2 * (np.pi) * x) + np.cos(0.85 * (np.pi) * x) plt.plot(abs(y)) plt.title('Plot of input signal') plt.xlabel('n') plt.ylabel('x[n]') plt.grid(True)
""" FIR filter design example; requires SciPy 0.9 or later. """ import numpy as np from scipy.signal import firwin2, freqz, kaiserord from matplotlib.pylab import plot, show, grid, xlabel, ylabel, legend, title # Bandpass with a notch. desired_freq = [0.0, 0.1, 0.2, 0.56, 0.6, 0.64, 0.8, 0.9, 1.0] desired_gain = [0.0, 0.0, 1.0, 1.0, 0.75, 1.0, 1.0, 0.0, 0.0] # Use firwin2 with a Kaiser window to design the filter. ntaps, beta = kaiserord(ripple=65, width=0.08) taps = firwin2(ntaps, desired_freq, desired_gain, window=('kaiser', beta)) # Compute the filter's response. w, h = freqz(taps, [1.0], worN=8000) # Plot the desired and actual responses. plot(desired_freq, desired_gain, 'g-', label='Desired') plot(w/np.pi, np.abs(h), 'b', label='Computed') xlabel('Frequency (rel. to Nyquist)') ylabel('Gain') title('FIR Filter Frequency Response (%d taps)' % ntaps) legend() grid(True) show()
f0 = 100 # fundamental pitch of excitation impulse nharm = 30 # number of harmonics in impulse nsamps = 8000 # number of samples to collect output_samples = 513 # number of samples per table (attack AND decay) table_size = 257 # length of each wavetable nsamps = output_samples * 11 # number of samples to process. offset = 10 cycles, + output fs = output_samples * f0 # sample rate nsecs = F.size R = np.exp(-np.pi * BW / fs) theta = 2 * np.pi * F / fs poles = np.multiply(R, np.exp(1j * theta)) # complex poles B = 1 polesMatrix = np.matrix([poles, np.conj(poles)]) A = np.real(np.poly(polesMatrix.A1)) w, h = signal.freqz(B, A) """ # plot formant filter frequency response freqPlot = plt.figure(); plt.title('Formant Filter Frequency Response') ax1 = freqPlot.add_subplot(111) plt.plot(w, 20 * np.log10(abs(h)), 'b') plt.ylabel('amplitude[dB]', color = 'b') plt.xlabel('frequency [rad/sample]') ax2 = ax1.twinx() angles = np.unwrap(np.angle(h)) plt.plot(w, angles, 'g') plt.ylabel('Angle (radians)', color='g') plt.grid()
import sys sys.path.append('../funcs') from animations import * from filters import * from playwav import * rate, audio = wav.read('sndfile.wav') audio = audio[:, 1] t = np.arange(len(audio)) / float(rate) print 'Sampling rate: ', rate print 'Audio shape: ', audio.shape w, H = signal.freqz(audio) #filter and downsample the signal no 8khz # newSamplingRate = 8000 # downSamplingFactor = rate/newSamplingRate samplingFactor = 4 rows = 500 cols = 512 frame = 0.0 * np.ones((rows, cols, 3)) frametxt = frame.copy() cv2.putText(frame, "f: change filter", (20, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 128, 128)) cv2.putText(frame, "p: play audio file, s: stop", (20, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 128, 128))
if voiced[i]: # choose alpha and gamma to get something like voiced speech alpha1 = 0.05 * np.pi + 0.25 * np.pi * r1[0] gamma1 = 0.9 + 0.09 * r1[1] alpha2 = alpha1 + 0.4 * np.pi * r2[0] gamma2 = 0.9 + 0.05 * r2[1] gain = 10 else: alpha1 = 0.5 * np.pi + 0.4 * np.pi * r1[0] gamma1 = 0.8 + 0.1 * r1[1] alpha2 = 0.5 * np.pi + 0.4 * np.pi * r2[0] gamma2 = 0.8 + 0.1 * r2[1] gain = 1 w1, h1 = signal.freqz(gain, [1, -2 * gamma1 * np.cos(alpha1), gamma1 * gamma1], range(1, L[i] + 1) * Wo[i]) w2, h2 = signal.freqz(gain, [1, -2 * gamma2 * np.cos(alpha2), gamma2 * gamma2], range(1, L[i] + 1) * Wo[i]) for m in range(1, L[i] + 1): A[i, m] = np.abs(h1[m - 1] * h2[m - 1]) if voiced[i]: phase[i, m] = np.angle(h1[m - 1] * h2[m - 1]) else: r = np.random.rand(1) phase[i, m] = -np.pi + r[0] * 2 * np.pi # write to a Codec 2 model file
adc = fx.Fixed(q_adc) # adc quantizer instance fil_ma_q = fx.FIX_filt_MA(q_mul, q_acc) # fxpoint filter instance dac = fx.Fixed(q_dac) # dac quantizer instance coeffq = fx.Fixed(q_coeff) ### quantize coefficients aq = coeffq.fix(a) bq = coeffq.fix(b) gq = coeffq.fix(g) if coeffq.N_over > 0: print("Coefficient overflows:", coeffq.N_over) ### Berechnung der Übertragungsfunktion mit idealen und quantisierten Koeff. # idealer Betragsgang [w, Hf] = sig.freqz(b, a, worN=int(N_FFT / 2)) Hf = abs( Hf ) * g * a_sig # Idealer Betragsgang zwischen f = 0 ... f_S/2 an N_FFT/2 Punkten f = w / (2 * pi) * f_S # translate w to absolute frequencies # Betragsgang mit quantisierten Koeffizienten [w, Hfq] = sig.freqz(bq, aq, int(N_FFT / 2)) Hfq = abs(Hfq) * gq * a_sig wtest = array( [fsig, f_S / 2] ) * 2 * pi / f_S # Testfrequenzen f_sig und f_S/2 (dummy-Punkt, ftest muss Vektor sein) w, H_sig_tst = sig.freqz(b, a, wtest) # Betrag der Übertragungsfunkt. bei ftest H_sig = abs(H_sig_tst[0]) * g * a_sig # Ideale Übertragungsfunktion bei fsig
def butter_bandpass_filter_signal_1d(signal, lowcut, highcut, sample_rate, order, verbose=False): r""" Digital filter bandpass zero-phase implementation (filtfilt) Apply a digital filter forward and backward to a signal Args: signal : ndarray, shape (time,) Single input signal in time domain lowcut : int Lower bound filter highcut : int Upper bound filter sample_rate : int Sampling frequency order : int, default: 4 Order of the filter verbose : boolean, default: False Print and plot details Returns: y : ndarray Filter signal Dependencies: filtfilt : scipy.signal.filtfilt butter_bandpass : function plt : `matplotlib.pyplot` package freqz : scipy.signal.freqz fast_fourier_transform : function """ b, a = butter_bandpass(lowcut, highcut, sample_rate, order) y = filtfilt(b, a, signal) if verbose: w, h = freqz(b, a) plt.plot((sample_rate * 0.5 / np.pi) * w, abs(h), label="order = %d" % order) plt.plot([0, 0.5 * sample_rate], [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') low = max(0, lowcut - (sample_rate / 100)) high = highcut + (sample_rate / 100) plt.xlim([low, high]) plt.ylim([0, 1.2]) plt.title('Frequency response of filter - lowcut:' + str(lowcut) + ', highcut:' + str(highcut)) plt.show() # TIME plt.plot(signal, label='Signal') plt.title('Signal') plt.show() plt.plot(y, label='Filtered') plt.title('Bandpass filtered') plt.show() # FREQ lower_xlim = lowcut - 10 if (lowcut - 10) > 0 else 0 fast_fourier_transform(signal, sample_rate, plot=True, plot_xlim=[lower_xlim, highcut + 20], plot_label='Signal') fast_fourier_transform(y, sample_rate, plot=True, plot_xlim=[lower_xlim, highcut + 20], plot_label='Filtered') plt.xlim([lower_xlim, highcut + 20]) plt.ylim([0, 2]) plt.legend() plt.xlabel('Frequency (Hz)') plt.show() print('Input: Signal shape', signal.shape) print('Output: Signal shape', y.shape) return y
def filtfft(filt, blocklen): return sps.freqz(filt[0], filt[1], blocklen, whole=1)[1]
plt.savefig('../images/Q1_b_espectro_nfilt.png') # Questão 2 # (a) if PB_filt: lp_fpass = 32. lp_fstop = 50.3 fny = fs/2. #wpass = fpass*2*np.pi #wstop = fstop*2*np.pi #wny = fny*2*np.pi lp_ord, lp_wn = buttord(lp_fpass/fny,lp_fstop/fny,3,40) lp_b, lp_a = butter(lp_ord, lp_wn, 'lowpass') #lp_b, lp_a = butter(8, lp_fpass/fny, 'lowpass') lp_w, lp_h = freqz(lp_b, lp_a, worN=len(fhz_nf),fs=fs*2*np.pi) sig_lp = lfilter(lp_b,lp_a,mysignal) sig_fft_lp = np.fft.rfft(sig_lp) f_dimensionless_lp = np.fft.rfftfreq(len(sig_lp)) T = dt*N df = 1./T fhz_lp = f_dimensionless_lp*df*N if plotQ2a: fig3 = plt.figure(figsize=(14,4.5)) plt.title('Q2 (a)') plt.xlabel('tempo [s]') plt.ylabel('sinal ECG filtrado PB [V]') plt.plot(t,sig_lp)
f = np.linspace(0, 80e3, 30) # frequencies for fitting the system Hvals = FreqResp(S0, delta, f0, f) # frequency response of the 2nd order system #%% fitting the IIR filter Fs = 500e3 # sampling frequency Na = 4; Nb = 4 # IIR filter order (Na - denominator, Nb - numerator) b, a, tau = fit_filter.LSIIR(Hvals, Na, Nb, f, Fs) #%% plot the result fplot = np.linspace(0, 80e3, 1000) # frequency range for the plot Hc = FreqResp(S0, delta, f0, fplot) # frequency response of the 2nd order system Hf = freqz(b, a, 2 * np.pi * fplot / Fs)[1] # frequency response of the fitted IIR filter Hf = Hf*np.exp(2j*np.pi*fplot/Fs*tau) # take into account the filter time delay tau fig1 = figure(1); cla() ax1 = fig1.add_subplot(111) ax1.plot(fplot, db(Hc), "+",fplot, db(Hf)) ax1.legend(('System', 'LSIIR fit')) ax1.set_xlabel("frequency / Hz",fontsize=18) ax1.set_ylabel("freq. response amplitude / a.u.",fontsize=18) fig2 = figure(2); cla() ax2 = fig2.add_subplot(111) ax2.plot(fplot, np.angle(Hc), "+",fplot, np.angle(Hf)) ax2.legend(('System', 'LSIIR fit')) ax2.set_xlabel("frequency / Hz",fontsize=18) ax2.set_ylabel("freq. response angle / rad",fontsize=18)
plt.plot(tim, v) fs = 1.0 / tim[1] n = len(t) freqspec = np.fft.fft(v) Hz = np.linspace(0, fs, n) plt.figure() plt.plot(Hz, np.abs(freqspec)) betaorder = 5 #order of the filter bbeta, abeta = butter_bandpass(16, 31, fs, betaorder) thetaorder = 2 btheta, atheta = butter_bandpass(4, 7, fs, thetaorder) wbeta, hbeta = freqz(bbeta, abeta) wtheta, htheta = freqz(btheta, atheta) plt.figure() plt.title('Band Pass Filter Responses') plt.plot(fs * wbeta / (2 * np.pi), np.abs(hbeta), 'b') plt.plot(fs * wtheta / (2 * np.pi), np.abs(htheta), 'r') plt.xlim(0, 100) beta = lfilter(bbeta, abeta, v) theta = lfilter(btheta, atheta, v) fig = plt.figure() plt.title('Theta Signal after 3-7 Hz band pass filter') ax = fig.add_subplot(111) ax.plot(tim, (theta))
def glottal_pole(f, pcm, pitch, hnr, visual=False): """ Algorithm to extract glottal poles using complex cepstrum. """ fig = None if visual: fig = core.Figure(6) frame = core.parameter('Frame', 0) # Window the framed signal frameSize = f.shape[-1] w = core.Window(f, core.nuttall(frameSize)) if visual: p = core.Periodogram(w) ax1 = fig.subplot() fig.specplot(ax1, p, pcm) # Excitation - use the windowed frames ac = core.Autocorrelation(w) ar, gg = AR.ARLevinson(ac, pcm.speech_ar_order()) ex = AR.ARExcitation(w, ar, gg) # Glottal closure. This should be near the middle as it's # windowed. # wsize is enough to capture two pitch periods. # cwsize is a bigger window, zero-padded version of # wsize to allow phase unwrapping. mean = np.mean(pitch) wsize = pcm.seconds_to_period(1 / mean) * 2 cwsize = 512 gci = ex.argmax(axis=-1) g = np.zeros((len(f), cwsize)) gw = core.nuttall(wsize) for i in range(len(f)): beg = gci[i] - wsize / 2 end = gci[i] + wsize / 2 if (beg < 0): end += -beg beg = 0 elif (end > frameSize): beg -= end - frameSize end = frameSize # Make sure to window the unwindowed frame g[i][cwsize / 2 - wsize / 2:cwsize / 2 + wsize / 2] = gw * f[i, beg:end] # Sample frame if fig: sample = w[frame] fr = fig.subplot() fr.plot(sample / np.max(np.abs(sample))) fr.plot(ex[frame] / np.max(np.abs(ex[frame]))) fr.set_xlim(0, frameSize) # Define a new PCM representing the downsampled signal for complex # cepstrum cepFreq = core.parameter('CepFreq', 1000.0) cepPCM = core.PulseCodeModulation(cepFreq * 2) clbin = pcm.hertz_to_dftbin(cepFreq, cwsize) if not int(clbin) & 1: clbin += 1 clsize = (clbin - 1) * 2 cl = ComplexCepstrum(g, clsize) # Maximum phase spectra negs = ComplexSpectrum(cl, 'max') # Convert negative spectrum to LP order = core.parameter('Order', 2) negp = np.abs(negs)**2 ac = core.Autocorrelation(negp, input='psd') a, g = AR.ARLevinson(ac, order=order) ars = AR.ARSpectrum(a, g, clsize / 2 + 1) roots = AR.ARRoots(a) if fig: neg = fig.subplot() fig.specplot(neg, np.abs(negs), cepPCM) spec = fig.subplot() spec.plot(10 * np.log10(np.abs(negs[frame])**2 / clsize)) spec.plot(10 * np.log10(np.abs(ars[frame]))) zpos = roots[frame, 0].real numer = np.array([1.0, -zpos]) * np.sqrt(g[frame]) denom = np.insert(-a[frame], 0, 1) tmp, zspec = sp.freqz(numer, denom, clsize / 2 + 1) spec.plot(10 * np.log10(np.abs(zspec)**2)) # Default pitch range is 40-500 Hz. #theta = [root_angle(r) for r in roots] theta, magtd = MinPolar(roots) loTheta = 1e-8 hiTheta = cepPCM.hertz_to_radians(500) thRange = hiTheta - loTheta thVar = (1.0 / hnr * thRange)**2 for i in range(len(thVar)): if theta[i] < loTheta or theta[i] > hiTheta: thVar[i] = 1e8 thMean = cepPCM.hertz_to_radians(mean) # obs, obsVar, seqVar, initMean, initVar kTheta, kTVar = core.kalman(theta, thVar, (thMean / 4)**2, thMean, thRange**2) # Smooth the magnitude mVar = (1.0 / hnr)**2 # obs, obsVar, seqVar, initMean, initVar kMag, kMVar = core.kalman(magtd, mVar, 0.01, 0.5, 1.0) if fig: ang = fig.subplot() ang.plot(pitch) iCom = [] vCom = [] iPos = [] vPos = [] for i in range(len(roots)): if root_complex(roots[i]): iCom.append(i) vCom.append(cepPCM.radians_to_hertz(root_angle(roots[i]))) elif not root_negative(roots[i]): iPos.append(i) vPos.append(0) ang.plot(iCom, vCom, '1') ang.plot(iPos, vPos, '2') kt = [cepPCM.radians_to_hertz(x) for x in kTheta] kv = [cepPCM.radians_to_hertz(x) for x in kTheta + np.sqrt(kTVar)] ang.plot(kt) ang.plot(kv) ang.set_xlim(0, len(roots)) ang.set_ylim(0, core.parameter('MaxHz', cepFreq)) magp = fig.subplot() magp.plot(magtd) magp.plot(kMag) magp.plot(kMag + np.sqrt(kMVar)) magp.plot(kMag - np.sqrt(kMVar)) #magp.plot(-np.log(magtd+1e-8)) magp.set_xlim(0, len(magtd)) if fig: pfig = plt.figure() pax = pfig.add_axes([0.1, 0.1, 0.8, 0.8], polar=True) pos = roots.flatten() mag = 1 / (np.abs(pos) + 1e-8) arg = np.angle(pos) pax.plot(arg, mag, '3') pax.set_rmax(5) if fig: plt.show() return kTheta, kMag, cepPCM
width = abs(passband_freq - stopband_freq) / 0.5 (tap_count, beta) = kaiserord(ripple=stopband_atten, width=width) #if len(sys.argv) > 6: tap_count = int( sys.argv[6] ) taps = firwin( numtaps = tap_count, \ cutoff = ((passband_freq+stopband_freq)/2)/0.5, \ window = ('kaiser', beta) ) #nn = 25 #taps = [] #for ii in range(0,nn): taps.append(1.0/nn) import matplotlib.pyplot as plt w, h = freqz(taps, worN=8000) fig = plt.figure() plt.title('Digital filter frequency response') ax1 = fig.add_subplot(111) plt.plot(w / (2 * np.pi) * 1.001, 20 * np.log10(abs(h)), 'b') plt.ylabel('Amplitude [dB]', color='b') plt.xlabel('Frequency [Normalized to Fs]') #ax2 = ax1.twinx() #angles = np.unwrap(np.angle(h)) / (2*np.pi) * 360.0 #plt.plot(w/(2*np.pi)*1.001, angles, 'g') #plt.ylabel('Angle (degrees)', color='g') plt.grid() plt.axis('tight') plt.show() L = 0
axis([0, 2*pi*cycles, -1.1, 1.1]) savefig('../images/figure8-11', dpi=150) if sx==6: N = 256 # number of points for freqz Wc = 0.2 # 3dB point Order = 3 # filter order # design a Butterworth filter [b, a] = signal.butter(Order, Wc) # calculate the frequency repsonse [w, h] = signal.freqz(b, a, N) # plot the results figure() p = subplot(2, 1, 1) nudge_subplot(p, 0.04) plot(arange(N)/float(N), 20*log10(abs(h)), lw=2) title('Frequency response') xlabel('Frequency (normalized)') ylabel('dB') ylim(ylim()[0], ylim()[1]+5) grid() p = subplot(2, 1, 2) nudge_subplot(p, -0.02)
#=== Differentiator: needs to have zero at f = 0 # -> antisymmetric, even numtaps -> type IV #Frequency Sampling ============= #b = sig.firwin2(L, [0, 1], [0, 1], antisymmetric = True) #=== REMEZ / Parks-McClellan / Equiripple #b = sig.remez(L, [0, 0.5], [1], type = 'differentiator') #=======================================================1 # Hilbert-Transformer: zero at f = 0 and f = fS/2 # -> antisymmetric, odd numtaps b = sig.firwin2(L, [0,0.01, 0.5, 0.99, 1], [0,1, 1, 1,0], antisymmetric = True) #b = sig.remez(L, [0, 0.1, 0.11, 0.4, 0.41, 0.5], [0,1,0], [0.1,10,0.1],type = 'hilbert') b = b / sum(abs(b)) print (b) [w, H] = sig.freqz(b, a, 1024) # Translate w to physical frequencies: f = w / (2 * pi) * f_S ############## Plot the Results ######### ## Pol/Nullstellenplan figure(1) [z, p, k] = dsp.zplane(b, a) ## ----- Impulsantwort ----- figure(2) [h, td] = dsp.impz(b, a, f_S) #Impulsantwort / Koeffizienten [ml, sl, bl] = stem(td, h) plt.setp(ml, 'markerfacecolor', 'r', 'markersize', 8) title(r'Impulsantwort h[n]') ## ----- Linear frequency plot ----- figure(3) plot(f, abs(H))
if __name__ == "__main__": import numpy as np import matplotlib.pyplot as plt from scipy.signal import freqz # Sample rate and desired cutoff frequencies (in Hz). fs = 5000.0 lowcut = 500.0 highcut = 1250.0 # Plot the frequency response for a few different orders. plt.figure(1) plt.clf() for order in [3, 6, 9]: b, a = butter_bandpass(lowcut, highcut, fs, order=order) w, h = freqz(b, a, worN=2000) 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('Frequenz (Hz)') plt.ylabel('Verstärkung') plt.grid(True) plt.legend(loc='best') # Filter a noisy signal. T = 0.05 nsamples = T * fs t = np.linspace(0, T, nsamples, endpoint=False) a = 0.02
ecg_one_lead = signals[:, 0] fs = fields.get('fs') nyq_frec = fs / 2 #%% #------DISEÑO DE FILTROS y PLANTILLA------- ripple = -0.05 atenua = -40. #------- Notch --------- Q = 100 wo = 30 / (fs / 2) t = np.arange(0, n / fs, 1 / fs) b, a = sig.iirnotch(wo, Q) w_notch, h_notch = sig.freqz(b, a) w_notch = w_notch / np.pi * nyq_frec #------Pasa Bajos------- wpb_p = 40.0 #Hz wpb_s = 50.0 #Hz cant_coef_pb = 201 frecs_pb = np.array([0.0, wpb_p, wpb_s, nyq_frec]) gainsDB_pb = np.array([ripple, ripple, atenua, atenua]) gains_pb = 10**(gainsDB_pb / 20) fir_coeff_pb = sig.firls(cant_coef_pb, frecs_pb, gains_pb, fs=fs) w_pb, hh_fir_pb = sig.freqz(fir_coeff_pb, 1) w_pb = w_pb / np.pi * nyq_frec
def butter_lowpass_filter(data, cutoff, fs, order=5): b, a = butter_lowpass(cutoff, fs, order=order) y = lfilter(b, a, data) return y # Filter requirements. order = 6 fs = 30.0 # sample rate, Hz cutoff = 3.667 # desired cutoff frequency of the filter, Hz # Get the filter coefficients so we can check its frequency response. b, a = butter_lowpass(cutoff, fs, order) # Plot the frequency response. w, h = freqz(b, a, worN=8000) plt.subplot(2, 1, 1) plt.plot(0.5 * fs * w / np.pi, np.abs(h), 'b') plt.plot(cutoff, 0.5 * np.sqrt(2), 'ko') plt.axvline(cutoff, color='k') plt.xlim(0, 0.5 * fs) plt.title("Lowpass Filter Frequency Response") plt.xlabel('Frequency [Hz]') plt.grid() # Demonstrate the use of the filter. # First make some data to be filtered. T = 5.0 # seconds n = int(T * fs) # total number of samples t = np.linspace(0, T, n, endpoint=False) # "Noisy" data. We want to recover the 1.2 Hz signal from this.
def change_freq_res(self, init=False, redraw=False): if self.cnp_gain is not None: self.cnp_gain.remove() self.cnp_gain = None if self.cnp_ph is not None: self.cnp_ph.remove() self.cnp_ph = None if init == True: # Generate the plots from scratch and name the axes with self.out: if redraw == True: # Remove the gain and phase plots for i in range(1, len(self.axs)): self.axs[1].remove() self.axs.pop(1) self.axs[0].lines[0].set_visible(self.discrete_mode) # Add gain (and phase) plot if self.show_phase: self.axs.append(self.fig.add_subplot(self.gs[:1, 1])) self.axs.append(self.fig.add_subplot(self.gs[1:, 1])) else: self.axs.append(self.fig.add_subplot(self.gs[:, 1])) # Get zeros and poles from the zero pole plot z_re, z_im = self.axs[0].lines[1].get_data() z = z_re + 1j * z_im p_re, p_im = self.axs[0].lines[2].get_data() p = p_re + 1j * p_im # Calculate the gain (C) gaind = np.prod(1. + 0.j - z) / np.prod(1. + 0.j - p) gainc = np.prod(-z) / np.prod(-p) try: if self.discrete_mode: # Generate the transfer function H = signal.ZerosPolesGain(z, p, gaind, dt=0.1).to_tf() # Generate dicrete frequency response w, h = signal.freqz(H.num, H.den, whole=True) # Shift the angles to [-pi, pi] w = w - np.pi # Shift the gain and phase accordingly h_ph = np.fft.fftshift(np.angle(h, deg=True)) h = np.abs(np.fft.fftshift(h)) if self.show_dB: h = 20 * np.log10(h) else: # Generate the transfer function H = signal.ZerosPolesGain(z, p, gainc) # Generate the continuous frequency response w1, h11 = signal.freqresp(H, w=None, n=1000) h_ph1 = np.angle(h11, deg=True) h1 = np.abs(h11) w2 = np.flip(-w1) w2, h21 = signal.freqresp(H, w2, n=1000) h_ph2 = np.angle(h21, deg=True) h2 = np.abs(h21) w = np.concatenate((w2, w1)) h = np.concatenate((h2, h1)) if self.show_dB: h = 20 * np.log10(h) h_ph = np.concatenate((h_ph2, h_ph1)) except ValueError: w = 1 h = 1 h_ph = 1 self.calc_not_possible() if np.any(np.isinf(h)) or np.any(np.isnan(h)) or np.any( np.isinf(h_ph)) or np.any(np.isnan(h_ph)): w = 1 h = 1 h_ph = 1 self.calc_not_possible() #This is to check if any pole is on/outside of the unit circle if np.any(np.abs(p) >= 1): self.tx_deb.set_text("Filter is non causal") else: self.tx_deb.set_text("") if init == True: with self.out: # Gain self.axs[1].set_title('Frequency response') if self.discrete_mode: self.axs[1].plot(w, h) else: self.axs[1].plot(w, h) self.axs[1].set_xlabel('$\omega$ [rad]') self.axs[1].set_ylabel( '|H(z)| [dB]' if self.show_dB else '|H(z)|') # Phase if self.show_phase: if self.discrete_mode: self.axs[2].plot(w, h_ph) else: self.axs[2].plot(w, h_ph) self.axs[2].set_xlabel('$\omega$ [rad]') self.axs[2].set_ylabel('$\phi$(H(z)) [deg]') if self.discrete_mode: positions = [-np.pi, -np.pi / 2, 0, np.pi / 2, np.pi] labels = [ '-$\pi$', '-$\dfrac{\pi}{2}$', '0', '$\dfrac{\pi}{2}$', '$\pi$' ] self.axs[1].set_xticks(positions) self.axs[1].set_xticklabels(labels) # Move y axis to the right self.axs[1].yaxis.set_label_position("right") self.axs[1].yaxis.tick_right() if self.show_phase: self.axs[1].xaxis.set_visible(False) positions = [-np.pi, -np.pi / 2, 0, np.pi / 2, np.pi] labels = [ '-$\pi$', '-$\dfrac{\pi}{2}$', '0', '$\dfrac{\pi}{2}$', '$\pi$' ] self.axs[2].set_xticks(positions) self.axs[2].set_xticklabels(labels) # Move y axis to the right self.axs[2].yaxis.set_label_position("right") self.axs[2].yaxis.tick_right() else: w_max = np.round(np.max(w) / np.pi) * np.pi w_min = np.round(np.min(w) / np.pi) * np.pi t = np.linspace(w_min, w_max, int((w_max - w_min) // np.pi) + 1) t_labels = [ f'{int(np.round(tick/np.pi))}$\pi$' if abs(int(np.round(tick / np.pi))) > 1 else '$\pi$' if tick > 0 else '$-\pi$' if int(np.round(tick / np.pi)) != 0 else '0' for tick in t ] self.axs[1].set_xticks(t) self.axs[1].set_xticklabels(t_labels) if self.show_phase: self.axs[1].xaxis.set_visible(False) self.axs[2].set_xticks(t) self.axs[2].set_xticklabels(t_labels) else: # Only change the values of the plots # Gain self.axs[1].lines[0].set_data(w, h) h_min = np.min(h) h_max = np.max(h) h_range = abs(h_max - h_min) self.axs[1].set_ylim( [h_min - 0.05 * h_range, h_max + 0.05 * h_range] if h_min != h_max else [h_min - 1, h_max + 1]) # Phase if self.show_phase: h_ph_min = np.min(h_ph) h_ph_max = np.max(h_ph) h_ph_range = abs(h_ph_max - h_ph_min) self.axs[2].lines[0].set_data(w, h_ph) self.axs[2].set_ylim([ h_ph_min - 0.05 * h_ph_range, h_ph_max + 0.05 * h_ph_range ] if h_ph_min != h_ph_max else [h_ph_min - 1, h_ph_max + 1]) # self.axs[2].set_xlim([w_min-0.05*w_range, w_max+0.05*w_range] if w_min != w_max and check else [w_min, w_max+1]) if self.active_line is not None: l_x, l_y = self.axs[0].lines[self.active_line + 1].get_data() if len(l_y) > self.active_point and len( l_x) > self.active_point: self.actual_change = False self.lastzeroRe = round(l_x[self.active_point], 3) self.input_Zero_RE.value = self.lastzeroRe self.lastzeroIm = round(l_y[self.active_point], 3) self.input_Zero_IM.value = self.lastzeroIm self.actual_change = True
def calculate_Pst(data): show_time_signals = 0 #Aktivierung des Plots der Zeitsignale im Flickermeter show_filter_responses = 0 #Aktivierung des Plots der Amplitudengänge der Filter. #(zu Prüfzecken der internen Filter) fs = 4000 ## Block 1: Modulierung des Spannungssignals u = data - np.mean(data) # entfernt DC-Anteil u_rms = np.sqrt(np.mean(np.power(u,2))) # Normierung des Eingangssignals u = u / (u_rms * np.sqrt(2)) ## Block 2: Quadratischer Demulator u_0 = u**2 ## Block 3: Hochpass-, Tiefpass- und Gewichtungsfilter # Konfiguration der Filter HIGHPASS_ORDER = 1 #Ordnungszahl der Hochpassfilters HIGHPASS_CUTOFF = 0.05 #Hz Grenzfrequenz LOWPASS_ORDER = 6 #Ordnungszahl des Tiefpassfilters if (f_line == 50): LOWPASS_CUTOFF = 35.0 #Hz Grenzfrequenz if (f_line == 60): LOWPASS_CUTOFF = 42.0 #Hz Grenzfrequenz # subtract DC component to limit filter transients at start of simulation u_0_ac = u_0 - np.mean(u_0) b_hp, a_hp = signal.butter(HIGHPASS_ORDER, (HIGHPASS_CUTOFF/(fs/2)), 'highpass') u_hp = signal.lfilter(b_hp, a_hp, u_0_ac) # smooth start of signal to avoid filter transient at start of simulation smooth_limit = min(round(fs / 10), len(u_hp)) u_hp[ : smooth_limit] = u_hp[ : smooth_limit] * np.linspace(0, 1, smooth_limit) b_bw, a_bw = signal.butter(LOWPASS_ORDER, (LOWPASS_CUTOFF/(fs/2)), 'lowpass') u_bw = signal.lfilter(b_bw, a_bw, u_hp) # Gewichtungsfilter (Werte sind aus der Norm) if (f_line == 50): K = 1.74802 LAMBDA = 2 * np.pi * 4.05981 OMEGA1 = 2 * np.pi * 9.15494 OMEGA2 = 2 * np.pi * 2.27979 OMEGA3 = 2 * np.pi * 1.22535 OMEGA4 = 2 * np.pi * 21.9 if (f_line == 60): K = 1.6357 LAMBDA = 2 * np.pi * 4.167375 OMEGA1 = 2 * np.pi * 9.077169 OMEGA2 = 2 * np.pi * 2.939902 OMEGA3 = 2 * np.pi * 1.394468 OMEGA4 = 2 * np.pi * 17.31512 num1 = [K * OMEGA1, 0] denum1 = [1, 2 * LAMBDA, OMEGA1**2] num2 = [1 / OMEGA2, 1] denum2 = [1 / (OMEGA3 * OMEGA4), 1 / OMEGA3 + 1 / OMEGA4, 1] b_w, a_w = signal.bilinear(np.convolve(num1, num2), np.convolve(denum1, denum2), fs) u_w = signal.lfilter(b_w, a_w, u_bw) ## Block 4: Quadrierung und Varianzschätzer LOWPASS_2_ORDER = 1 LOWPASS_2_CUTOFF = 1 / (2 * np.pi * 300e-3) # Zeitkonstante 300 msek. SCALING_FACTOR = 1238400 # Skalierung des Signals auf eine Wahrnehmbarkeitsskala u_q = u_w**2 b_lp, a_lp = signal.butter(LOWPASS_2_ORDER, (LOWPASS_2_CUTOFF/(fs/2)), 'low') s = SCALING_FACTOR * signal.lfilter(b_lp, a_lp, u_q) ## Block 5: Statistische Berechnung p_50s = np.mean([np.percentile(s, 100-30, interpolation="linear"), np.percentile(s, 100-50, interpolation="linear"), np.percentile(s, 100-80, interpolation="linear")]) p_10s = np.mean([np.percentile(s, 100-6, interpolation="linear"), np.percentile(s, 100-8, interpolation="linear"), np.percentile(s, 100-10, interpolation="linear"), np.percentile(s, 100-13, interpolation="linear"), np.percentile(s, 100-17, interpolation="linear")]) p_3s = np.mean([np.percentile(s, 100-2.2, interpolation="linear"), np.percentile(s, 100-3, interpolation="linear"), np.percentile(s, 100-4, interpolation="linear")]) p_1s = np.mean([np.percentile(s, 100-0.7, interpolation="linear"), np.percentile(s, 100-1, interpolation="linear"), np.percentile(s, 100-1.5, interpolation="linear")]) p_0_1s = np.percentile(s, 100-0.1, interpolation="linear") P_st = np.sqrt(0.0314*p_0_1s+0.0525*p_1s+0.0657*p_3s+0.28*p_10s+0.08*p_50s) if (show_time_signals): t = np.linspace(0, len(u) / fs, num=len(u)) plt.figure() plt.clf() #plt.subplot(2, 2, 1) plt.hold(True) plt.plot(t, u, 'b', label="u") plt.plot(t, u_0, 'm', label="u_0") plt.plot(t, u_hp, 'r', label="u_hp") plt.xlim(0, len(u)/fs) plt.hold(False) plt.legend(loc=1) plt.grid(True) #plt.subplot(2, 2, 2) plt.figure() plt.clf() plt.hold(True) plt.plot(t, u_bw, 'b', label="u_bw") plt.plot(t, u_w, 'm', label="u_w") plt.xlim(0, len(u)/fs) plt.legend(loc=1) plt.hold(False) plt.grid(True) #plt.subplot(2, 2, 3) plt.figure() plt.clf() plt.plot(t, u_q, 'b', label="u_q") plt.xlim(0, len(u)/fs) plt.legend(loc=1) plt.grid(True) #plt.subplot(2, 2, 4) plt.figure() plt.clf() plt.plot(t, s, 'b', label="s") plt.xlim(0, len(u)/fs) plt.legend(loc=1) plt.grid(True) if (show_filter_responses): f, h_hp = signal.freqz(b_hp, a_hp, 4096) f, h_bw = signal.freqz(b_bw, a_bw, 4096) f, h_w = signal.freqz(b_w, a_w, 4096) f, h_lp = signal.freqz(b_lp, a_lp, 4096) f = f/np.pi*fs/2 plt.figure() plt.clf() plt.hold(True) plt.plot(f, abs(h_hp), 'b', label="Hochpass 1. Ordnung") plt.plot(f, abs(h_bw), 'r', label="Butterworth Tiefpass 6.Ordnung") plt.plot(f, abs(h_w), 'g', label="Gewichtungsfilter") plt.plot(f, abs(h_lp), 'm', label="Varianzschätzer") plt.legend(bbox_to_anchor=(1., 1.), loc=2) plt.hold(False) plt.grid(True) plt.axis([0, 35, 0, 1]) return P_st
__author__ = 'caocongcong' from primary_signal.const_value import constValue import scipy.signal as signal import pylab as plt import numpy as np if __name__ == "__main__": b = np.array(constValue.lp_fs400_Overband20) w, h = signal.freqz(b, 1) plt.plot(w / 2 / np.pi, 20 * np.log10(np.abs(h))) plt.show() # 进行滤波实验 fs = 1.2e9 f1 = 0.2e9 f2 = 0.5e9 time = 0.000001 t = np.linspace(0, time, int(time * fs)) s = np.sin(2 * np.pi * f1 * t) + np.sin(2 * np.pi * f2 * t) plt.plot(t, s) plt.xlabel('time/s') plt.title('before fliter') plt.show() sf = signal.filtfilt(b, 1, s) plt.plot(t, sf) plt.xlabel('time/s') plt.title('after fliter') plt.show()