functional_cpu_test.py 4.9 KB
Newer Older
jamarshon's avatar
jamarshon committed
1
import math
2
import unittest
jamarshon's avatar
jamarshon committed
3
4
5

import torch
import torchaudio
6
import torchaudio.functional as F
7
from parameterized import parameterized
8
import pytest
jamarshon's avatar
jamarshon committed
9

10
from . import common_utils
11
from .functional_impl import Lfilter
12

jamarshon's avatar
jamarshon committed
13

moto's avatar
moto committed
14
class TestLFilterFloat32(Lfilter, common_utils.PytorchTestCase):
15
16
    dtype = torch.float32
    device = torch.device('cpu')
17
18


moto's avatar
moto committed
19
class TestLFilterFloat64(Lfilter, common_utils.PytorchTestCase):
20
21
    dtype = torch.float64
    device = torch.device('cpu')
22
23


moto's avatar
moto committed
24
class TestComputeDeltas(common_utils.TorchaudioTestCase):
moto's avatar
moto committed
25
26
27
28
29
    """Test suite for correctness of compute_deltas"""
    def test_one_channel(self):
        specgram = torch.tensor([[[1.0, 2.0, 3.0, 4.0]]])
        expected = torch.tensor([[[0.5, 1.0, 1.0, 0.5]]])
        computed = F.compute_deltas(specgram, win_length=3)
30
        torch.testing.assert_allclose(computed, expected)
Vincent QB's avatar
Vincent QB committed
31

moto's avatar
moto committed
32
33
34
35
36
37
    def test_two_channels(self):
        specgram = torch.tensor([[[1.0, 2.0, 3.0, 4.0],
                                  [1.0, 2.0, 3.0, 4.0]]])
        expected = torch.tensor([[[0.5, 1.0, 1.0, 0.5],
                                  [0.5, 1.0, 1.0, 0.5]]])
        computed = F.compute_deltas(specgram, win_length=3)
38
        torch.testing.assert_allclose(computed, expected)
39

Vincent QB's avatar
Vincent QB committed
40

moto's avatar
moto committed
41
class TestDetectPitchFrequency(common_utils.TorchaudioTestCase):
42
43
44
45
46
47
48
49
50
51
52
53
    @parameterized.expand([(100,), (440,)])
    def test_pitch(self, frequency):
        sample_rate = 44100
        test_sine_waveform = common_utils.get_sinusoid(
            frequency=frequency, sample_rate=sample_rate, duration=5,
        )

        freq = torchaudio.functional.detect_pitch_frequency(test_sine_waveform, sample_rate)

        threshold = 1
        s = ((freq - frequency).abs() > threshold).sum()
        self.assertFalse(s)
Vincent QB's avatar
Vincent QB committed
54

moto's avatar
moto committed
55

moto's avatar
moto committed
56
class TestDB_to_amplitude(common_utils.TorchaudioTestCase):
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
    def test_DB_to_amplitude(self):
        # Make some noise
        x = torch.rand(1000)
        spectrogram = torchaudio.transforms.Spectrogram()
        spec = spectrogram(x)

        amin = 1e-10
        ref = 1.0
        db_multiplier = math.log10(max(amin, ref))

        # Waveform amplitude -> DB -> amplitude
        multiplier = 20.
        power = 0.5

        db = F.amplitude_to_DB(torch.abs(x), multiplier, amin, db_multiplier, top_db=None)
        x2 = F.DB_to_amplitude(db, ref, power)

74
        torch.testing.assert_allclose(x2, torch.abs(x), atol=5e-5, rtol=1e-5)
75
76
77
78
79

        # Spectrogram amplitude -> DB -> amplitude
        db = F.amplitude_to_DB(spec, multiplier, amin, db_multiplier, top_db=None)
        x2 = F.DB_to_amplitude(db, ref, power)

80
        torch.testing.assert_allclose(x2, spec, atol=5e-5, rtol=1e-5)
81
82
83
84
85
86
87
88

        # Waveform power -> DB -> power
        multiplier = 10.
        power = 1.

        db = F.amplitude_to_DB(x, multiplier, amin, db_multiplier, top_db=None)
        x2 = F.DB_to_amplitude(db, ref, power)

89
        torch.testing.assert_allclose(x2, torch.abs(x), atol=5e-5, rtol=1e-5)
90
91
92
93
94

        # Spectrogram power -> DB -> power
        db = F.amplitude_to_DB(spec, multiplier, amin, db_multiplier, top_db=None)
        x2 = F.DB_to_amplitude(db, ref, power)

95
        torch.testing.assert_allclose(x2, spec, atol=5e-5, rtol=1e-5)
96

97
98
99
100
101
102
103
104
105
106

@pytest.mark.parametrize('complex_tensor', [
    torch.randn(1, 2, 1025, 400, 2),
    torch.randn(1025, 400, 2)
])
@pytest.mark.parametrize('power', [1, 2, 0.7])
def test_complex_norm(complex_tensor, power):
    expected_norm_tensor = complex_tensor.pow(2).sum(-1).pow(power / 2)
    norm_tensor = F.complex_norm(complex_tensor, power)

107
    torch.testing.assert_allclose(norm_tensor, expected_norm_tensor, atol=1e-5, rtol=1e-5)
108
109


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
@pytest.mark.parametrize('specgram', [
    torch.randn(2, 1025, 400),
    torch.randn(1, 201, 100)
])
@pytest.mark.parametrize('mask_param', [100])
@pytest.mark.parametrize('mask_value', [0., 30.])
@pytest.mark.parametrize('axis', [1, 2])
def test_mask_along_axis(specgram, mask_param, mask_value, axis):

    mask_specgram = F.mask_along_axis(specgram, mask_param, mask_value, axis)

    other_axis = 1 if axis == 2 else 2

    masked_columns = (mask_specgram == mask_value).sum(other_axis)
    num_masked_columns = (masked_columns == mask_specgram.size(other_axis)).sum()
moto's avatar
moto committed
125
    num_masked_columns //= mask_specgram.size(0)
126
127
128
129
130
131
132
133

    assert mask_specgram.size() == specgram.size()
    assert num_masked_columns < mask_param


@pytest.mark.parametrize('mask_param', [100])
@pytest.mark.parametrize('mask_value', [0., 30.])
@pytest.mark.parametrize('axis', [2, 3])
134
135
136
def test_mask_along_axis_iid(mask_param, mask_value, axis):
    torch.random.manual_seed(42)
    specgrams = torch.randn(4, 2, 1025, 400)
137
138
139
140
141
142
143
144
145
146

    mask_specgrams = F.mask_along_axis_iid(specgrams, mask_param, mask_value, axis)

    other_axis = 2 if axis == 3 else 3

    masked_columns = (mask_specgrams == mask_value).sum(other_axis)
    num_masked_columns = (masked_columns == mask_specgrams.size(other_axis)).sum(-1)

    assert mask_specgrams.size() == specgrams.size()
    assert (num_masked_columns < mask_param).sum() == num_masked_columns.numel()