import numpy as np from scipy.signal import butter, lfilter, decimate def anti_alias(data, sample_rate, max_frequency): FILTER_HEADROOM = 1.2 nyquist_rate = 2 * max_frequency downsample_factor = 1 if sample_rate > nyquist_rate: filtered_data = lowpass_filter(data, max_frequency * FILTER_HEADROOM, sample_rate) downsample_factor = int(sample_rate / nyquist_rate) filtered_data = decimate(filtered_data, downsample_factor) sample_rate = sample_rate // downsample_factor else: filtered_data = data return filtered_data, sample_rate, downsample_factor def smoothing_filter(data, window_size=256): window = np.ones(window_size) / window_size return np.convolve(data, window, mode='same') # Stolen from selcald def note(freq, length, amp=1.0, rate=44100): if freq == 0: data = np.zeros(int(length * rate)) else: t = np.linspace(0, length, int(length * rate)) data = np.sin(2 * np.pi * freq * t) * amp return data # These originally came from https://scipy.github.io/old-wiki/pages/Cookbook/ButterworthBandpass, # but they've been copied around the internet so many times that ChatGPT now produces them verbatim. def butter_bandpass(lowcut, highcut, fs, order=5): nyquist = 0.5 * fs low = lowcut / nyquist high = highcut / nyquist b, a = butter(order, [low, high], btype='band') return b, a def bandpass_filter(data, lowcut, highcut, fs, order=5): b, a = butter_bandpass(lowcut, highcut, fs, order=order) y = lfilter(b, a, data) return y def butter_lowpass(cutoff, fs, order=5): nyquist = 0.5 * fs normal_cutoff = cutoff / nyquist b, a = butter(order, normal_cutoff, btype='low', analog=False) return b, a def lowpass_filter(data, cutoff, fs, order=5): b, a = butter_lowpass(cutoff, fs, order=order) y = lfilter(b, a, data) return y