Example #1
0
def get_phase(cfg):
    read = WaveReader(WAVE_DIR, cfg)
    instr = read.read()

    spectrum = rfft_norm(instr.waves[0])
    phase = np.angle(spectrum[1])
    return phase
Example #2
0
def test_reader_multi_waves():
    cfg_str = '''\
files:
  - path: sine440.69.wav
  - path: sine440.69.wav
    speed: 2
    volume: 1.1
  - path: sine256.59.624.wav
    speed: 3
    volume: 0
pitch_estimate: 69
nwave: 1

nsamp: 16
'''
    harmonics = [1, 2]  # plus 3 at volume=0

    cfg = n163_cfg(**yaml.load(cfg_str))
    read = WaveReader(WAVE_DIR, cfg)
    instr = read.read()

    # Calculate spectrum of resulting signal
    spectrum: np.ndarray = np.abs(rfft_norm(instr.waves[0]))
    spectrum[0] = 0
    threshold = np.amax(spectrum) / 2
    assert threshold > 0.1

    # Ensure pitches present
    assert (spectrum[harmonics] > threshold).all()

    # Ensure no other pitches present
    spectrum[harmonics] = 0
    spectrum[0] = 0
    assert (spectrum < threshold).all()
Example #3
0
    def _get_periodic_fft_freq(self, data) -> Tuple[SpectrumType, float]:
        """ Returns periodic FFT and frequency (Hz) of data. """

        # Number of samples
        nsamp = self.wcfg.nsamp
        freq_mul = self.freq_mul

        mode = self.cfg.mode

        periodic_fft = []
        fundamental_bin: float = self._get_fundamental_bin(data)

        if mode == 'stft':
            # Get STFT.
            stft = self._stft(data)

            # Convert STFT to periodic FFT.
            for harmonic in range(rfft_length(nsamp, freq_mul)):
                begin = fundamental_bin * (harmonic - 0.5)
                end = fundamental_bin * (harmonic + 0.5)

                bands = stft[math.ceil(begin):math.ceil(end)]
                amplitude: complex = self.power_sum(bands)
                periodic_fft.append(amplitude)

        elif mode == 'cycle':
            period = round(len(data) / fundamental_bin)

            # Pick 1 period of data, from the middle of the region.
            end = (len(data) + period) // 2
            begin = end - period

            periodic_fft = fourier.rfft_norm(data[begin:end])

        else:
            raise ValueError(f'mode=[stft, cycle] (you supplied {mode})')

        # Multiply pitch of FFT.
        freq_mul_fft = zero_pad(periodic_fft, freq_mul)

        # Ensure we didn't omit any harmonics <= Nyquist.
        if mode == 'stft':
            fft_plus_harmonic_length = len(freq_mul_fft) + freq_mul
            assert fft_plus_harmonic_length > rfft_length(nsamp), \
                f'fft len={len(freq_mul_fft)} + {freq_mul} not > {rfft_length(nsamp)}'

        # cyc/s = cyc/bin * bin/samp * samp/s
        freq_hz = fundamental_bin / len(data) * self.smp_s
        return freq_mul_fft, freq_hz
Example #4
0
def filter_wave(wave: WaveType, transfer) -> WaveType:
    harm = fourier.rfft_norm(wave)
    harm[1:] *= transfer(np.arange(1, len(harm)))
    return fourier.irfft_norm(harm)
Example #5
0
 def _stft(self, data: np.ndarray) -> np.ndarray:
     """ Phasor phases will match center of data, or peak of window. """
     data *= self.window
     phased_data = np.roll(data, len(data) // 2)
     return fourier.rfft_norm(phased_data)
Example #6
0
def test_repeat():
    cat = rfft_zoh(pulse * 3)
    pad = zero_pad(rfft_zoh(pulse), 3)
    assert_close(cat, pad)
    assert not np.allclose(cat, rfft_norm(pulse * 3))
Example #7
0
def test_irfft():
    zoh1 = rfft_norm(pulse)
    zoh3 = zero_pad(zoh1, 3)
    ipulse3 = irfft_norm(zoh3)
    assert_close(ipulse3, pulse3)
Example #8
0
# noinspection PyUnresolvedReferences
import numpy as np
from wavetable.dsp.fourier import zero_pad, rfft_norm, irfft_norm, rfft_zoh, irfft_zoh, \
    nyquist_real_idx, rfft_length


def assert_close(a, b):
    assert len(a) == len(b)
    assert np.allclose(a, b)


pulse = [1, 0, 0, 0]
pulse3 = pulse * 3
expected = [0.25] * 3

fft1 = rfft_norm(pulse)
assert_close(fft1, expected)


def test_nyquist_real():
    assert nyquist_real_idx(4) == 2
    assert nyquist_real_idx(5) == 3


def test_nyquist_inclusive():
    assert rfft_length(4) == 3
    assert rfft_length(5) == 3

    # A 16-sample wave has harmonics [0..8] with length 9.
    assert rfft_length(16, 1) == 9