Spaces:
Running
on
Zero
Running
on
Zero
| from scipy.signal import butter, lfilter | |
| import torch | |
| from scipy import signal | |
| import librosa | |
| import numpy as np | |
| from scipy.signal import sosfiltfilt | |
| from scipy.signal import butter, cheby1, cheby2, ellip, bessel | |
| from scipy.signal import resample_poly | |
| def align_length(x=None, y=None, Lx=None): | |
| """align the length of y to that of x | |
| Args: | |
| x (np.array): reference signal | |
| y (np.array): the signal needs to be length aligned | |
| Return: | |
| yy (np.array): signal with the same length as x | |
| """ | |
| assert y is not None | |
| if Lx is None: | |
| Lx = len(x) | |
| Ly = len(y) | |
| if Lx == Ly: | |
| return y | |
| elif Lx > Ly: | |
| # pad y with zeros | |
| return np.pad(y, (0, Lx - Ly), mode="constant") | |
| else: | |
| # cut y | |
| return y[:Lx] | |
| def bandpass_filter(x, lowcut, highcut, fs, order, ftype): | |
| """process input signal x using bandpass filter | |
| Args: | |
| x (np.array): input signal | |
| lowcut (float): low cutoff frequency | |
| highcut (float): high cutoff frequency | |
| order (int): the order of filter | |
| ftype (string): type of filter | |
| ['butter', 'cheby1', 'cheby2', 'ellip', 'bessel'] | |
| Return: | |
| y (np.array): filtered signal | |
| """ | |
| nyq = 0.5 * fs | |
| lo = lowcut / nyq | |
| hi = highcut / nyq | |
| if ftype == "butter": | |
| # b, a = butter(order, [lo, hi], btype='band') | |
| sos = butter(order, [lo, hi], btype="band", output="sos") | |
| elif ftype == "cheby1": | |
| sos = cheby1(order, 0.1, [lo, hi], btype="band", output="sos") | |
| elif ftype == "cheby2": | |
| sos = cheby2(order, 60, [lo, hi], btype="band", output="sos") | |
| elif ftype == "ellip": | |
| sos = ellip(order, 0.1, 60, [lo, hi], btype="band", output="sos") | |
| elif ftype == "bessel": | |
| sos = bessel(order, [lo, hi], btype="band", output="sos") | |
| else: | |
| raise Exception(f"The bandpass filter {ftype} is not supported!") | |
| # y = lfilter(b, a, x) | |
| y = sosfiltfilt(sos, x) | |
| if len(y) != len(x): | |
| y = align_length(x, y) | |
| return y | |
| def lowpass_filter(x, highcut, fs, order, ftype): | |
| """process input signal x using lowpass filter | |
| Args: | |
| x (np.array): input signal | |
| highcut (float): high cutoff frequency | |
| order (int): the order of filter | |
| ftype (string): type of filter | |
| ['butter', 'cheby1', 'cheby2', 'ellip', 'bessel'] | |
| Return: | |
| y (np.array): filtered signal | |
| """ | |
| nyq = 0.5 * fs | |
| hi = highcut / nyq | |
| if ftype == "butter": | |
| sos = butter(order, hi, btype="low", output="sos") | |
| elif ftype == "cheby1": | |
| sos = cheby1(order, 0.1, hi, btype="low", output="sos") | |
| elif ftype == "cheby2": | |
| sos = cheby2(order, 60, hi, btype="low", output="sos") | |
| elif ftype == "ellip": | |
| sos = ellip(order, 0.1, 60, hi, btype="low", output="sos") | |
| elif ftype == "bessel": | |
| sos = bessel(order, hi, btype="low", output="sos") | |
| else: | |
| raise Exception(f"The lowpass filter {ftype} is not supported!") | |
| y = sosfiltfilt(sos, x) | |
| if len(y) != len(x): | |
| y = align_length(x, y) | |
| y_len = len(y) | |
| y = stft_hard_lowpass(y, hi, fs_ori=fs) | |
| y = sosfiltfilt(sos, y) | |
| if len(y) != y_len: | |
| y = align_length(y=y, Lx=y_len) | |
| return y | |
| def stft_hard_lowpass(data, lowpass_ratio, fs_ori=44100): | |
| fs_down = int(lowpass_ratio * fs_ori) | |
| # downsample to the low sampling rate | |
| y = resample_poly(data, fs_down, fs_ori) | |
| # upsample to the original sampling rate | |
| y = resample_poly(y, fs_ori, fs_down) | |
| if len(y) != len(data): | |
| y = align_length(data, y) | |
| return y | |
| def limit(integer, high, low): | |
| if integer > high: | |
| return high | |
| elif integer < low: | |
| return low | |
| else: | |
| return int(integer) | |
| def lowpass(data, highcut, fs, order=5, _type="butter"): | |
| """ | |
| :param data: np.float32 type 1d time numpy array, (samples,) , can not be (samples, 1) !!!!!!!!!!!! | |
| :param highcut: cutoff frequency | |
| :param fs: sample rate of the original data | |
| :param order: order of the filter | |
| :return: filtered data, (samples,) | |
| """ | |
| if len(list(data.shape)) != 1: | |
| raise ValueError( | |
| "Error (chebyshev_lowpass_filter): Data " | |
| + str(data.shape) | |
| + " should be type 1d time array, (samples,) , can not be (samples, 1)" | |
| ) | |
| if _type in "butter": | |
| order = limit(order, high=10, low=2) | |
| return lowpass_filter( | |
| x=data, highcut=int(highcut), fs=fs, order=order, ftype="butter" | |
| ) | |
| elif _type in "cheby1": | |
| order = limit(order, high=10, low=2) | |
| return lowpass_filter( | |
| x=data, highcut=int(highcut), fs=fs, order=order, ftype="cheby1" | |
| ) | |
| elif _type in "ellip": | |
| order = limit(order, high=10, low=2) | |
| return lowpass_filter( | |
| x=data, highcut=int(highcut), fs=fs, order=order, ftype="ellip" | |
| ) | |
| elif _type in "bessel": | |
| order = limit(order, high=10, low=2) | |
| return lowpass_filter( | |
| x=data, highcut=int(highcut), fs=fs, order=order, ftype="bessel" | |
| ) | |
| # elif(_type in "stft"): | |
| # return stft_hard_lowpass(data, lowpass_ratio=highcut / int(fs / 2)) | |
| # elif(_type in "stft_hard"): | |
| # return stft_hard_lowpass_v0(data, lowpass_ratio=highcut / int(fs / 2)) | |
| else: | |
| raise ValueError("Error: Unexpected filter type " + _type) | |
| def bandpass(data, lowcut, highcut, fs, order=5, _type="butter"): | |
| """ | |
| :param data: np.float32 type 1d time numpy array, (samples,) , can not be (samples, 1) !!!!!!!!!!!! | |
| :param lowcut: low cutoff frequency | |
| :param highcut: high cutoff frequency | |
| :param fs: sample rate of the original data | |
| :param order: order of the filter | |
| :param _type: type of filter | |
| :return: filtered data, (samples,) | |
| """ | |
| if len(list(data.shape)) != 1: | |
| raise ValueError( | |
| "Error (chebyshev_lowpass_filter): Data " | |
| + str(data.shape) | |
| + " should be type 1d time array, (samples,) , can not be (samples, 1)" | |
| ) | |
| if _type in "butter": | |
| order = limit(order, high=10, low=2) | |
| return bandpass_filter( | |
| x=data, | |
| lowcut=int(lowcut), | |
| highcut=int(highcut), | |
| fs=fs, | |
| order=order, | |
| ftype="butter", | |
| ) | |
| elif _type in "cheby1": | |
| order = limit(order, high=10, low=2) | |
| return bandpass_filter( | |
| x=data, | |
| lowcut=int(lowcut), | |
| highcut=int(highcut), | |
| fs=fs, | |
| order=order, | |
| ftype="cheby1", | |
| ) | |
| # elif(_type in "cheby2"): | |
| # return bandpass_filter(x=data,lowcut=int(lowcut),highcut=int(highcut), fs=fs, order=order,ftype="cheby2") | |
| elif _type in "ellip": | |
| order = limit(order, high=10, low=2) | |
| return bandpass_filter( | |
| x=data, | |
| lowcut=int(lowcut), | |
| highcut=int(highcut), | |
| fs=fs, | |
| order=order, | |
| ftype="ellip", | |
| ) | |
| elif _type in "bessel": | |
| order = limit(order, high=10, low=2) | |
| return bandpass_filter( | |
| x=data, | |
| lowcut=int(lowcut), | |
| highcut=int(highcut), | |
| fs=fs, | |
| order=order, | |
| ftype="bessel", | |
| ) | |
| else: | |
| raise ValueError("Error: Unexpected filter type " + _type) | |