def display_observation(signal_large, f_min, f_max, fs, window_size_t, config, figure_title, figure_path): """ Function used to display an observation, either to make observations to annotate, either to check predictions """ # Get spectrofram window spectro_window_size = config.display['spectro_window_size'] if config.display['window_type'] == 'kaiser': w = sg.kaiser(spectro_window_size, 18) w = w * spectro_window_size / sum([pow(j, 2) for j in w]) else: print('window %s not implemented yet' % config.display['window_type']) return None # Get signal that will be displayed from input signal if config.display['decimate_factor'] is None: spectro_signal = signal_large fs_spectro = fs else: spectro_signal = sg.decimate(signal_large, config.display['decimate_factor'], zero_phase=True) fs_spectro = int(fs / config.display['decimate_factor']) # Compute spectrogram f, time, spec = sg.spectrogram( spectro_signal, fs=fs_spectro, nperseg=eval(config.display['nperseg']), noverlap=eval(config.display['noverlap']), nfft=eval(config.display['nfft']), window=w, scaling=config.display['scaling']) # PSD in unit(x)**2/Hz if eval(config.display['dB']): spec_db = 10 * np.log10(spec) # Make figure and all the proper display on it fig = plt.figure(figsize=(15, 6)) ax = fig.add_subplot(111) plt.pcolormesh(time, f, spec_db, shading='flat', vmin=30, vmax=85) cbar = plt.colorbar() cbar.set_label('Energy (dB)', size=25) cbar.ax.tick_params(labelsize=25) plt.xlabel('Time (s)', size=25) plt.ylabel('Frequency (Hz)', size=25) ax.tick_params(labelsize=25) # Plot the rectangle (observation) height = f_max - f_min plt.title(figure_title, size=25) my_rectangle = patches.Rectangle((window_size_t, f_min), window_size_t, height, alpha=1, facecolor='none', edgecolor='red', linewidth=5) ax.add_patch(my_rectangle) # Save everything plt.savefig(figure_path + '.png', format='png') plt.close('all') # And off you go ! return
def freq_from_hps(signal, fs): """ Estimate frequency using harmonic product spectrum - also not working so well Low frequency noise piles up and overwhelms the peaks? """ N = len(signal) signal -= np.mean(signal) # Remove DC offset # Compute Fourier transform of windowed signal windowed = signal * kaiser(N, 100) # Get spectrum X = np.log(abs(rfft(windowed))) # Downsample sum logs of spectra instead of multiplying hps = np.copy(X) for h in np.arange(2, 9): # TODO: choose a smarter upper limit dec = decimate(X, h) hps[:len(dec)] += dec # Find the peak and interpolate to get a more accurate peak i_peak = np.argmax(hps[:len(dec)]) i_interp = parabolic(hps, i_peak)[0] # Convert to equivalent frequency return fs * i_interp / N # Hz
def freq_from_hps(signal, fs): """ Original by endolith: https://github.com/endolith/waveform_analysis/blob/master/waveform_analysis/freq_estimation.py Estimate frequency using harmonic product spectrum Low frequency noise piles up and overwhelms the desired peaks Doesn't work well if signal doesn't have harmonics """ signal = np.asarray(signal) + 0.0 N = len(signal) signal -= np.mean(signal) # Remove DC offset # Compute Fourier transform of windowed signal windowed = signal * kaiser(N, 100) # Get spectrum X = np.log(abs(rfft(windowed))) # Remove np.mean of spectrum (so sum is not increasingly offset # only in overlap region) X -= np.mean(X) # Downsample sum np.logs of spectra instead of multiplying hps = np.copy(X) for h in range(2, 9): # TODO: choose a smarter upper limit dec = decimate(X, h, zero_phase=True) hps[:len(dec)] += dec # Find the peak and interpolate to get a more accurate peak i_peak = np.argmax(hps[:len(dec)]) i_interp = parabolic(hps, i_peak)[0] # Convert to equivalent frequency return fs * i_interp / N # Hz
def scope_analyzethd(data, channel): signal = (data[channel - 1] - numpy.mean(data[channel - 1])) * kaiser( len(data[channel - 1]), 100) signal_f = numpy.fft.rfft(signal) fidx = numpy.argmax(abs(signal_f)) return sum([abs(signal_f[i * fidx]) for i in range(2, 10)]) / abs(signal_f[fidx])
def taper(flag, m, samples): # m = samples for taper # samples = total samples window = kaiser(2 * m + 1, beta=14) if flag == 'front': # cut and replace the second half of window with 1s ones = np.ones(samples - m - 1) window = window[0:(m + 1)] window = np.concatenate([window, ones]) elif flag == 'end': # cut and replace the first half of window with 1s ones = np.ones(samples - m - 1) window = window[(m + 1):] window = np.concatenate([ones, window]) elif flag == 'all': ones = np.ones(samples - 2 * m - 1) window = np.concatenate([window[0:(m + 1)], ones, window[(m + 1):]]) # avoid concatenate error if window.size < samples: window = np.append(window, 1) if window.size != samples: print(window.size) print(samples) print( "[ERROR]: taper and data do not have the same number of samples.") window = np.ones(samples) return window
def firwin_kaiser_hpf(f_stop, f_pass, d_stop, fs = 1.0, N_bump=0, status = True): """ Design an FIR highpass filter using the sinc() kernel and a Kaiser window. The filter order is determined based on f_pass Hz, f_stop Hz, and the desired stopband attenuation d_stop in dB, all relative to a sampling rate of fs Hz. Note: the passband ripple cannot be set independent of the stopband attenuation. Mark Wickert October 2016 """ # Transform HPF critical frequencies to lowpass equivalent f_pass_eq = fs/2. - f_pass f_stop_eq = fs/2. - f_stop # Design LPF equivalent wc = 2*np.pi*(f_pass_eq + f_stop_eq)/2/fs delta_w = 2*np.pi*(f_stop_eq - f_pass_eq)/fs # Find the filter order M = np.ceil((d_stop - 8)/(2.285*delta_w)) # Adjust filter order up or down as needed M += N_bump N_taps = M + 1 # Obtain the Kaiser window beta = signal.kaiser_beta(d_stop) w_k = signal.kaiser(N_taps,beta) n = np.arange(N_taps) b_k = wc/np.pi*np.sinc(wc/np.pi*(n-M/2)) * w_k b_k /= np.sum(b_k) # Transform LPF equivalent to HPF n = np.arange(len(b_k)) b_k *= (-1)**n if status: log.info('Kaiser Win filter taps = %d.' % N_taps) return b_k
def test_spectrogram_energy_conservation(self): """Test the energy conservation property of the spectrogram.""" signal, _ = fmlin(128, 0.1, 0.4) window = kaiser(17, 3 * np.pi) tfr, ts, freqs = cohen.Spectrogram(signal, n_fbins=64, fwindow=window).run() e_sig = (np.abs(signal) ** 2).sum() self.assertAlmostEqual(tfr.sum().sum() / 64, e_sig)
def __init_weight(self): """ :return: (window_len,) numpy.array """ filter_len = 2 * self.window_len if self.init_dist == 'gaussian': window = signal.gaussian(filter_len, std=10) elif self.init_dist == 'kaiser': window = signal.kaiser(filter_len, beta=14) else: # uniform window = np.ones(filter_len) if self.attention_to == 'right': window = window[:self.window_len] elif self.attention_to == 'left': window = window[self.window_len:] else: # middle window = window[self.window_len // 4:self.window_len // 4 + self.window_len] window = torch.from_numpy(window).float() if self.train_weights: window = nn.Parameter(window).to(device) return window
def apply_kaiserbessel_window(X, alpha=6.5): """ Apply a Kaiser-Bessel window to X. Parameters ---------- X : ndarray, shape=(n_samples, n_features) Input array of samples alpha : float, optional (default=6.5) Tuning parameter for Kaiser-Bessel function. alpha=6.5 should make perfect reconstruction possible for MDCT. Returns ------- X_windowed : ndarray, shape=(n_samples, n_features) Windowed version of X. """ beta = np.pi * alpha win = sg.kaiser(X.shape[1], beta) row_stride = 0 col_stride = win.itemsize strided_win = as_strided(win, shape=X.shape, strides=(row_stride, col_stride)) return X * strided_win
def freq_from_hps(signal, fs): """ Estimate frequency using harmonic product spectrum Low frequency noise piles up and overwhelms the desired peaks Doesn't work well if signal doesn't have harmonics """ signal = asarray(signal) + 0.0 N = len(signal) signal -= mean(signal) # Remove DC offset # Compute Fourier transform of windowed signal windowed = signal * kaiser(N, 100) # Get spectrum X = log(abs(rfft(windowed))) # Remove mean of spectrum (so sum is not increasingly offset # only in overlap region) X -= mean(X) # Downsample sum logs of spectra instead of multiplying hps = copy(X) for h in range(2, 9): # TODO: choose a smarter upper limit dec = decimate(X, h, zero_phase=True) hps[:len(dec)] += dec # Find the peak and interpolate to get a more accurate peak i_peak = argmax(hps[:len(dec)]) i_interp = parabolic(hps, i_peak)[0] # Convert to equivalent frequency return fs * i_interp / N # Hz
def freq_from_fft(signal, fs): """ Estimate frequency from peak of FFT Pros: Accurate, usually even more so than zero crossing counter (1000.000004 Hz for 1000 Hz, for instance). Due to parabolic interpolation being a very good fit for windowed log FFT peaks? https://ccrma.stanford.edu/~jos/sasp/Quadratic_Interpolation_Spectral_Peaks.html Accuracy also increases with signal length Cons: Doesn't find the right value if harmonics are stronger than fundamental, which is common. """ signal = asarray(signal) N = len(signal) # Compute Fourier transform of windowed signal windowed = signal * kaiser(N, 100) f = rfft(windowed) # Find the peak and interpolate to get a more accurate peak i_peak = argmax(abs(f)) # Just use this value for less-accurate result i_interp = parabolic(log(abs(f)), i_peak)[0] # Convert to equivalent frequency return fs * i_interp / N # Hz
def firwin_kaiser_hpf(f_stop, f_pass, d_stop, fs = 1.0, N_bump=0): """ Design an FIR highpass filter using the sinc() kernel and a Kaiser window. The filter order is determined based on f_pass Hz, f_stop Hz, and the desired stopband attenuation d_stop in dB, all relative to a sampling rate of fs Hz. Note: the passband ripple cannot be set independent of the stopband attenuation. Mark Wickert October 2016 """ # Transform HPF critical frequencies to lowpass equivalent f_pass_eq = fs/2. - f_pass f_stop_eq = fs/2. - f_stop # Design LPF equivalent wc = 2*np.pi*(f_pass_eq + f_stop_eq)/2/fs delta_w = 2*np.pi*(f_stop_eq - f_pass_eq)/fs # Find the filter order M = np.ceil((d_stop - 8)/(2.285*delta_w)) # Adjust filter order up or down as needed M += N_bump N_taps = M + 1 # Obtain the Kaiser window beta = signal.kaiser_beta(d_stop) w_k = signal.kaiser(N_taps,beta) n = np.arange(N_taps) b_k = wc/np.pi*np.sinc(wc/np.pi*(n-M/2)) * w_k b_k /= np.sum(b_k) # Transform LPF equivalent to HPF n = np.arange(len(b_k)) b_k *= (-1)**n print('Kaiser Win filter taps = %d.' % N_taps) return b_k
def firwin_kaiser_lpf(f_pass, f_stop, d_stop, fs = 1.0, N_bump=0): """ Design an FIR lowpass filter using the sinc() kernel and a Kaiser window. The filter order is determined based on f_pass Hz, f_stop Hz, and the desired stopband attenuation d_stop in dB, all relative to a sampling rate of fs Hz. Note: the passband ripple cannot be set independent of the stopband attenuation. Mark Wickert October 2016 """ wc = 2*np.pi*(f_pass + f_stop)/2/fs delta_w = 2*np.pi*(f_stop - f_pass)/fs # Find the filter order M = np.ceil((d_stop - 8)/(2.285*delta_w)) # Adjust filter order up or down as needed M += N_bump N_taps = M + 1 # Obtain the Kaiser window beta = signal.kaiser_beta(d_stop) w_k = signal.kaiser(N_taps,beta) n = np.arange(N_taps) b_k = wc/np.pi*np.sinc(wc/np.pi*(n-M/2)) * w_k b_k /= np.sum(b_k) print('Kaiser Win filter taps = %d.' % N_taps) return b_k
def freq_from_hps(signal, fs): """Estimate frequency using harmonic product spectrum Low frequency noise piles up and overwhelms the desired peaks """ N = len(signal) signal -= mean(signal) # Remove DC offset # Compute Fourier transform of windowed signal windowed = signal * kaiser(N, 100) # Get spectrum X = log(abs(rfft(windowed))) # Downsample sum logs of spectra instead of multiplying hps = copy(X) for h in arange(2, 9): # TODO: choose a smarter upper limit dec = decimate(X, h) hps[:len(dec)] += dec # Find the peak and interpolate to get a more accurate peak i_peak = argmax(hps[:len(dec)]) i_interp = parabolic(hps, i_peak)[0] # Convert to equivalent frequency return fs * i_interp / N # Hz
def hps_method(frame, rate): N = len(frame) # De-mean the frame frame -= np.mean(frame, dtype=np.int16) # Apply a window to the frame windowed_frame = frame * kaiser(N, 100) # Compute the real fft and get the spectrum spectrum = np.log(np.abs(np.fft.rfft(windowed_frame))) hps = np.copy(spectrum) # Downsample the spectrum and add the log of spectrum instead # of multiplying for i in range(2, 5): y = decimate(spectrum, i) hps[:len(y)] += y # Find the highest peak and interpolate to get a more accurate result peak = np.argmax(hps[:len(y)]) interp = parabolic(hps, peak)[0] # Convert to the corresponding frequency f0 = rate * interp / N # Process the interpolated result if np.max(hps) > 45 and f0 > 50 and f0 < 550: return f0 else: return 0
def THD(signal, sample_rate): """Measure the THD for a signal This function is not yet trustworthy. Returns the estimated fundamental frequency and the measured THD, calculated by finding peaks in the spectrum. There are two definitions for THD, a power ratio or an amplitude ratio When finished, this will list both """ # Get rid of DC and window the signal signal -= mean(signal) # TODO: Do this in the frequency domain, and take any skirts with it? windowed = signal * kaiser(len(signal), 100) # Find the peak of the frequency spectrum (fundamental frequency) f = rfft(windowed) i = argmax(abs(f)) true_i = parabolic(log(abs(f)), i)[0] print 'Frequency: %f Hz' % (sample_rate * (true_i / len(windowed))) print 'fundamental amplitude: %.3f' % abs(f[i]) # Find the values for the first 15 harmonics. Includes harmonic peaks only, by definition # TODO: Should peak-find near each one, not just assume that fundamental was perfectly estimated. # Instead of limited to 15, figure out how many fit based on f0 and sampling rate and report this "4 harmonics" and list the strength of each for x in range(2, 15): print '%.3f' % abs(f[i * x]), THD = sum([abs(f[i*x]) for x in range(2,15)]) / abs(f[i]) print '\nTHD: %f%%' % (THD * 100) return
def spec_est(x, fs, ref=2**15, plot=False): N = len(x) # Apply window window = signal.kaiser(N, beta=38) # x = multiply(x, window) # Use FFT to get the amplitude of the spectrum ampl = 1 / N * absolute(fft(x)) ampl = 20 * log10(ampl / ref + 10**-20) # FFT frequency bins freqs = fftfreq(N, 1 / fs) if plot: # Plot signal, showing how endpoints wrap from one chunk to the next import matplotlib.pyplot as plt plt.subplot(2, 1, 1) plt.plot(x, ".-") plt.plot(1, 1, "r.") # first sample of next chunk plt.margins(0.1, 0.1) plt.xlabel("Time [s]") # Plot shifted data on a shifted axis plt.subplot(2, 1, 2) plt.plot(fftshift(freqs), fftshift(ampl)) plt.margins(0.1, 0.1) plt.xlabel("Frequency [Hz]") plt.tight_layout() plt.show() return ampl, freqs
def firwin_kaiser_lpf(f_pass, f_stop, d_stop, fs = 1.0, N_bump=0, status = True): """ Design an FIR lowpass filter using the sinc() kernel and a Kaiser window. The filter order is determined based on f_pass Hz, f_stop Hz, and the desired stopband attenuation d_stop in dB, all relative to a sampling rate of fs Hz. Note: the passband ripple cannot be set independent of the stopband attenuation. Mark Wickert October 2016 """ wc = 2*np.pi*(f_pass + f_stop)/2/fs delta_w = 2*np.pi*(f_stop - f_pass)/fs # Find the filter order M = np.ceil((d_stop - 8)/(2.285*delta_w)) # Adjust filter order up or down as needed M += N_bump N_taps = M + 1 # Obtain the Kaiser window beta = signal.kaiser_beta(d_stop) w_k = signal.kaiser(N_taps,beta) n = np.arange(N_taps) b_k = wc/np.pi*np.sinc(wc/np.pi*(n-M/2)) * w_k b_k /= np.sum(b_k) if status: log.info('Kaiser Win filter taps = %d.' % N_taps) return b_k
def taper(flag, m, samples): # m = samples for taper # samples = total samples window = kaiser(2*m+1, beta=14) if flag == 'front': # cut and replace the second half of window with 1s ones = np.ones(samples-m-1) window = window[0:(m+1)] window = np.concatenate([window, ones]) elif flag == 'end': # cut and replace the first half of window with 1s ones = np.ones(samples-m-1) window = window[(m+1):] window = np.concatenate([ones, window]) elif flag == 'all': ones = np.ones(samples-2*m-1) window = np.concatenate([window[0:(m+1)], ones, window[(m+1):]]) # avoid concatenate error if window.size < samples: window = np.append(window, 1) if window.size != samples: print(window.size) print(samples) print("[ERROR]: taper and data do not have the same number of samples.") window = np.ones(samples) return window
def design_prototype_filter(taps=62, cutoff_ratio=0.142, beta=9.0): """Design prototype filter for PQMF. This method is based on `A Kaiser window approach for the design of prototype filters of cosine modulated filterbanks`_. Args: taps (int): The number of filter taps. cutoff_ratio (float): Cut-off frequency ratio. beta (float): Beta coefficient for kaiser window. Returns: ndarray: Impluse response of prototype filter (taps + 1,). .. _`A Kaiser window approach for the design of prototype filters of cosine modulated filterbanks`: https://ieeexplore.ieee.org/abstract/document/681427 """ # check the arguments are valid assert taps % 2 == 0, "The number of taps mush be even number." assert 0.0 < cutoff_ratio < 1.0, "Cutoff ratio must be > 0.0 and < 1.0." # make initial filter omega_c = np.pi * cutoff_ratio with np.errstate(invalid='ignore'): h_i = np.sin(omega_c * (np.arange(taps + 1) - 0.5 * taps)) \ / (np.pi * (np.arange(taps + 1) - 0.5 * taps)) h_i[taps // 2] = np.cos(0) * cutoff_ratio # fix nan due to indeterminate form # apply kaiser window w = kaiser(taps + 1, beta) h = h_i * w return h
def narrow_band(self): """create an narrow banded pulse to specs""" xmitt = np.sin(2 * pi * self.fc * self.time) # window is unknown, assuming a pretty narrow mainlobe window = sig.kaiser(self.time.size, 1.0 * pi) xmitt *= window return xmitt
def freq_from_hps(signal, fs): """Estimate frequency using harmonic product spectrum Low frequency noise piles up and overwhelms the desired peaks """ N = len(signal) signal -= mean(signal) # Remove DC offset # Compute Fourier transform of windowed signal windowed = signal * kaiser(N, 100) # Get spectrum X = log(abs(rfft(windowed))) # Remove mean of spectrum (so sum is not increasingly offset # only in overlap region) X -= mean(X) # Downsample sum logs of spectra instead of multiplying hps = copy(X) for h in arange(2, 9): # TODO: choose a smarter upper limit h = int(h) # https://github.com/scipy/scipy/pull/7351 dec = decimate(X, h, zero_phase=True) hps[:len(dec)] += dec # Find the peak and interpolate to get a more accurate peak i_peak = argmax(hps[:len(dec)]) i_interp = parabolic(hps, i_peak)[0] # Convert to equivalent frequency return fs * i_interp / N # Hz
def doppler_cpi_estimate(rp, fft_interp=1, fft_oversample=0, window='hann', findpeak='max'): """ Doppler fine-resolution cell estimation on MMV frames [note] using theoretical frequency resolution. Theoretical resolution is proportional to accumulation time only. So, if you using (interp) in RD plane, it should be multiply by fft_interp = int(n_doppler / n_pulse) before calculating the real-frequency """ n_frame = len(rp) n_slowfft = int(2**(np.ceil(np.log2(n_frame)) + fft_oversample)) freqs = fft_interp * np.fft.fftfreq(n_slowfft) # windowing signal before FFT if window == 'hann': window_fcn = signal.hann(n_frame, sym=False) elif window == 'gauss': window_fcn = signal.gaussian(n_frame, 16) elif window == 'kaiser': window_fcn = signal.kaiser(n_frame, 3.5) else: window_fcn = np.ones(n_frame) rp_win = rp * window_fcn # find the peak of FFT fine-resoluted spectrum rp_fft = np.fft.fft(rp_win, n_slowfft) vv = doppler_fftpeak(rp_fft, freqs, method=findpeak) return vv
def spectrum_wwind(array, time, window='hanning'): # time should be in seconds # Size of array Nw = array.shape[0] # Calculate time step (assumed to be in seconds) dt = time[1] - time[0] # prefactor # print 'dt = ',dt prefactor = dt # Calculate array of frequencies, shift w = np.fft.fftfreq(Nw, dt) w0 = np.fft.fftshift(w) # make window # blackman window if window == 'blackman': bwin = blackman(Nw) # pretty good if window == 'hanning': bwin = hanning(Nw) # pretty good if window == 'hamming': bwin = hamming(Nw) # not as good if window == 'bartlett': bwin = bartlett(Nw) # pretty good if window == 'kaiser': bwin = kaiser(Nw, 6) if window == 'None': bwin = 1.0 # Calculate FFT aw = prefactor * np.fft.fft(array * bwin) aw0 = np.fft.fftshift(aw) # Calcuate Phase phase = np.angle(aw) phase0 = np.fft.fftshift(phase) # Adjust arrays if not div by 2 if not np.mod(Nw, 2): w0 = np.append(w0, -w0[0]) aw0 = np.append(aw0, -aw0[0]) phase0 = np.append(phase0, -phase0[0]) # Cut FFTs in half Nwi = Nw // 2 w2 = w0[Nwi:] aw2 = aw0[Nwi:] phase2 = phase0[Nwi:] comp = aw pwr = (np.abs(aw2))**2 pwr2 = (np.abs(aw))**2 mag = np.sqrt(pwr) cos_phase = np.cos(phase2) freq = w2 freq2 = w return freq, freq2, comp, pwr, mag, phase2, cos_phase, dt
def test_spectrogram_linearity(self): signal, _ = fmlin(128, 0.1, 0.4) window = kaiser(17, 3 * np.pi) tfr1, _, _ = cohen.spectrogram(signal, n_fbins=64, window=window) tfr2, _, _ = cohen.spectrogram(signal * 2, n_fbins=64, window=window) x = np.sum(np.sum(tfr2)) y = np.sum(np.sum(tfr1)) self.assertEqual(x / y, 4)
def data_oneTime_filter(close, window_size, window_beta): window_array = signal.kaiser(window_size, beta=window_beta) close_filtered = signal.convolve(close, window_array, mode='same') / sum(window_array) if window_size % 2 == 0: cutExtraDays_for_FilteredClose = list(close_filtered)[int(window_size / 2):-int(window_size / 2 - 1)] # else: cutExtraDays_for_FilteredClose = list(close_filtered)[int(window_size / 2):-int(window_size / 2)] # return cutExtraDays_for_FilteredClose
def buildGateKB2(self): NKaiser = 200 littleKaiser = kaiser(2 * NKaiser, 6, sym=True) myWindowLittleKaiser = np.zeros(self.N) myWindowLittleKaiser[0] = 1 myWindowLittleKaiser[1:NKaiser + 1] = littleKaiser[NKaiser:] myWindowLittleKaiser[self.N - NKaiser:] = littleKaiser[0:NKaiser] fftMyGateLittleKaiser = self.fft * myWindowLittleKaiser self.gateKB2 = np.fft.ifft(fftMyGateLittleKaiser)
def upsampling_filter(upsamp_factor, half_transition_width, tolerance=0.1, plot=False): if (upsamp_factor == 1): return [1.0] if half_transition_width > 1.0: raise ValueError('half_transition_width > 1.0') attenuation = -20.0 * np.log10(tolerance) #print 'attenuation', attenuation #beta = kaiser_beta(FILTER_ATTENUATION) w_size, beta = kaiserord(attenuation, width=(half_transition_width * 2.0 / upsamp_factor)) #print 'window size:', w_size, 'beta:', beta w_size = int( np.ceil((w_size - 1) / (2.0 * upsamp_factor)) * 2.0 * upsamp_factor + 1.0) #print 'new window size:', w_size w = kaiser(w_size, beta) num_periods = (w_size - 1) / (2.0 * upsamp_factor) x = np.linspace(-num_periods, num_periods, w_size) s = np.sinc(x) coef = s * w if plot: plt.figure(figsize=(12, 6), dpi=85) plt.stem(np.arange(0, len(w)), w) plt.title('Kaiser window size=' + str(w_size) + ' beta=' + str(beta)) plt.figure(figsize=(12, 6), dpi=85) plt.stem(x, s) plt.title('Sinc period=' + str(upsamp_factor)) plt.grid(True) plt.figure(figsize=(12, 6), dpi=85) plt.stem(x, coef) plt.title('Windowed sinc') plt.grid(True) freq, h = freqz(coef, worN=4096) ft = 0.5 / upsamp_factor plt.figure(figsize=(12, 6), dpi=85) plt.plot(freq / (2.0 * np.pi), abs(h) / upsamp_factor, 'k', [0.0, ft], [1.0 + tolerance, 1.0 + tolerance], 'r', [0.0, ft], [1.0 - tolerance, 1.0 - tolerance], 'r', [ft, 0.5], [tolerance, tolerance], 'r', [ft, ft], [0.0, 1.0], 'r') plt.title('Filter freq. response') plt.grid(True) return coef
def calc_freq_fft(signal): N = len(signal) # Compute Fourier transform of windowed signal windowed = signal * ss.kaiser(N, 100) f = np.fft.rfft(windowed) # Find the peak and interpolate to get a more accurate peak i_peak = np.argmax(abs(f)) # Just use this value for less-accurate result i_interp = parabolic(np.log(abs(f)), i_peak)[0] # Convert to equivalent frequency return sample_rate * i_interp / N # Hz
def firwin_kaiser_bsf(f_stop1, f_pass1, f_pass2, f_stop2, d_stop, fs=1.0, n_bump=0, status=True): """ Design an FIR bandstop filter using the sinc() kernel and a Kaiser window. The filter order is determined based on f_stop1 Hz, f_pass1 Hz, f_pass2 Hz, f_stop2 Hz, and the desired stopband attenuation d_stop in dB for both stopbands, all relative to a sampling rate of fs Hz. Note: The passband ripple cannot be set independent of the stopband attenuation. Note: The filter order is forced to be even (odd number of taps) so there is a center tap that can be used to form 1 - H_BPF. Mark Wickert October 2016 """ # First design a BPF starting from simple LPF equivalent # The upper and lower stopbands are assumed to have # the same attenuation level. The LPF equivalent critical # frequencies: f_pass = (f_pass2 - f_pass1) / 2 f_stop = (f_stop2 - f_stop1) / 2 # Continue to design equivalent LPF wc = 2 * np.pi * (f_pass + f_stop) / 2 / fs delta_w = 2 * np.pi * (f_stop - f_pass) / fs # Find the filter order M = np.ceil((d_stop - 8) / (2.285 * delta_w)) # Adjust filter order up or down as needed M += n_bump # Make filter order even (odd number of taps) if ((M + 1) / 2.0 - int((M + 1) / 2.0)) == 0: M += 1 N_taps = M + 1 # Obtain the Kaiser window beta = signal.kaiser_beta(d_stop) w_k = signal.kaiser(N_taps, beta) n = np.arange(N_taps) b_k = wc / np.pi * np.sinc(wc / np.pi * (n - M / 2)) * w_k b_k /= np.sum(b_k) # Transform LPF to BPF f0 = (f_pass2 + f_pass1) / 2 w0 = 2 * np.pi * f0 / fs n = np.arange(len(b_k)) b_k_bs = 2 * b_k * np.cos(w0 * (n - M / 2)) # Transform BPF to BSF via 1 - BPF for odd N_taps b_k_bs = -b_k_bs b_k_bs[int(M / 2)] += 1 if status: log.info('Kaiser Win filter taps = %d.' % N_taps) return b_k_bs
def downsampling_filter(decimation_factor, half_transition_width, tolerance=0.1, plot=False): if (decimation_factor == 1): return [1.0] if half_transition_width > 1.0: raise ValueError('half_transition_width > 1.0') attenuation = -20.0 * np.log10(tolerance) w_size, beta = kaiserord(attenuation, width=(half_transition_width * 2.0 / decimation_factor)) print('window size: {} beta: {}'.format(w_size, beta)) w_size = int( np.ceil((w_size - 1) / (2.0 * decimation_factor)) * 2.0 * decimation_factor + 1.0) print('new window size: {}'.format(w_size)) w = kaiser(w_size, beta) num_periods = (w_size - 1) / (2.0 * decimation_factor) x = np.linspace(-num_periods, num_periods, w_size) s = np.sinc(x) / decimation_factor coef = s * w if plot: plt.figure(figsize=(12, 6), dpi=85) plt.stem(np.arange(0, len(w)), w) plt.title('Kaiser window size=' + str(w_size) + ' beta=' + str(beta)) plt.grid(True) plt.figure(figsize=(12, 6), dpi=85) plt.stem(x, s) plt.title('Sinc period=' + str(decimation_factor)) plt.grid(True) plt.figure(figsize=(12, 6), dpi=85) plt.stem(x, coef) plt.title('Windowed sinc') plt.grid(True) freq, h = freqz(coef, worN=4096) ft = 0.5 / decimation_factor plt.figure(figsize=(12, 6), dpi=85) cf = 1.0 / decimation_factor plt.plot(freq / (2.0 * np.pi), abs(h) / decimation_factor, 'k', [0.0, ft], [cf + tolerance, cf + tolerance], 'r', [0.0, ft], [cf - tolerance, cf - tolerance], 'r', [ft, 0.5], [tolerance, tolerance], 'r', [ft, ft], [0.0, cf], 'r') plt.title('Filter freq. response') plt.grid(True) return coef
def test_spectrogram_linearity(self): """Test the linearity property of the spectrogram.""" signal, _ = fmlin(128, 0.1, 0.4) window = kaiser(17, 3 * np.pi) tfr1, _, _ = cohen.Spectrogram(signal, n_fbins=64, fwindow=window).run() tfr2, _, _ = cohen.Spectrogram(signal * 2, n_fbins=64, fwindow=window).run() x = np.sum(np.sum(tfr2)) y = np.sum(np.sum(tfr1)) self.assertEqual(x / y, 4)
def buildGateKB(self): # scipy.signal.kaiser(M, beta, sym=True) # **SYM** When True (default), generates a symmetric window, for use in filter design. # When False, generates a periodic window, for use in spectral analysis beta = 6 myWindow = np.zeros(self.N) myWindow[0] = 1 myWindow[1:] = np.fft.fftshift(kaiser(self.N - 1, beta, sym=True)) modMyWindow = 20 * np.log10(np.abs(myWindow)) self.fftKB = np.fft.fft(self.gate) * myWindow self.gateKB = np.fft.ifft(self.fftKB)
def test_basic(self): assert_allclose(signal.kaiser(6, 0.5), [0.9403061933191572, 0.9782962393705389, 0.9975765035372042, 0.9975765035372042, 0.9782962393705389, 0.9403061933191572]) assert_allclose(signal.kaiser(7, 0.5), [0.9403061933191572, 0.9732402256999829, 0.9932754654413773, 1.0, 0.9932754654413773, 0.9732402256999829, 0.9403061933191572]) assert_allclose(signal.kaiser(6, 2.7), [0.2603047507678832, 0.6648106293528054, 0.9582099802511439, 0.9582099802511439, 0.6648106293528054, 0.2603047507678832]) assert_allclose(signal.kaiser(7, 2.7), [0.2603047507678832, 0.5985765418119844, 0.8868495172060835, 1.0, 0.8868495172060835, 0.5985765418119844, 0.2603047507678832]) assert_allclose(signal.kaiser(6, 2.7, False), [0.2603047507678832, 0.5985765418119844, 0.8868495172060835, 1.0, 0.8868495172060835, 0.5985765418119844])
def recompute_window(self): zoom = int(self.width * (self.get_eff_sample_rate()) / self.zoom_fac) if self.filter == 'kaiser': self.window = signal.kaiser( freqshow.SDR_SAMPLE_SIZE, self.kaiser_beta, False, )[0:zoom + 2] # for every bin there is a window the same exact size as the read samples. elif self.filter == 'boxcar': self.window = signal.boxcar( freqshow.SDR_SAMPLE_SIZE, False, )[0:zoom + 2] elif self.filter == 'hann': self.window = signal.hann( freqshow.SDR_SAMPLE_SIZE, False, )[0:zoom + 2] elif self.filter == 'hamming': self.window = signal.hamming( freqshow.SDR_SAMPLE_SIZE, False, )[0:zoom + 2] elif self.filter == 'blackman': self.window = signal.blackman( freqshow.SDR_SAMPLE_SIZE, False, )[0:zoom + 2] elif self.filter == 'blackmanharris': self.window = signal.blackmanharris( freqshow.SDR_SAMPLE_SIZE, False, )[0:zoom + 2] elif self.filter == 'bartlett': self.window = signal.bartlett( freqshow.SDR_SAMPLE_SIZE, False, )[0:zoom + 2] elif self.filter == 'barthann': self.window = signal.barthann( freqshow.SDR_SAMPLE_SIZE, False, )[0:zoom + 2] elif self.filter == 'nuttall': self.window = signal.nuttall( freqshow.SDR_SAMPLE_SIZE, False, )[0:zoom + 2] else: self.window = 1
def CircularDeconvolution(x,y,dt,fmax,beta=None): from numpy.fft import rfft, irfft, fftshift, fft, ifft, fftfreq, ifftshift from numpy import floor,zeros,hstack,conj,pi,exp,linspace,ones,real,pi from scipy.signal import blackmanharris,kaiser,hann from matplotlib.pyplot import plot, show # mx = abs(x).argmax() # my = abs(y).argmax() # Nx = len(x) # Ny = len(y) Nmin = len(x)+len(y)-1 N = FFTLengthPower2((len(x)+len(y)-1)) # X = rfft(hstack((x[mx::],zeros(abs(Ny-Nx)),x[0:mx-1]))) X = fft(x,n=N) Sxx = fftshift(X*conj(X)) # Y = rfft(y[m::],n=Ny) # Y = rfft(hstack((y[mx::],y[0:mx-1]))) Y = fft(y,n=N) Syx = fftshift(Y*conj(X)) f = fftshift(fftfreq(N,dt)) fpass = [(f>=-fmax)&(f<=fmax)] H = Syx[fpass]/Sxx[fpass] if beta is None: H = hann(len(H))*H else: H = kaiser(len(H),beta)*H HH = zeros(N)+0.0*1j HH[fpass] = H.copy() H = ifftshift(HH) h = real(ifft(H)) return h[0:Nmin], H
def __init__(self, duration=10.0, low=100.0, high=15000.0, Fs=44100.0): self.Fs = Fs # Total length in samples self.T = Fs * duration self.w1 = low / self.Fs * 2 * np.pi self.w2 = high / self.Fs * 2 * np.pi self.probe_pulse = self.probe() # Apply exponential signal on the beginning and the end of the probe signal. exp_window = 1 - np.exp(np.linspace(0, -10, 5000)) window_len = 2500 win = kaiser(window_len, 16) win_start = win[:int(win.shape[0] / 2)] self.probe_pulse[:win_start.shape[0]] *= win_start window_len = 2500 win = kaiser(window_len, 14) win_end = win[int(win.shape[0] / 2):] self.probe_pulse[-win_end.shape[0]:] *= win_end # This is what the value of K will be at the end (in dB): kend = 10**((-6 * np.log2(self.w2 / self.w1)) / 20) # dB to rational number. k = np.log(kend) / self.T # Making reverse probe impulse so that convolution will just # calculate dot product. Weighting it with exponent to acheive # 6 dB per octave amplitude decrease. self.reverse_pulse = self.probe_pulse[-1::-1] * \ np.array(list(\ map(lambda t: np.exp(float(t)*k), range(int(self.T)))\ )\ ) # Now we have to normilze energy of result of dot product. # This is "naive" method but it just works. Frp = fft(fftconvolve(self.reverse_pulse, self.probe_pulse)) self.reverse_pulse /= np.abs(Frp[round(Frp.shape[0] / 4)])
def kaiser_derived(M, beta): """ Return a Kaiser-Bessel derived window. Parameters ---------- M : int Number of points in the output window. If zero or less, an empty array is returned. beta : float Kaiser-Bessel window shape parameter. Returns ------- w : ndarray The window, normalized to fulfil the Princen-Bradley condition. Notes ----- This window is only defined for an even number of taps. References ---------- .. [1] Wikipedia, "Kaiser window", https://en.wikipedia.org/wiki/Kaiser_window """ M = int(M) try: from scipy.signal import kaiser_derived as scipy_kd return scipy_kd(M, beta) except ImportError: pass if M < 1: return np.array([]) if M % 2: raise ValueError( "Kaiser Bessel Derived windows are only defined for even number " "of taps" ) w = np.zeros(M) kaiserw = kaiser(M // 2 + 1, beta) csum = np.cumsum(kaiserw) halfw = np.sqrt(csum[:-1] / csum[-1]) w[:M//2] = halfw w[-M//2:] = halfw[::-1] return w
def firwin_kaiser_bsf(f_stop1, f_pass1, f_pass2, f_stop2, d_stop, fs = 1.0, N_bump=0): """ Design an FIR bandstop filter using the sinc() kernel and a Kaiser window. The filter order is determined based on f_stop1 Hz, f_pass1 Hz, f_pass2 Hz, f_stop2 Hz, and the desired stopband attenuation d_stop in dB for both stopbands, all relative to a sampling rate of fs Hz. Note: The passband ripple cannot be set independent of the stopband attenuation. Note: The filter order is forced to be even (odd number of taps) so there is a center tap that can be used to form 1 - H_BPF. Mark Wickert October 2016 """ # First design a BPF starting from simple LPF equivalent # The upper and lower stopbands are assumed to have # the same attenuation level. The LPF equivalent critical # frequencies: f_pass = (f_pass2 - f_pass1)/2 f_stop = (f_stop2 - f_stop1)/2 # Continue to design equivalent LPF wc = 2*np.pi*(f_pass + f_stop)/2/fs delta_w = 2*np.pi*(f_stop - f_pass)/fs # Find the filter order M = np.ceil((d_stop - 8)/(2.285*delta_w)) # Adjust filter order up or down as needed M += N_bump # Make filter order even (odd number of taps) if ((M+1)/2.0-int((M+1)/2.0)) == 0: M += 1 N_taps = M + 1 # Obtain the Kaiser window beta = signal.kaiser_beta(d_stop) w_k = signal.kaiser(N_taps,beta) n = np.arange(N_taps) b_k = wc/np.pi*np.sinc(wc/np.pi*(n-M/2)) * w_k b_k /= np.sum(b_k) # Transform LPF to BPF f0 = (f_pass2 + f_pass1)/2 w0 = 2*np.pi*f0/fs n = np.arange(len(b_k)) b_k_bs = 2*b_k*np.cos(w0*(n-M/2)) # Transform BPF to BSF via 1 - BPF for odd N_taps b_k_bs = -b_k_bs b_k_bs[int(M/2)] += 1 print('Kaiser Win filter taps = %d.' % N_taps) return b_k_bs
def THDN(signal, sample_rate): """Measure the THD+N for a signal and print the results Prints the estimated fundamental frequency and the measured THD+N. This is calculated from the ratio of the entire signal before and after notch-filtering. This notch-filters by nulling out the frequency coefficients ±10% of the fundamental """ # Get rid of DC and window the signal signal -= mean(signal) # TODO: Do this in the frequency domain, and take any skirts with it? windowed = signal * kaiser(len(signal), 100) del signal # Zero pad to nearest power of two new_len = 2**ceil( log(len(windowed)) / log(2) ) windowed = concatenate((windowed, zeros(new_len - len(windowed)))) # Measure the total signal before filtering but after windowing total_rms = rms_flat(windowed) # Find the peak of the frequency spectrum (fundamental frequency) f = rfft(windowed) i = argmax(abs(f)) true_i = parabolic(log(abs(f)), i)[0] print 'Frequency: %f Hz' % (sample_rate * (true_i / len(windowed))) # Filter out fundamental by throwing away values ±10% lowermin = true_i - 0.1 * true_i uppermin = true_i + 0.1 * true_i f[lowermin: uppermin] = 0 # Transform noise back into the time domain and measure it noise = irfft(f) THDN = rms_flat(noise) / total_rms # TODO: RMS and A-weighting in frequency domain? # Apply A-weighting to residual noise (Not normally used for distortion, # but used to measure dynamic range with -60 dBFS signal, for instance) weighted = A_weight(noise, sample_rate) THDNA = rms_flat(weighted) / total_rms print "THD+N: %.4f%% or %.1f dB" % (THDN * 100, 20 * log10(THDN)) print "A-weighted: %.4f%% or %.1f dB(A)" % (THDNA * 100, 20 * log10(THDNA))
def analyze(filename): global correct_count print('analyzing ' + filename + ' ...') try: sampling_rate, signal = scipy.io.wavfile.read(filename) except: print("unable to analyze " + filename) print("") else: samples_count = len(signal) duration = float(samples_count) / sampling_rate if not isinstance(signal[0], np.int16): signal = [s[0] for s in signal] signal = signal * kaiser(samples_count, 100) spectrum = np.log(abs(np.fft.rfft(signal))) hps = copy(spectrum) for h in np.arange(2, 6): dec = decimate(spectrum, h) hps[:len(dec)] += dec peak_start = 50 * duration peak = np.argmax(hps[peak_start:]) fundamental = (peak_start + peak) / duration if fundamental < 165: verdict = 'M' elif 180 < fundamental: verdict = 'F' else: verdict = 'U' correct = re.search('([KM])\.wav', filename).group(1) if correct == 'K': correct = 'F' if correct == verdict: correct_count += 1 print("fundamendal frequency: " + "%.5f" % fundamental) print("verdict: " + verdict) if correct != verdict: print("WRONG") print("")
def wndow(win_size_N, out_vector_N = -1, **kwargs): if win_size_N > out_vector_N: out_vector_N = win_size_N wnd_size_div = out_vector_N / win_size_N wndw_kind = kwargs.get('kind', 'hamming') wndw = np.arange(1) if wndw_kind == 'kaiser': shaper = kwargs.get('shaper', 1) wndw_s = si.kaiser(win_size_N, shaper) wndw = np.concatenate([np.zeros((wnd_size_div - 1)*out_vector_N/(2*wnd_size_div)), wndw_s]) wndw = np.concatenate([wndw, np.zeros((wnd_size_div - 1)*out_vector_N/(2*wnd_size_div))]) return wndw
def test_spectrogram_time_invariance(self): """Test the time invariance property of the spectrogram.""" signal, _ = fmlin(128, 0.1, 0.4) window = kaiser(17, 3 * np.pi) tfr, ts, freqs = cohen.Spectrogram(signal, n_fbins=64, fwindow=window).run() shift = 64 timeshifted_signal = np.roll(signal, shift) timeshifted_tfr, _, _ = cohen.Spectrogram(timeshifted_signal, n_fbins=64, fwindow=window).run() rolled_tfr = np.roll(tfr, shift, axis=1) # the time invariance property holds mostly qualitatively. The shifted # TFR is not numerically indentical to the rolled TFR, having # differences at the edges; so clip with two TFRs where there are # discontinuities in the TFR. edge = 10 xx = np.c_[timeshifted_tfr[:, edge:(shift - edge)], timeshifted_tfr[:, (shift + edge):-edge]] yy = np.c_[rolled_tfr[:, edge:(shift - edge)], rolled_tfr[:, (shift + edge):-edge]] np.testing.assert_allclose(xx, yy)
def genderRecognition(filename): global countrights try: rate, signal = sc.read(filename) except: print("") else: frames = len(signal) dur = float(frames) / rate if not isinstance(signal[0], np.int16): signal = [s[0] for s in signal] try: signal = signal * kaiser(frames, 30) except: print("") else: signal1 = abs(np.fft.rfft(signal))#np.log(abs(np.fft.rfft(signal))) signal2 = copy(signal1) for h in np.arange(2, 6): decsignal = decimate(signal1, h) signal2[:len(decsignal)] += decsignal speak = 50 * dur peak = np.argmax(signal2[speak:]) freq = (speak + peak) / dur if freq < 180: result = 'M' elif 180 <= freq: result = 'K' truth = re.search('([KM])\.wav', filename).group(1) if truth == result: countrights += 1
def compute_frequency_bands(self, y): """ Compute FFT using a kaiser window over a series of data points of length window_size. The Kaiser window can approximate many other windows by varying the beta parameter. beta | Window shape ------------------------------ 0 | Rectangular 5 | Similar to a Hamming 6 | Similar to a Hann 8.6 | Similar to a Blackman A beta value of 14 is probably a good starting point. Note that as beta gets large, the window narrows, and so the number of samples needs to be large enough to sample the increasingly narrow spike, otherwise NaNs will get returned. More at http://docs.scipy.org/doc/scipy-0.17.0/reference/generated/scipy.signal.kaiser.html :param y: (numpy.Array) array of floats. Frequency bands will be extracted from this data. """ # make sure the number of data points to analyze is equal to window size assert len(y) == self.window_size w = kaiser(self.window_size, beta=14) ywf = fft(y * w) freqs = np.fft.fftfreq(self.window_size, d=1. / self.sampling_frequency) bands = {} for (name, freq_range) in self.frequency_bands.items(): bands[name] = np.sum(np.abs(ywf[(freqs >= freq_range[0]) & (freqs < freq_range[1])])) return bands
def test_spectrogram_reality(self): signal, _ = fmlin(128, 0.1, 0.4) window = kaiser(17, 3 * np.pi) tfr, _, _ = cohen.spectrogram(signal, n_fbins=64, window=window) self.assertTrue(np.all(np.isreal(tfr)))
def test_kaiser_float(self): win1 = signal.get_window(7.2, 64) win2 = signal.kaiser(64, 7.2, False) assert_allclose(win1, win2)
def spec_track(signal, pitch, parameters): #--------------------------------------------------------------- # Set parameters. #--------------------------------------------------------------- nframe_size = pitch.frame_size*2 maxpeaks = parameters['shc_maxpeaks'] delta = signal.new_fs/pitch.nfft window_length = int(np.fix(parameters['shc_window']/delta)) half_window_length = int(np.fix(float(window_length)/2)) if not(window_length % 2): window_length += 1 max_SHC = int(np.fix((parameters['f0_max']+parameters['shc_pwidth']*2)/delta)) min_SHC = int(np.ceil(parameters['f0_min']/delta)) num_harmonics = parameters['shc_numharms'] #--------------------------------------------------------------- # Main routine. #--------------------------------------------------------------- cand_pitch = np.zeros((maxpeaks, pitch.nframes)) cand_merit = np.ones((maxpeaks, pitch.nframes)) data = np.append(signal.filtered, np.zeros((1, nframe_size + ((pitch.nframes-1)*pitch.frame_jump-signal.size)))) #Compute SHC for voiced frame window = kaiser(nframe_size, 0.5) SHC = np.zeros((max_SHC)) row1_mat = np.empty((max_SHC-min_SHC+1, window_length)) row2_mat = np.empty((max_SHC-min_SHC+1, window_length)) row3_mat = np.empty((max_SHC-min_SHC+1, window_length)) row4_mat = np.empty((max_SHC-min_SHC+1, window_length)) magnitude = np.zeros((half_window_length+(pitch.nfft/2)+1)) for frame in np.where(pitch.vuv)[0].tolist(): fir_step = frame*pitch.frame_jump data_slice = data[fir_step:fir_step+nframe_size]*window data_slice -= np.mean(data_slice) magnitude[half_window_length:] = np.abs(np.fft.rfft(data_slice, pitch.nfft)) row1_mat[:, :] = stride_matrix(magnitude[min_SHC:], max_SHC-min_SHC+1, window_length, 1) row2_mat[:, :] = stride_matrix(magnitude[min_SHC*2:], max_SHC-min_SHC+1, window_length, 2) row3_mat[:, :] = stride_matrix(magnitude[min_SHC*3:], max_SHC-min_SHC+1, window_length, 3) row4_mat[:, :] = stride_matrix(magnitude[min_SHC*4:], max_SHC-min_SHC+1, window_length, 4) SHC[min_SHC-1:max_SHC] = np.sum(row1_mat*row2_mat*row3_mat*row4_mat, axis=1) cand_pitch[:, frame], cand_merit[:, frame] = \ peaks(SHC, delta, maxpeaks, parameters) #Extract the pitch candidates of voiced frames for the future pitch selection. spec_pitch = cand_pitch[0, :] voiced_cand_pitch = cand_pitch[:, cand_pitch[0, :] > 0] voiced_cand_merit = cand_merit[:, cand_pitch[0, :] > 0] num_voiced_cand = len(voiced_cand_pitch[0, :]) avg_voiced = np.mean(voiced_cand_pitch[0, :]) std_voiced = np.std(voiced_cand_pitch[0, :]) #Interpolation of the weigthed candidates. delta1 = abs((voiced_cand_pitch - 0.8*avg_voiced))*(3-voiced_cand_merit) index = delta1.argmin(0) voiced_peak_minmrt = voiced_cand_pitch[index, xrange(num_voiced_cand)] voiced_merit_minmrt = voiced_cand_merit[index, xrange(num_voiced_cand)] voiced_peak_minmrt = medfilt(voiced_peak_minmrt, max(1, parameters['median_value']-2)) #Replace the lowest merit candidates by the median smoothed ones #computed from highest merit peaks above. voiced_cand_pitch[index, xrange(num_voiced_cand)] = voiced_peak_minmrt voiced_cand_merit[index, xrange(num_voiced_cand)] = voiced_merit_minmrt #Use dynamic programming to find best overal path among pitch candidates. #Dynamic weight for transition costs balance between local and #transition costs. weight_trans = parameters['dp5_k1']*std_voiced/avg_voiced if num_voiced_cand > 2: voiced_pitch = dynamic5(voiced_cand_pitch, voiced_cand_merit, weight_trans, parameters['f0_min']) voiced_pitch = medfilt(voiced_pitch, max(1, parameters['median_value']-2)) else: if num_voiced_cand > 0: voiced_pitch = (ones(1, num_voiced_cand))*150.0 else: voiced_pitch = [150.0] cand_pitch[0, 0] = 0 pitch_avg = np.mean(voiced_pitch) pitch_std = np.std(voiced_pitch) spec_pitch[cand_pitch[0, :] > 0] = voiced_pitch[:] if (spec_pitch[0] < pitch_avg/2): spec_pitch[0] = pitch_avg if (spec_pitch[-1] < pitch_avg/2): spec_pitch[-1] = pitch_avg spec_voiced = np.array(np.nonzero(spec_pitch)[0]) spec_pitch = pchip(spec_voiced, spec_pitch[spec_voiced])(xrange(pitch.nframes)) spec_pitch = lfilter(np.ones((3))/3, 1.0, spec_pitch) spec_pitch[0] = spec_pitch[2] spec_pitch[1] = spec_pitch[3] return spec_pitch, pitch_std
from scipy.signal import firwin, kaiser from pylab import figure, plot, grid, show, xlabel, ylabel, title N = 128 D = 12 sample_rate = 1.0 / 1.28e6 cof_bit = 12 b = firwin(N * D - 1, 1.0 / N) b = (1 - pow(2, -(cof_bit - 1))) * b / max(b) window = kaiser(N * D - 1, 5) x_axis = [] for x in range(-1 * (N * D / 2), (N * D / 2 - 1)): x_axis.append(x * sample_rate * 1e6) figure(1) # plot(x_axis,b) # plot(x_axis,window,'r-') filter = b * window # invert the filter inv_filter = [] threshold = 100 for coeff in filter: inv_coeff = 1.0 / coeff if abs(inv_coeff) < threshold: inv_filter.append(inv_coeff) else: inv_filter.append(threshold * abs(inv_coeff) / (inv_coeff)) print coeff
# Plot the window and its frequency response: from scipy import signal from scipy.fftpack import fft, fftshift import matplotlib.pyplot as plt window = signal.kaiser(51, beta=14) plt.plot(window) plt.title(r"Kaiser window ($\beta$=14)") plt.ylabel("Amplitude") plt.xlabel("Sample") plt.figure() A = fft(window, 2048) / (len(window)/2.0) freq = np.linspace(-0.5, 0.5, len(A)) response = 20 * np.log10(np.abs(fftshift(A / abs(A).max()))) plt.plot(freq, response) plt.axis([-0.5, 0.5, -120, 0]) plt.title(r"Frequency response of the Kaiser window ($\beta$=14)") plt.ylabel("Normalized magnitude [dB]") plt.xlabel("Normalized frequency [cycles per sample]")
clf()#figure(2) grid(True) stem(n, y) # Filter response. fig = figure(2) mag_p = fig.add_subplot(2,1,1) ang_p = fig.add_subplot(2,1,2) gfiltpak.gfreqz(b, a, color = 'k', magfig = mag_p, angfig = ang_p) hold(True) from scipy import signal as si b = si.kaiser(N, 3) gfiltpak.gfreqz(b, a, color = 'm', magfig = mag_p, angfig = ang_p, label = "kaiser", threedb = True) hold(True) b = si.blackmanharris(N) gfiltpak.gfreqz(b, a, color = 'g', magfig = mag_p, angfig = ang_p, ylimmag = [-500, 0]) hold(True) b = si.blackman(N) gfiltpak.gfreqz(b, a, color = 'y', magfig = mag_p, angfig = ang_p) # Show mag_p.legend(('r', 'k', '3dB', 'b-h', 'b'), numpoints = 4, fancybox = True) ang_p.legend(('r', 'k', 'b-h', 'b'), numpoints = 2, fancybox = True) ##############################################################
def test_spectrogram_non_negativity(self): """Test that the spectrogram is non negative.""" signal, _ = fmlin(128, 0.1, 0.4) window = kaiser(17, 3 * np.pi) tfr, _, _ = cohen.Spectrogram(signal, n_fbins=64, fwindow=window).run() self.assertTrue(np.all(tfr >= 0))
def test_spectrogram_reality(self): """Test the reality property of the spectrogram.""" signal, _ = fmlin(128, 0.1, 0.4) window = kaiser(17, 3 * np.pi) tfr, _, _ = cohen.Spectrogram(signal, n_fbins=64, fwindow=window).run() self.assertTrue(np.all(np.isreal(tfr)))