def bandpass_filter(s, sample_rate, low_freq, high_freq, filter_order=5, rescale=False): """ Bandpass filter a signal s. s: the signal sample_rate: the sample rate in Hz of the signal low_freq: the lower cutoff frequency upper_freq: the upper cutoff frequency filter_order: the order of the filter... Returns the bandpass filtered signal s. """ #create a butterworth filter nyq = sample_rate / 2.0 f = np.array([low_freq, high_freq]) / nyq b, a = filter_design.butter(filter_order, f, btype='bandpass') #filter the signal filtered_s = filtfilt(b, a, s) if rescale: #rescale filtered signal filtered_s /= filtered_s.max() filtered_s *= s.max() return filtered_s
def lowpass(data, in_t, cutoff, order=4): """ data: vector of data in_t: sample times cutoff: cutoff period in the same units as in_t returns vector same as data, but with high frequencies removed """ # Step 1: Determine dt from data (complicated due to TRIM time series precision legacy) mean_dt = mean(diff(in_t)) # print 'Data Time Step: %8.4f'%mean_dt # test size of data for vectors only Wn = mean_dt / cutoff # 90 = half # of minutes in 3 hours. # print 'Using %1ith Order Butterworth Filter, with %g time-unit cutoff (Wn=%12.6f).'%(order,2*cutoff,Wn) B, A = butter(order, Wn) data_filtered = filtfilt(B, A, data) return data_filtered
def lowpass(data, in_t=None, cutoff=None, order=4, dt=None, axis=-1, causal=False): """ data: vector of data in_t: sample times cutoff: cutoff period in the same units as in_t returns vector same as data, but with high frequencies removed """ # Step 1: Determine dt from data or from user if specified if dt is None: dt = np.median(np.diff(in_t)) dt = float(dt) # make sure it's not an int cutoff = float(cutoff) Wn = dt / cutoff B, A = butter(order, Wn) if not causal: # scipy filtfilt triggers some warning message about tuple # indices. with warnings.catch_warnings(): warnings.simplefilter("ignore") data_filtered = filtfilt(B, A, data, axis=axis) else: data_filtered = lfilter(B, A, data, axis=axis) return data_filtered
def bandpass_filter(s, sample_rate, low_freq, high_freq, filter_order=5, rescale=False): """ Bandpass filter a signal s. s: the signal sample_rate: the sample rate in Hz of the signal low_freq: the lower cutoff frequency upper_freq: the upper cutoff frequency filter_order: the order of the filter... Returns the bandpass filtered signal s. """ #create a butterworth filter nyq = sample_rate / 2.0 f = np.array([low_freq, high_freq]) / nyq b,a = filter_design.butter(filter_order, f, btype='bandpass') #filter the signal filtered_s = filtfilt(b, a, s) if rescale: #rescale filtered signal filtered_s /= filtered_s.max() filtered_s *= s.max() return filtered_s
def highpass_filter(s, sample_rate, cutoff_freq, filter_order=5, rescale=False): """ Highpass filter a signal s, with sample rate sample_rate. s: the signal sample_rate: the sample rate in Hz of the signal cutoff_freq: the cutoff frequency of the filter filter_order: the order of the filter... Returns the low-pass filtered signal s. """ #create a butterworth filter nyq = sample_rate / 2.0 b, a = filter_design.butter(filter_order, cutoff_freq / nyq, btype='high') #filter the signal filtered_s = filtfilt(b, a, s) if rescale: #rescale filtered signal filtered_s /= filtered_s.max() filtered_s *= s.max() return filtered_s
def lpFiltSpec(fp, fs, nyqf): nyqf = float(nyqf) ord, wn = filter_design.buttord(fp / nyqf, fs / nyqf, 1, 12, analog=0) b, a = butter(ord, wn, btype="lowpass", analog=0, output='ba') w, h = freqz(b, a) fig = _plt.figure() _plt.plot(w * (nyqf / _N.pi), _N.abs(h))
def highpass_filter(s, sample_rate, cutoff_freq, filter_order=5, rescale=False): """ Highpass filter a signal s, with sample rate sample_rate. s: the signal sample_rate: the sample rate in Hz of the signal cutoff_freq: the cutoff frequency of the filter filter_order: the order of the filter... Returns the low-pass filtered signal s. """ #create a butterworth filter nyq = sample_rate / 2.0 b,a = filter_design.butter(filter_order, cutoff_freq / nyq, btype='high') #filter the signal filtered_s = filtfilt(b, a, s) if rescale: #rescale filtered signal filtered_s /= filtered_s.max() filtered_s *= s.max() return filtered_s
def butter_bandpass_filter_two(data, lowcut, highcut, fs, order=5): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq b, a = butter(order, [low, high], btype='band') y = lfilter(b, a, data) return y
def lowpass(data, in_t=None, cutoff=None, order=4, dt=None, axis=-1, causal=False): """ data: vector of data in_t: sample times cutoff: cutoff period in the same units as in_t returns vector same as data, but with high frequencies removed """ # Step 1: Determine dt from data dt = dt or np.median(np.diff(in_t)) dt = float(dt) cutoff = float(cutoff) Wn = dt / cutoff B, A = butter(order, Wn) if not causal: data_filtered = filtfilt(B, A, data, axis=axis) else: data_filtered = lfilter(B, A, data, axis=axis) return data_filtered
def envelope(signal, fs, env_cutoff=16., env_order=4., full_rect=False): '''Extracts the amplitude envelope from a signal using rectification and low-pass filtering Parameters ---------- signal : array The signal to extract the amplitude envelope from fs : scalar The sampling frequency env_cutoff : scalar The envelope cutoff frequency [default=16 Hz] env_order : scalar The order of the envelope filter [must be even number; default=6] full_rect : bool True for full-wave rectification [default=half-wave rectification] Returns ------- env : array The amplitude envelope of the input signal ''' signal = signal - np.mean(signal) # Remove DC component if full_rect: rect = np.absolute(signal) else: rect = np.maximum(signal,0) env_b,env_a = filters.butter(env_order/2.,np.float32(env_cutoff)/(np.float32(fs)/2.)) env = filtfilt(env_b,env_a,rect) return env
def bpFilt(fpL, fpH, fsL, fsH, nyqf, y): nyqf = float(nyqf) ord, wn = filter_design.buttord((fpL / nyqf, fpH / nyqf), (fsL / nyqf, fsH / nyqf), 1, 12, analog=0) b, a = butter(ord, wn, btype="bandpass", analog=0, output='ba') fy = filtfilt(b, a, y) return fy
def band_pass_filter(self, wavFile): rate, sound_samples = read(wavFile) # f , fs sound_samples = np.float64(sound_samples / 32768.0) n = 7 beginFreq = 700.0 / (rate / 2) endFreq = 12000.0 / (rate / 2) [b, a] = butter(n, [beginFreq, endFreq], 'bandpass') filtered = lfilter(b, a, sound_samples) filtered = np.int16(filtered * 32768 * 10) write(self.__filteredFile, rate, filtered) return self.__filteredFile
def bpFiltSpec(fpL, fpH, fsL, fsH, nyqf): nyqf = float(nyqf) ord, wn = filter_design.buttord((fpL / nyqf, fpH / nyqf), (fsL / nyqf, fsH / nyqf), 1, 12, analog=0) b, a = butter(ord, wn, btype="bandpass", analog=0, output='ba') w, h = freqz(b, a) fig = _plt.figure() _plt.plot(w * (nyqf / _N.pi), _N.abs(h))
def lowpass(signal, order, cutoff, sr): b, a = butter(order, cutoff / (sr / 2)) filteredSignal = nans(shape(signal)) if len(signal) <= 3 * max(len(a), len(b)): print "signal too short to be lowpassed: " + str(len(signal)) return nans(shape(signal)) for i in range(shape(signal)[1]): filteredSignal[:, i] = filtfilt(b, a, signal[:, i]) return filteredSignal
def low_filter(self, wavFile): rate, sound_samples = read(wavFile) sound_samples = np.float64(sound_samples / 32768.0) pass_freq = 0.2 stop_freq = 0.3 pass_gain = 0.5 # permissible loss (ripple) in passband (dB) stop_gain = 10.0 # attenuation required in stopband (dB) ord, wn = buttord(pass_freq, stop_freq, pass_gain, stop_gain) b, a = butter(ord, wn, btype='low') filtered = lfilter(b, a, sound_samples) filtered = np.int16(filtered * 32768 * 10) write(self.__filteredFile, rate, filtered) return self.__filteredFile
def butter_bandpass_filter(data, lowcut, highcut, fs, order=5): """ Runs a Butterworth bandpass filter on sound data :param data: sound data to filter :param lowcut: the lowest frequency to accept :param highcut: the highest frequency to accept :param fs: sampling frequency :param order: the order of the filter """ nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq b, a = butter(order, [low, high], btype='band') y = lfilter(b, a, data) return y
def butter_pass(cutoff, fs, order=5, btype="low"): nyq = 0.5 * fs normal_cutoff = cutoff / nyq b, a = butter(order, normal_cutoff, btype=btype, analog=False) return b, a
def butter_bp(lo=0, hi=0, Fs=2.0, ord=3): # note: "lo" corresponds to highpass cutoff # "hi" corresponds to lowpass cutoff freqs, btype = _bandpass_params(lo, hi) return fdesign.butter(ord, 2 * freqs / Fs, btype=btype)
def butter_bandpass(lowcut, highcut, fs, order=9): nyq = 0.5 * fs low = lowcut / nyq high = highcut / nyq b, a = butter(order, [low, high], btype='band') return b, a
format(data_wav.shape[0] / fs_wav)) duration = (data_wav.shape[0] / fs_wav) print(duration, " Duration") count_minutes = int(duration/60) print(count_minutes, " minutes") bpm=[] for j in range(1,count_minutes+1): print(j,"th iteration") data_wav_norm = copy.deepcopy(data_wav) data_wav_norm = data_wav_norm[(j-1)*60 * fs_wav: (j)*60 * fs_wav] time_wav = np.arange(0, len(data_wav_norm)) / fs_wav # Applying Low-pass Butter filter b, a = butter(3, 0.9/(fs_wav*0.5), btype = 'low', analog=False) filtered = lfilter(b, a, data_wav_norm) data_wav_lp = filtered print(len(data_wav_lp), "Length") data_wav_lp = data_wav_lp/ (2**15) #Applying hilbert Transformation to get envelope of the signal analytic_signal = hilbert(data_wav_lp) amplitude_envelope = np.abs(analytic_signal) instantaneous_phase = np.unwrap(np.angle(analytic_signal)) #getting Properties of the envelope peaks, prop = find_peaks(amplitude_envelope,height=[0,0.2], distance=5000) peak_graph = prop["peak_heights"]
def f0(sig, fs, noisegate=15): '''Estimates the fundamental frequency of a signal Returns an array of estimated instantaneous fundamental frequency (F0) values based on zeros crossings in the input signal. Parameters ---------- sig : array The input signal. fs : array The sampling frequency. Returns ------- y : array The pitch track. ''' # Low-pass at 270 Hz (above most F0's) b, a = filters.butter(4, 270. / (fs / 2.)) fsig = filtfilt(b, a, sig) b, a = filters.butter(4, 60. / (fs / 2.), btype='high') fsig = filtfilt(b, a, fsig) # Get zero crossings zc = np.array( np.where(np.sign(fsig[1:]) != np.sign(fsig[:-1]))).transpose()[:, 0] # Compute period at each crossing # (actually half-period, since a full period is 2 zero crossings) zc2 = np.concatenate((zc, np.zeros((1)))) zc3 = np.concatenate((np.zeros((1)), zc)) p = zc2 - zc3 p[-1] = p[-2] # Create new array of periods @ fs pfs = np.zeros(fsig.shape) # Resample period data (aliased) for k in range(zc.shape[0] - 1): pfs[zc[k]:zc[k + 1]] = p[k] pfs[0:zc[0]] = p[0] pfs[zc[-1]:] = p[-2] # Convert instantaneous period data to instantaneous frequency data ps = ((pfs / (fs / 1000.)) / 1000.) # The 2 here corrects for the half-period issue above f = (1. / ps) / 2. # Smooth the F0 track b, a = filters.butter(1, 16. / (fs / 2.)) f = filtfilt(b, a, f) # Voicing env = envelope(fsig, fs) env = env / np.max(np.abs(env)) # Noise gate env[20 * np.log10(env) < -noisegate] = 0 env[env > 0] = 1 # env2 = env # vonsets = array(where(sign(env[1:]) < sign(env[:-1]))).transpose()[:,0] # print vonsets # print vonsets + vdelay - 1 # skip = True # for k in range(vonsets.shape[0]): # if (skip): # env2[vonsets[k]:vonsets[k] + vdelay - 1] = 0 # skip = False # else: # skip = True # Smooth the transitions b, a = filters.butter(1, 16. / (fs / 2.)) envf = filtfilt(b, a, env) return f * np.maximum(envf, 0)
if((n-k)>= len(int_resp)): temp += 0 else: temp += data_buffer[k%64]*int_resp[n-k] data_dump[n%64] = temp; f = open('sample_vishwa.dat', 'r') data = [] for i in f.readlines(): data.append(int(i)) data_test = zeros(len(data)) data_test[0] = 1 order, Wn = fd.buttord(0.2, 0.3, 1, 10) print order, Wn b, a = fd.butter(order, Wn) response = sg.lfilter(b, a, data_test)[:256] int_resp = [] resp_file = open('impulse_response_integer.dat', 'r') for i in resp_file.readlines(): int_resp.append(int(i)) #op1 = conv(data[:1024], int_resp) f.close() op2 = range(1024) conv(data) op1 = convolve(int_resp, data) clf() plot(op1, 'r') plot(op2) show()
def hpFilt(fp, fs, nyqf, y, disp=False): nyqf = float(nyqf) ord, wn = filter_design.buttord(fp / nyqf, fs / nyqf, 1, 12, analog=0) b, a = butter(ord, wn, btype="highpass", analog=0, output='ba') fy = filtfilt(b, a, y) return fy
def butterworth(ts, cutoff_period=None, cutoff_frequency=None, order=4): """ low-pass butterworth-squared filter on a regular time series. Parameters ----------- ts : :class:`DataFrame <pandas:pandas.DataFrame>` Must be one or two dimensional, and regular. order: int ,optional The default is 4. cutoff_frequency: float,optional Cutoff frequency expressed as a ratio with Nyquist frequency, should within the range (0,1). For a discretely sampled system, the Nyquist frequency is the fastest frequency that can be resolved by that sampling, which is half the sampling frequency. For example, if the sampling frequency is 1 sample/1 hour, the Nyquist frequency is 1 sample/2 hours. If we want a 36 hour cutoff period, the frequency is 1/36 or 0.0278 cycles per hour. Hence the cutoff frequency argument used here would be 0.0278/0.5 = 0.056. cutoff_period : string or :ref:`time_interval<time_intervals>` Period corresponding to cutoff frequency. If input as a string, it must be convertible to a regular interval using the same rules as a pandas frequency.. cutoff_frequency and cutoff_period can't be specified at the same time. Returns ------- result : A new regular time series with the same interval as ts. Raise -------- ValueError If input order is not even, or input timeseries is not regular, or neither cutoff_period and cutoff_frequency is given while input time series interval is not 15min or 1 hour, or cutoff_period and cutoff_frequency are given at the same time. """ if (order % 2): raise ValueError("only even order is accepted") #if not ts.is_regular(): # raise ValueError("Only regular time series can be filtered.") freq = ts.index.freq # if (not (interval in _butterworth_interval)) and (cutoff_period is None) and (cutoff_frequency is None): # raise ValueError("time interval is not supported by butterworth if no cuttoff period/frequency given.") if (not (cutoff_frequency is None)) and (not (cutoff_period is None)): raise ValueError( "cutoff_frequency and cutoff_period can't be specified simultaneously" ) if (cutoff_frequency is None) and (cutoff_period is None): raise ValueError( "Either cutoff_frequency or cutoff_period must be given") cf = cutoff_frequency if (cf is None): if (not (cutoff_period is None)): cutoff_period = pd.tseries.frequencies.to_offset(cutoff_period) cf = 2. * freq / cutoff_period else: cf = butterworth_cutoff_frequencies[interval] ## get butter filter coefficients. [b, a] = butter(order / 2, cf) d2 = filtfilt(b, a, ts.values, axis=0, padlen=90) out = ts.copy(deep=True) out[:] = d2 # prop={} # for key,val in ts.props.items(): # prop[key]=val # prop[TIMESTAMP]=INST # prop[AGGREGATION]=INDIVIDUAL # time_interval return out
def butterworth(ts, order=4, cutoff_period=None, cutoff_frequency=None): """ low-pass butterworth-squared filter on a regular time series. Parameters ----------- ts : :class:`~vtools.data.timeseries.TimeSeries` Must has data of one dimension, and regular. order: int ,optional The default is 4. cutoff_frequency: float,optional Cutoff frequency expressed as a ratio of a Nyquist frequency, should within the range (0,1). For example, if the sampling frequency is 1 hour, the Nyquist frequency is 1 sample/2 hours. If we want a 36 hour cutoff period, the frequency is 1/36 or 0.0278 cycles per hour. Hence the cutoff frequency argument used here would be 0.0278/0.5 = 0.056. cutoff_period : string or :ref:`time_interval<time_intervals>` Period of cutting off frequency. If input as a string, it must be convertible to :ref:`Time interval<time_intervals>`. cutoff_frequency and cutoff_period can't be specified at the same time. Returns ------- result : :class:`~vtools.data.timeseries.TimeSeries` A new regular time series with the same interval of ts. Raise -------- ValueError If input order is not even, or input timeseries is not regular, or neither cutoff_period and cutoff_frequency is given while input time series interval is not 15min or 1 hour, or cutoff_period and cutoff_frequency are given at the same time. """ if (order % 2): raise ValueError("only even order is accepted") if not ts.is_regular(): raise ValueError("Only regular time series can be filtered.") interval = ts.interval if (not (interval in _butterworth_interval)) and ( cutoff_period is None) and (cutoff_frequency is None): raise ValueError( "time interval is not supported by butterworth if no cuttoff period/frequency given." ) if (not (cutoff_frequency is None)) and (not (cutoff_period is None)): raise ValueError( "cutoff_frequency and cutoff_period can't be specified simultaneously" ) cf = cutoff_frequency if (cf is None): if (not (cutoff_period is None)): ## convert it to ticks if not (is_interval(cutoff_period)): cutoff_period = parse_interval(cutoff_period) cutoff_frequency_in_ticks = 1.0 / float(ticks(cutoff_period)) nyquist_frequency = 0.5 / float(ticks(interval)) cf = cutoff_frequency_in_ticks / nyquist_frequency else: cf = butterworth_cutoff_frequencies[interval] ## get butter filter coefficients. [b, a] = butter(order / 2, cf) # d1=lfilter(b, a, ts.data,0) # d1=d1[len(d1)::-1] # d2=lfilter(b,a,d1,0) # d2=d2[len(d2)::-1] d2 = filtfilt(b, a, ts.data, axis=0) prop = {} for key, val in ts.props.items(): prop[key] = val prop[TIMESTAMP] = INST prop[AGGREGATION] = INDIVIDUAL time_interval return rts(d2, ts.start, ts.interval, prop)
def vocoder_overlap(signal, fs, channel_n, channel_width, flo, fhi): '''Prototype vocoder where channel width is independent of channel spacing That is, channels are not necessarily contiguous The channel_width parameter is in octaves, and channel cfs are logarithmically spaced from flo to fhi E.g., the following set of parameters would yield contiguous bands from 88 to 11314 Hz: psylab.signal.vocoder_overlap(sig,fs,6,1,125,8000) vocoder_overlap(signal, fs, channel_n, channel_width, flo, fhi) ''' signal = signal - np.mean(signal) cfs = np.float32(np.round(np.linspace(flo, fhi, channel_n))) cfs = logspace(flo, fhi, channel_n) cw = np.float32(channel_width / 2.) nyq = np.float32(fs / 2.) envfilter = 400. print("Channel width: {:} Oct".format(channel_width)) noisecarrier = np.random.randn(len(signal)) noisecarrier = noisecarrier / max(np.abs(noisecarrier)) summed_carriers = np.zeros(len(signal)) for cf in cfs: lo = np.round(cf * (2.**-cw)) hi = np.round(cf * (2.**cw)) print(" lo {:}; cf {:}; hi {:}".format(lo, cf, hi)) [b_band_hp, a_band_hp] = filters.butter(3, (lo / nyq), btype='high') [b_band_lp, a_band_lp] = filters.butter(3, (hi / nyq)) [b_wind_hp, a_wind_hp] = filters.butter(1, (cf / nyq), btype='high') [b_wind_lp, a_wind_lp] = filters.butter(1, (cf / nyq)) [b_env, a_env] = filters.butter(2, min((.5 * (hi - lo)), envfilter) / nyq) # Filter signal into sub-band Sig_band = lfilter(b_band_hp, a_band_hp, signal) Sig_band = lfilter(b_band_lp, a_band_lp, Sig_band) # Apply window to shape band Sig_band = lfilter(b_wind_hp, a_wind_hp, Sig_band) Sig_band = lfilter(b_wind_lp, a_wind_lp, Sig_band) # Extract envelope rms_Sig_band = np.sqrt(np.mean(Sig_band**2)) Sig_env_band = lfilter(b_env, a_env, np.maximum(Sig_band, 0)) # Prefilter, modulate carrier Mod_carrier = filtfilt(b_band_hp, a_band_hp, noisecarrier) Mod_carrier = filtfilt(b_band_lp, a_band_lp, Mod_carrier) * Sig_env_band # Post filter Mod_carrier_filt = lfilter(b_band_hp, a_band_hp, Mod_carrier) Mod_carrier_filt = lfilter(b_band_lp, a_band_lp, Mod_carrier_filt) summed_carriers += Mod_carrier / np.sqrt(np.mean(Mod_carrier** 2)) * rms_Sig_band return summed_carriers * (np.sqrt(np.mean(signal**2)) / np.sqrt(np.mean(summed_carriers**2)))
def vocoder(signal, fs, channels, inlo, inhi, **kwargs): '''Implements an envelope vocoder Vocodes the input signal using specified parameters. You can specify a different frequency range for both input (analysis) and output, for a given number of channels (the output frequency range values default to input values). Both input and output channels are distributed contiguously on a log scale across the respective frequency ranges. Carriers can be pure tones (at the arithmetic center of each band) or noise bands (which are as wide as the output channel). The envelope cutoff frequency defaults to 400 Hz, but is never more than half the output-channel bandwidth. Parameters ---------- signal : array The input signal fs : scalar The sampling frequency channels : scalar The number of vocoder channels inlo : scalar Low-side (start) frequency of the analysis channels inhi : scalar High-side (end) frequency of the analysis channels Kwargs ------ outlo : scalar Low-side (start) frequency of the output channels [ default = inlo ] outhi : scalar High-side (end) frequency of the output channels [ default = inhi ] compression_ratio : scalar Compression ration: input / output [ default = 1 ] gate : scalar A gate to apply to each envelope. Values below gate are set to 0 [ default = 0 ] envfilter : scalar Low-pass cutoff frequency of the envelope extraction filter [ default = 400 ] noise : bool False for sinusoidal carriers [ default ] True for noise band carriers sumchannels : bool False to return a 2-d array in which each output channel is a column True to return a 1-d array containing the summed output channels. The rms will be equated to the rms of the input [ default ] order : int The filter order to use [ default = 3 ] Returns ------- y : array The vocoded signal Notes ----- Depends on tone.py ''' outlo = kwargs.get('outlo', inlo) outhi = kwargs.get('outhi', inhi) envfilter = kwargs.get('envfilter', 400) noise = kwargs.get('noise', False) sumchannels = kwargs.get('sumchannels', True) ord = kwargs.get('order', 3) compression_ratio = kwargs.get('compression_ratio', 1) gate = kwargs.get('gate', None) if noise: noisecarrier = np.random.randn(len(signal)) noisecarrier = noisecarrier / max(np.abs(noisecarrier)) signal = signal - np.mean(signal) nyq = np.float32(fs / 2.) ininterval = np.log10( np.float32(inhi) / np.float32(inlo)) / np.float32(channels) outinterval = np.log10( np.float32(outhi) / np.float32(outlo)) / np.float32(channels) if sumchannels: carriers = np.zeros(len(signal)) else: carriers = np.zeros((len(signal), channels)) ret = np.zeros((len(signal), channels)) for i in range(channels): # Estimate filters finhi = np.float32(inlo) * 10.**(ininterval * (i + 1)) finlo = np.float32(inlo) * 10.**(ininterval * i) fouthi = np.float32(outlo) * 10.**(outinterval * (i + 1)) foutlo = np.float32(outlo) * 10.**(outinterval * i) fcarrier = .5 * (fouthi + foutlo) [b_sub_hp, a_sub_hp] = filters.butter(ord, (finlo / nyq), btype='high') [b_sub_lp, a_sub_lp] = filters.butter(ord, (finhi / nyq)) [b_env, a_env ] = filters.butter(2, min((.5 * (fouthi - foutlo)), envfilter) / nyq) [b_out_hp, a_out_hp] = filters.butter(ord, (foutlo / nyq), btype='high') [b_out_lp, a_out_lp] = filters.butter(ord, (fouthi / nyq)) ## Filter input Sig_sub = lfilter(b_sub_hp, a_sub_hp, signal) Sig_sub = lfilter(b_sub_lp, a_sub_lp, Sig_sub) # ret[:,i] = Sig_sub.copy() rms_Sig_sub = np.sqrt(np.mean(Sig_sub**2)) Sig_env_sub = lfilter(b_env, a_env, np.maximum(Sig_sub, 0)) peak = Sig_env_sub.max() Sig_env_sub /= compression_ratio Sig_env_sub += peak - Sig_env_sub.max() if gate is not None: db = 20 * np.log10(Sig_env_sub / peak) Sig_env_sub[db < gate] = 0 if noise: Mod_carrier = filtfilt(b_out_hp, a_out_hp, noisecarrier) Mod_carrier = filtfilt(b_out_lp, a_out_lp, Mod_carrier) * Sig_env_sub else: Mod_carrier = tone(np.ones(len(signal)) * fcarrier, fs, 1) * Sig_env_sub ## Filter output Mod_carrier_filt = lfilter(b_out_hp, a_out_hp, Mod_carrier) Mod_carrier_filt = lfilter(b_out_lp, a_out_lp, Mod_carrier_filt) if sumchannels: carriers += Mod_carrier_filt / np.sqrt(np.mean(Mod_carrier_filt** 2)) * rms_Sig_sub else: carriers[:, i] = Mod_carrier_filt / np.sqrt( np.mean(Mod_carrier_filt**2)) * rms_Sig_sub # return ret if sumchannels: return carriers * (np.sqrt(np.mean(signal**2)) / np.sqrt(np.mean(carriers**2))) else: return carriers