Example #1
0
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
Example #2
0
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)
Example #3
0
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)
Example #5
0
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
Example #6
0
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
Example #7
0
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
Example #8
0
    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()
Example #9
0
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
Example #11
0
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
Example #12
0
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()
Example #13
0
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()
Example #14
0
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
Example #15
0
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')
Example #16
0
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)
Example #18
0
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
Example #20
0
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
Example #21
0
 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.")
Example #23
0
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)
Example #24
0
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")
Example #25
0
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
Example #27
0
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
Example #28
0
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)))
Example #30
0
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")