def test_butterBandpass_egde(self): # no signal allowed b, a = self.util.butterBandpass(5, 5, 16) _, h = freqz(b, a, worN=32) self.assertEquals(np.count_nonzero(abs(h)), 0) # everything gets through (except 0) b, a = self.util.butterBandpass(0, 8, 16) _, h = freqz(b, a, worN=16) self.assertAlmostEqual(sum(abs(h)), len(h)-1, delta = 1) b, a = self.util.butterBandpass(0.5, 8, 16) _, h = freqz(b, a, worN=16) self.assertAlmostEqual(sum(abs(h)), len(h)-1, delta = 1) b, a = self.util.butterBandpass(-1, 9, 16) _, h = freqz(b, a, worN=16) self.assertAlmostEqual(sum(abs(h)), len(h)-1, delta = 1)
def test_butterBandpass(self): samplingRate = 32 i = samplingRate / 4 b, a = self.util.butterBandpass(i-1, i+1, samplingRate) _, h = freqz(b, a, worN=samplingRate*4) h = abs(h) self.assertEqual(np.argmax(h), len(h)/2) self.assertAlmostEqual(max(h), 1, delta=0.1) self.assertAlmostEqual(h[0], 0, delta=0.01) self.assertAlmostEqual(h[len(h)-1], 0, delta=0.01)
def plot_frequency_response(self, filter_coeffs, framerate, cutoffs, title=None): ''' Plot response to a low/high/bandpass filter. Filter coefficients from from calling iirfilter(). If that function was called such that it returned nominator/denominator of the transfer function, namely a and b, hen filter_coeffs should be a tuple (a,b) if the function was called requesting second order segments, (sos), then filter_coeffs should be the sos. @param filter_coeffs: definiting filter characteristics @type filter_coeffs: {(np_arr, np_arr) | np_arr} @param framerate: sample frequency of the audio file. @type int @param cutoffs: frequencies (Hz) at which filter is supposed to cut off @type cutoffs: {int | [int]} @param title: optional title of the figure. If None, a title is created from the cutoff freqs. @type str ''' if type(cutoffs) != list: cutoffs = [cutoffs] if type(filter_coeffs) == tuple: (a, b) = filter_coeffs w, h = freqz(b, a, worN=8000) else: w, h = sosfreqz(filter_coeffs, worN=8000) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(0.5 * framerate * w / np.pi, np.abs(h), 'b') # Blue ax.plot(cutoffs[0], 0.5 * np.sqrt(2), 'ko') ax.axvline(cutoffs[0], color='k') if len(cutoffs) > 1: ax.plot(cutoffs[1], 0.5 * np.sqrt(2), 'ko') ax.axvline(cutoffs[1], color='k') # Since x axis will be log, cannot start # x vals at 0. To make best use of the # horizontal space, start plotting at # 5Hz below the low cutoff freq: ax.set_xlim(cutoffs[0] - 5, max(cutoffs) + max(cutoffs)) #0.5*framerate) ax.set_xscale('log') ax.set_yscale('log') if title is not None: fig.suptitle(title) else: fig.suptitle(f"Filter Frequency Response cutoff(s): {cutoffs} Hz") ax.set_xlabel('Log frequency [Hz]') ax.grid() fig.show()
def plot_filter_responce(filter_coefficients): w, h = freqz(filter_coefficients) fig = plt.figure() plt.title('Digital filter frequency 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') plt.show()
def test_cheby2_low_pass_filter(): rate = 16000 # sampling rate of speech waveform(Hz) cut_off = 700 # cut off frequency (Hz) ripple = 0.5 # pass band maximum loss (gpass) attenuation = 60 # stop band min attenuation (gstop) b, a = cheby2_low_pass_coefficients(cut_off, rate, ripple, attenuation) # Plot the frequency response. w, h = fd.freqz(b, a, worN=8000) plt.subplot(2, 1, 1) plt.plot(0.5 * rate * w / np.pi, np.abs(h), 'b') plt.plot(cut_off, 0.5 * np.sqrt(2), 'ko') plt.axvline(cut_off, color='k') plt.xlim(0, 0.5 * rate) plt.title("Low pass 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 * rate) # 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. data = np.sin(1.2 * 2 * np.pi * t) + 1.5 * np.cos( 9 * 2 * np.pi * t) + 0.5 * np.sin(12.0 * 2 * np.pi * t) # Filter the data, and plot both the original and filtered signals. y = cheby2_low_pass_filter(data, cut_off, rate, ripple, attenuation) plt.subplot(2, 1, 2) plt.plot(t, data, 'b-', label='data') plt.plot(t, y, 'g-', linewidth=2, label='filtered data') plt.xlabel('Time [sec]') plt.grid() plt.legend() plt.subplots_adjust(hspace=0.35) plt.show() # TODO pass