Example #1
0
File: tools.py Project: IPGP/webobs
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
Example #2
0
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])
Example #5
0
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
Example #7
0
 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)
Example #8
0
    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
Example #9
0
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
Example #14
0
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
Example #16
0
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
Example #17
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
Example #18
0
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
Example #19
0
 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 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
Example #21
0
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
Example #22
0
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
Example #23
0
 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
Example #24
0
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
Example #25
0
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
Example #26
0
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
Example #27
0
 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)
Example #28
0
 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)
Example #29
0
    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
Example #30
0
 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)
Example #31
0
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
Example #32
0
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
Example #33
0
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
Example #34
0
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
Example #35
0
 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)
Example #36
0
 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)
Example #37
0
 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)
Example #38
0
 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])
Example #39
0
 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])
Example #40
0
    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
Example #41
0
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
Example #42
0
    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)])
Example #43
0
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
Example #45
0
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))
Example #46
0
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("")
Example #47
0
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
Example #48
0
 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
Example #50
0
    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
Example #51
0
 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)))
Example #52
0
 def test_kaiser_float(self):
     win1 = signal.get_window(7.2, 64)
     win2 = signal.kaiser(64, 7.2, False)
     assert_allclose(win1, win2)
Example #53
0
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
Example #54
0
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]")
Example #56
0
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)

##############################################################
Example #57
0
 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))
Example #58
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)))