Exemple #1
0
def test_getter_signal_type():
    """Test if attribute signal type is accessed correctly."""
    signal = Signal([1, 2, 3], 44100, fft_norm='none')
    npt.assert_string_equal(signal.signal_type, 'energy')

    signal = Signal([1, 2, 3], 44100, fft_norm='rms')
    npt.assert_string_equal(signal.signal_type, 'power')
Exemple #2
0
def test_get_arithmetic_data_with_signal():
    # all possible combinations of `domain`, `signal_type`, and `fft_norm`
    meta = [['time', None], ['freq', None], ['time', 'unitary'],
            ['freq', 'unitary'], ['time', 'amplitude'], ['freq', 'amplitude'],
            ['time', 'rms'], ['freq', 'rms'], ['time', 'power'],
            ['freq', 'power'], ['time', 'psd'], ['freq', 'psd']]

    # reference signal - _get_arithmetic_data should return the data without
    # any normalization regardless of the input data
    s_ref = Signal([1, 0, 0], 44100)

    for m_in in meta:
        # create input signal with current domain, type, and norm
        s_in = Signal([1, 0, 0], 44100, fft_norm=m_in[1])
        s_in.domain = m_in[0]
        for domain in ['time', 'freq']:
            print(f"Testing from {m_in[0]} ({m_in[1]}) to {domain}.")

            # get output data
            data_out = signal._get_arithmetic_data(s_in,
                                                   n_samples=3,
                                                   domain=domain)
            if domain == 'time':
                npt.assert_allclose(s_ref.time, data_out, atol=1e-15)
            elif domain == 'freq':
                npt.assert_allclose(s_ref.freq, data_out, atol=1e-15)
Exemple #3
0
def test_division():
    # only test one case - everything else is tested below
    x = Signal([1, 0, 0], 44100)
    y = Signal([2, 2, 2], 44100)
    z = signal.divide((x, y), 'time')

    # check result
    npt.assert_allclose(z.time, np.atleast_2d([0.5, 0, 0]), atol=1e-15)
Exemple #4
0
def test_power():
    # only test one case - everything else is tested below
    x = Signal([2, 1, 0], 44100)
    y = Signal([2, 2, 2], 44100)
    z = signal.power((x, y), 'time')

    # check result
    npt.assert_allclose(z.time, np.atleast_2d([4, 1, 0]), atol=1e-15)
Exemple #5
0
def test_magic_setitem_wrong_norm(sine, sine_rms):
    """Test the magic function __setitem__."""
    signal = Signal(sine.time, sine.sampling_rate, fft_norm=sine.fft_norm)
    set_signal = Signal(sine_rms.time,
                        sine_rms.sampling_rate,
                        fft_norm=sine_rms.fft_norm)
    with pytest.raises(ValueError, match='FFT norms do not match'):
        signal[0] = set_signal
Exemple #6
0
def test___eq___notEqual(sine_signal, sine):
    actual = Signal(0.5 * sine.time, sine.sampling_rate, domain='time')
    assert not sine_signal == actual
    actual = Signal(sine.time, 2 * sine.sampling_rate, domain='time')
    assert not sine_signal == actual
    actual = sine_signal.copy()
    actual.comment = f'{actual.comment} A completely different thing'
    assert not sine_signal == actual
Exemple #7
0
def test_multiplication():
    # only test one case - everything else is tested below
    x = Signal([1, 0, 0], 44100)
    y = Signal([0, 1, 0], 44100)
    z = signal.multiply((x, y), 'time')

    # check result
    npt.assert_allclose(z.time, np.atleast_2d([0, 0, 0]), atol=1e-15)
Exemple #8
0
def test_getter_signal_type(sine, sine_rms):
    """Test if attribute signal type is accessed correctly."""
    signal = Signal(sine.time, sine.sampling_rate, fft_norm=sine.fft_norm)
    npt.assert_string_equal(signal.signal_type, 'energy')

    signal = Signal(sine_rms.time,
                    sine_rms.sampling_rate,
                    fft_norm=sine_rms.fft_norm)
    npt.assert_string_equal(signal.signal_type, 'power')
Exemple #9
0
def test___eq___notEqual():
    time = np.arange(2 * 3 * 4).reshape((2, 3, 4))
    signal = Signal(time, 44100, domain='time')

    actual = Signal(0.5 * time, 44100, domain='time')
    assert not signal == actual
    actual = Signal(time, 2 * 44100, domain='time')
    assert not signal == actual
    comment = f'{signal.comment} A completely different thing'
    actual = Signal(time, 44100, domain='time', comment=comment)
    assert not signal == actual
Exemple #10
0
def test_setter_fft_norm():
    spec_power_unitary = np.atleast_2d([1, 2, 1])
    spec_power_amplitude = np.atleast_2d([1 / 4, 2 / 4, 1 / 4])

    signal = Signal(spec_power_unitary,
                    44100,
                    n_samples=4,
                    domain='freq',
                    fft_norm='unitary')

    # changing the fft_norm also changes the spectrum
    signal.fft_norm = 'amplitude'
    assert signal.fft_norm == 'amplitude'
    npt.assert_allclose(signal.freq, spec_power_amplitude, atol=1e-15)

    # changing the fft norm in the time domain does not change the time data
    signal.domain = 'time'
    time_power_amplitude = signal._data.copy()
    signal.fft_norm = 'unitary'
    npt.assert_allclose(signal.time, time_power_amplitude)
    npt.assert_allclose(signal.freq, spec_power_unitary)

    # setting an invalid fft_norm
    with pytest.raises(ValueError):
        signal.fft_norm = 'bullshit'
Exemple #11
0
def test_signal_init_default_parameter(sine):
    # using all defaults
    signal = Signal(sine.time, sine.sampling_rate)
    assert signal.domain == 'time'
    assert signal.fft_norm == 'none'
    assert signal.comment == 'none'
    assert signal.fft_norm == 'none'
Exemple #12
0
def test_signal_init_default_parameter():
    # using all defaults
    signal = Signal([1, 2, 3], 44100)
    assert signal.domain == 'time'
    assert signal.fft_norm == 'none'
    assert signal.comment == 'none'
    assert signal.fft_norm == 'none'
Exemple #13
0
def read_wav(filename):
    """
    Import a WAV file as signal object.

    This method is based on scipy.io.wavfile.read().

    Parameters
    ----------
    filename : string or open file handle
        Input wav file.

    Returns
    -------
    signal : signal instance
        An audio signal object from the pyfar Signal class
        containing the audio data from the WAV file.

    Notes
    -----
    * This function is based on scipy.io.wavfile.write().
    * This function cannot read wav files with 24-bit data.
    """
    sampling_rate, data = wavfile.read(filename)
    signal = Signal(data.T, sampling_rate, domain='time')
    return signal
Exemple #14
0
def test_sti_warn_data_type_unknown():
    sig = Signal(np.zeros((1, 31072)), 44100)
    sig.time[0] = 1
    with pytest.raises(ValueError,
                       match="Data_type is 'generic' but must "
                       "be 'electrical' or 'acoustical'."):
        sti.sti(sig, data_type="generic")
Exemple #15
0
def test_signal_init_val(sine):
    """Test to init Signal with complete parameters."""
    signal = Signal(sine.time,
                    sine.sampling_rate,
                    domain='time',
                    fft_norm=sine.fft_norm)
    assert isinstance(signal, Signal)
Exemple #16
0
def test_iter_write():
    data = np.ones((3, 1024)) * np.atleast_2d(np.arange(3)).T
    sig = Signal(data, 1)
    sig.domain = 'time'

    for idx, s in enumerate(sig):
        sig[idx] = s
Exemple #17
0
def signal_stub(time, freq, sampling_rate, fft_norm):
    """Function to generate stub of pyfar Signal class based on MagicMock.
    The properties of the signal are set without any further check.

    Parameters
    ----------
    time : ndarray
        Time data
    freq : ndarray
        Frequency data
    sampling_rate : float
        Sampling rate
    fft_norm : 'unitary', 'amplitude', 'rms', 'power', 'psd'
        See documentation of pyfar.fft.normalization.

    Returns
    -------
    signal
        stub of pyfar Signal class
    """

    # Use MagicMock and side_effect to mock __getitem__
    # See "Mocking a dictionary with MagicMock",
    # https://het.as.utexas.edu/HET/Software/mock/examples.html
    def getitem(slice):
        time = np.atleast_2d(signal.time[slice])
        freq = np.atleast_2d(signal.freq[slice])
        item = signal_stub(time, freq, signal.sampling_rate, signal.fft_norm)
        return item

    def find_nearest_time(times):
        samples = np.zeros(len(times), dtype=int)
        for idx, time in enumerate(times):
            samples[idx] = np.argmin(np.abs(signal.times - time))
        return samples

    def find_nearest_frequency(freqs):
        bin = np.zeros(len(freqs), dtype=int)
        for idx, freq in enumerate(freqs):
            bin[idx] = np.argmin(np.abs(signal.frequencies - freq))
        return bin

    signal = mock.MagicMock(
        spec_set=Signal(time, sampling_rate, domain='time'))
    signal.time = np.atleast_2d(time)
    signal.freq = np.atleast_2d(freq)
    signal.sampling_rate = sampling_rate
    signal.fft_norm = fft_norm
    signal.n_samples = signal.time.shape[-1]
    signal.n_bins = signal.freq.shape[-1]
    signal.cshape = signal.time.shape[:-1]
    signal.times = np.atleast_1d(
        np.arange(0, signal.n_samples) / sampling_rate)
    signal.frequencies = np.atleast_1d(
        np.fft.rfftfreq(signal.n_samples, 1 / sampling_rate))
    signal.__getitem__.side_effect = getitem
    signal.find_nearest_time = find_nearest_time
    signal.find_nearest_frequency = find_nearest_frequency

    return signal
Exemple #18
0
def test_sti_value_error_gender():
    sig = Signal(np.zeros((1, 31072)), 44100)
    sig.time[0] = 1
    with pytest.raises(ValueError,
                       match="Gender is 'generic' but must be "
                       "'male' or 'female'."):
        sti.sti(sig, gender="generic")
Exemple #19
0
def test_sti_value_error_level():
    sig = Signal(np.zeros((1, 31072)), 44100)
    sig.time[0] = 1
    lvl = np.array([30, 30, 30, 30, 30, 30])
    with pytest.raises(ValueError,
                       match="Level consists of wrong number of "
                       "components."):
        sti.sti(sig, level=lvl)
Exemple #20
0
def test_iter_domain_change():
    data = np.ones((3, 1024)) * np.atleast_2d(np.arange(3)).T
    sig = Signal(data, 1)
    sig.domain = 'time'

    with pytest.raises(RuntimeError, match='domain changes'):
        for s in sig:
            s.freq
Exemple #21
0
def test_reshape():

    # test reshape with tuple
    signal_in = Signal(np.random.rand(6, 256), 44100)
    signal_out = signal_in.reshape((3, 2))
    npt.assert_allclose(signal_in._data.reshape(3, 2, -1), signal_out._data)
    assert id(signal_in) != id(signal_out)

    signal_out = signal_in.reshape((3, -1))
    npt.assert_allclose(signal_in._data.reshape(3, 2, -1), signal_out._data)
    assert id(signal_in) != id(signal_out)

    # test reshape with int
    signal_in = Signal(np.random.rand(3, 2, 256), 44100)
    signal_out = signal_in.reshape(6)
    npt.assert_allclose(signal_in._data.reshape(6, -1), signal_out._data)
    assert id(signal_in) != id(signal_out)
Exemple #22
0
def test_flatten():

    # test 2D signal (flatten should not change anything)
    x = np.random.rand(2, 256)
    signal_in = Signal(x, 44100)
    signal_out = signal_in.flatten()

    npt.assert_allclose(signal_in._data, signal_out._data)
    assert id(signal_in) != id(signal_out)

    # test 3D signal
    x = np.random.rand(3, 2, 256)
    signal_in = Signal(x, 44100)
    signal_out = signal_in.flatten()

    npt.assert_allclose(signal_in._data.reshape((6, -1)), signal_out._data)
    assert id(signal_in) != id(signal_out)
Exemple #23
0
def test_sti_value_error_snr():
    sig = Signal(np.zeros((1, 31072)), 44100)
    sig.time[0] = 1
    sn = np.array([30, 30, 30, 30, 30, 30])
    with pytest.raises(ValueError,
                       match="SNR consists of wrong number of "
                       "components."):
        sti.sti(sig, snr=sn)
Exemple #24
0
def test_sti_warn_data_type_not_given():
    sig = Signal(np.zeros((1, 31072)), 44100)
    sig.time[0] = 1
    with pytest.warns(UserWarning,
                      match="Data type is considered as "
                      "acoustical. Consideration of masking effects not valid "
                      "for electrically obtained signals."):
        sti.sti(sig)
Exemple #25
0
def test_sti_female():
    expected = np.array([0.6116])
    sig = Signal(np.zeros((1, 131072)), 44100)
    sig.time[0, 0] = 1
    sig.time[0, 1000] = 1
    sig.time[0, 10000] = 1
    array = sti.sti(sig, gender="female")
    np.testing.assert_allclose(array, expected, rtol=1e-3, atol=0)
Exemple #26
0
def test_domain_setter_time_when_freq(sine):
    signal = Signal(sine.freq,
                    sine.sampling_rate,
                    domain='freq',
                    fft_norm=sine.fft_norm)
    domain = 'time'
    signal.domain = domain
    assert signal.domain == domain
    npt.assert_allclose(signal._data, sine.time, atol=1e-10, rtol=1e-10)
Exemple #27
0
def test_sti_warn_snr_low():
    sig = Signal(np.zeros((1, 31072)), 44100)
    sig.time[0] = 1
    lvl = np.array([70, 70, 70, 70, 70, 70, 70])
    sn = np.array([10, 30, 30, 30, 30, 30, 30])
    with pytest.warns(UserWarning,
                      match="SNR should be at least 20 dB for "
                      "every octave band."):
        sti.sti(sig, level=lvl, snr=sn)
Exemple #28
0
def test_sti_lvl_snr_1D():
    expected = np.array([0.8933])
    sig = Signal(np.zeros((1, 131072)), 44100)
    sig.time[0, 0] = 1
    sig.time[0, 1000] = 1
    lvl = np.array([70, 70, 70, 70, 70, 70, 70])
    sn = np.array([30, 30, 30, 30, 30, 30, 30])
    array = sti.sti(sig, level=lvl, snr=sn)
    np.testing.assert_allclose(array, expected, rtol=1e-3, atol=0)
Exemple #29
0
def test_sti_amb_false():
    expected = np.array([0.8864])
    sig = Signal(np.zeros((1, 131072)), 44100)
    sig.time[0, 0] = 1
    sig.time[0, 1000] = 1
    lvl = np.array([70, 70, 70, 70, 70, 70, 70])
    sn = np.array([20, 20, 20, 20, 20, 20, 20])
    array = sti.sti(sig, level=lvl, snr=sn, amb=False)
    np.testing.assert_allclose(array, expected, rtol=1e-3, atol=0)
Exemple #30
0
def test_sti_2D():
    expected = np.ones((2, 2))
    sig = Signal(np.zeros((2, 2, 131072)), 44100)
    sig.time[0, 0, 0] = 1
    sig.time[1, 0, 0] = 1
    sig.time[0, 1, 0] = 1
    sig.time[1, 1, 0] = 1
    array = sti.sti(sig)
    np.testing.assert_allclose(array, expected, rtol=1e-2, atol=0)