Unverified Commit d63d851e authored by Vincent QB's avatar Vincent QB Committed by GitHub
Browse files

testing with sox only when sox is available (#419)

* testing with sox only when sox is available.

* use wav instead of mp3 for testing functions.

* typo.

* guard against not sox.

* backends definition.

* grouping backend functions into a separate file.

* remove duplicated code.

* requires sox.

* replace by wav, requires sox.

* require with scope.

* undo alignment.

* requires sox for these two, because of mp3.

* no longer need first mp3.

* cleaning.

* new wav version of file.

* flake8.

* remove unnecessary load.

* flake8.

* lint.

* lint.

* revert formatting of file.

* merging into common_utils.

* docstring.

* rename to common_utils.
parent dbed5b11
import os import os
from shutil import copytree
import tempfile import tempfile
from contextlib import contextmanager
from shutil import copytree
import torch import torch
import torchaudio
TEST_DIR_PATH = os.path.dirname(os.path.realpath(__file__)) TEST_DIR_PATH = os.path.dirname(os.path.realpath(__file__))
BACKENDS = torchaudio._backend._audio_backends
def create_temp_assets_dir(): def create_temp_assets_dir():
...@@ -48,3 +51,35 @@ def random_int_tensor(seed, size, low=0, high=2 ** 32, a=22695477, c=1, m=2 ** 3 ...@@ -48,3 +51,35 @@ def random_int_tensor(seed, size, low=0, high=2 ** 32, a=22695477, c=1, m=2 ** 3
""" Same as random_float_tensor but integers between [low, high) """ Same as random_float_tensor but integers between [low, high)
""" """
return torch.floor(random_float_tensor(seed, size, a, c, m) * (high - low)) + low return torch.floor(random_float_tensor(seed, size, a, c, m) * (high - low)) + low
@contextmanager
def AudioBackendScope(new_backend):
previous_backend = torchaudio.get_audio_backend()
try:
torchaudio.set_audio_backend(new_backend)
yield
finally:
torchaudio.set_audio_backend(previous_backend)
def filter_backends_with_mp3(backends):
# Filter out backends that do not support mp3
test_dirpath, _ = create_temp_assets_dir()
test_filepath = os.path.join(
test_dirpath, "assets", "steam-train-whistle-daniel_simon.mp3"
)
def supports_mp3(backend):
try:
with AudioBackendScope(backend):
torchaudio.load(test_filepath)
return True
except RuntimeError:
return False
return [backend for backend in backends if supports_mp3(backend)]
BACKENDS_MP3 = filter_backends_with_mp3(BACKENDS)
import unittest import unittest
import common_utils
import torch import torch
import torchaudio import torchaudio
import math import math
import os import os
from common_utils import AudioBackendScope, BACKENDS, BACKENDS_MP3, create_temp_assets_dir
class AudioBackendScope:
def __init__(self, backend):
self.new_backend = backend
self.previous_backend = torchaudio.get_audio_backend()
def __enter__(self):
torchaudio.set_audio_backend(self.new_backend)
return self.new_backend
def __exit__(self, type, value, traceback):
backend = self.previous_backend
torchaudio.set_audio_backend(backend)
class Test_LoadSave(unittest.TestCase): class Test_LoadSave(unittest.TestCase):
test_dirpath, test_dir = common_utils.create_temp_assets_dir() test_dirpath, test_dir = create_temp_assets_dir()
test_filepath = os.path.join(test_dirpath, "assets", test_filepath = os.path.join(test_dirpath, "assets",
"steam-train-whistle-daniel_simon.mp3") "steam-train-whistle-daniel_simon.mp3")
test_filepath_wav = os.path.join(test_dirpath, "assets", test_filepath_wav = os.path.join(test_dirpath, "assets",
"steam-train-whistle-daniel_simon.wav") "steam-train-whistle-daniel_simon.wav")
def test_1_save(self): def test_1_save(self):
for backend in ["sox"]: for backend in BACKENDS_MP3:
with self.subTest(): with self.subTest():
with AudioBackendScope(backend): with AudioBackendScope(backend):
self._test_1_save(self.test_filepath, False) self._test_1_save(self.test_filepath, False)
for backend in ["sox", "soundfile"]: for backend in BACKENDS:
with self.subTest(): with self.subTest():
with AudioBackendScope(backend): with AudioBackendScope(backend):
self._test_1_save(self.test_filepath_wav, True) self._test_1_save(self.test_filepath_wav, True)
...@@ -79,7 +65,7 @@ class Test_LoadSave(unittest.TestCase): ...@@ -79,7 +65,7 @@ class Test_LoadSave(unittest.TestCase):
torchaudio.save(new_filepath, x, sr) torchaudio.save(new_filepath, x, sr)
def test_1_save_sine(self): def test_1_save_sine(self):
for backend in ["sox", "soundfile"]: for backend in BACKENDS:
with self.subTest(): with self.subTest():
with AudioBackendScope(backend): with AudioBackendScope(backend):
self._test_1_save_sine() self._test_1_save_sine()
...@@ -112,12 +98,12 @@ class Test_LoadSave(unittest.TestCase): ...@@ -112,12 +98,12 @@ class Test_LoadSave(unittest.TestCase):
os.unlink(new_filepath) os.unlink(new_filepath)
def test_2_load(self): def test_2_load(self):
for backend in ["sox"]: for backend in BACKENDS_MP3:
with self.subTest(): with self.subTest():
with AudioBackendScope(backend): with AudioBackendScope(backend):
self._test_2_load(self.test_filepath, 278756) self._test_2_load(self.test_filepath, 278756)
for backend in ["sox", "soundfile"]: for backend in BACKENDS:
with self.subTest(): with self.subTest():
with AudioBackendScope(backend): with AudioBackendScope(backend):
self._test_2_load(self.test_filepath_wav, 276858) self._test_2_load(self.test_filepath_wav, 276858)
...@@ -153,7 +139,7 @@ class Test_LoadSave(unittest.TestCase): ...@@ -153,7 +139,7 @@ class Test_LoadSave(unittest.TestCase):
torchaudio.load(tdir) torchaudio.load(tdir)
def test_2_load_nonormalization(self): def test_2_load_nonormalization(self):
for backend in ["sox"]: for backend in BACKENDS_MP3:
with self.subTest(): with self.subTest():
with AudioBackendScope(backend): with AudioBackendScope(backend):
self._test_2_load_nonormalization(self.test_filepath, 278756) self._test_2_load_nonormalization(self.test_filepath, 278756)
...@@ -170,7 +156,7 @@ class Test_LoadSave(unittest.TestCase): ...@@ -170,7 +156,7 @@ class Test_LoadSave(unittest.TestCase):
self.assertTrue(isinstance(x, torch.LongTensor)) self.assertTrue(isinstance(x, torch.LongTensor))
def test_3_load_and_save_is_identity(self): def test_3_load_and_save_is_identity(self):
for backend in ["sox", "soundfile"]: for backend in BACKENDS:
with self.subTest(): with self.subTest():
with AudioBackendScope(backend): with AudioBackendScope(backend):
self._test_3_load_and_save_is_identity() self._test_3_load_and_save_is_identity()
...@@ -185,6 +171,7 @@ class Test_LoadSave(unittest.TestCase): ...@@ -185,6 +171,7 @@ class Test_LoadSave(unittest.TestCase):
self.assertEqual(sample_rate, sample_rate2) self.assertEqual(sample_rate, sample_rate2)
os.unlink(output_path) os.unlink(output_path)
@unittest.skipIf(set(["sox", "soundfile"]) not in set(BACKENDS), "sox and soundfile are not available")
def test_3_load_and_save_is_identity_across_backend(self): def test_3_load_and_save_is_identity_across_backend(self):
with self.subTest(): with self.subTest():
self._test_3_load_and_save_is_identity_across_backend("sox", "soundfile") self._test_3_load_and_save_is_identity_across_backend("sox", "soundfile")
...@@ -208,7 +195,7 @@ class Test_LoadSave(unittest.TestCase): ...@@ -208,7 +195,7 @@ class Test_LoadSave(unittest.TestCase):
os.unlink(output_path) os.unlink(output_path)
def test_4_load_partial(self): def test_4_load_partial(self):
for backend in ["sox"]: for backend in BACKENDS_MP3:
with self.subTest(): with self.subTest():
with AudioBackendScope(backend): with AudioBackendScope(backend):
self._test_4_load_partial() self._test_4_load_partial()
...@@ -250,7 +237,7 @@ class Test_LoadSave(unittest.TestCase): ...@@ -250,7 +237,7 @@ class Test_LoadSave(unittest.TestCase):
torchaudio.load(input_sine_path, offset=100000) torchaudio.load(input_sine_path, offset=100000)
def test_5_get_info(self): def test_5_get_info(self):
for backend in ["sox", "soundfile"]: for backend in BACKENDS:
with self.subTest(): with self.subTest():
with AudioBackendScope(backend): with AudioBackendScope(backend):
self._test_5_get_info() self._test_5_get_info()
......
import math import math
import os import os
import common_utils
import compliance.utils import compliance.utils
import torch import torch
import torchaudio import torchaudio
import torchaudio.compliance.kaldi as kaldi import torchaudio.compliance.kaldi as kaldi
import unittest import unittest
from common_utils import AudioBackendScope, BACKENDS, create_temp_assets_dir
def extract_window(window, wave, f, frame_length, frame_shift, snip_edges): def extract_window(window, wave, f, frame_length, frame_shift, snip_edges):
...@@ -45,7 +45,7 @@ def extract_window(window, wave, f, frame_length, frame_shift, snip_edges): ...@@ -45,7 +45,7 @@ def extract_window(window, wave, f, frame_length, frame_shift, snip_edges):
class Test_Kaldi(unittest.TestCase): class Test_Kaldi(unittest.TestCase):
test_dirpath, test_dir = common_utils.create_temp_assets_dir() test_dirpath, test_dir = create_temp_assets_dir()
test_filepath = os.path.join(test_dirpath, 'assets', 'kaldi_file.wav') test_filepath = os.path.join(test_dirpath, 'assets', 'kaldi_file.wav')
test_8000_filepath = os.path.join(test_dirpath, 'assets', 'kaldi_file_8000.wav') test_8000_filepath = os.path.join(test_dirpath, 'assets', 'kaldi_file_8000.wav')
kaldi_output_dir = os.path.join(test_dirpath, 'assets', 'kaldi') kaldi_output_dir = os.path.join(test_dirpath, 'assets', 'kaldi')
...@@ -159,6 +159,8 @@ class Test_Kaldi(unittest.TestCase): ...@@ -159,6 +159,8 @@ class Test_Kaldi(unittest.TestCase):
self.assertTrue(output.shape, kaldi_output.shape) self.assertTrue(output.shape, kaldi_output.shape)
self.assertTrue(torch.allclose(output, kaldi_output, atol=atol, rtol=rtol)) self.assertTrue(torch.allclose(output, kaldi_output, atol=atol, rtol=rtol))
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_spectrogram(self): def test_spectrogram(self):
def get_output_fn(sound, args): def get_output_fn(sound, args):
output = kaldi.spectrogram( output = kaldi.spectrogram(
...@@ -179,6 +181,8 @@ class Test_Kaldi(unittest.TestCase): ...@@ -179,6 +181,8 @@ class Test_Kaldi(unittest.TestCase):
self._compliance_test_helper(self.test_filepath, 'spec', 131, 13, get_output_fn, atol=1e-3, rtol=0) self._compliance_test_helper(self.test_filepath, 'spec', 131, 13, get_output_fn, atol=1e-3, rtol=0)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_fbank(self): def test_fbank(self):
def get_output_fn(sound, args): def get_output_fn(sound, args):
output = kaldi.fbank( output = kaldi.fbank(
...@@ -209,6 +213,8 @@ class Test_Kaldi(unittest.TestCase): ...@@ -209,6 +213,8 @@ class Test_Kaldi(unittest.TestCase):
self._compliance_test_helper(self.test_filepath, 'fbank', 97, 22, get_output_fn, atol=1e-3, rtol=1e-1) self._compliance_test_helper(self.test_filepath, 'fbank', 97, 22, get_output_fn, atol=1e-3, rtol=1e-1)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_mfcc(self): def test_mfcc(self):
def get_output_fn(sound, args): def get_output_fn(sound, args):
output = kaldi.mfcc( output = kaldi.mfcc(
...@@ -243,6 +249,8 @@ class Test_Kaldi(unittest.TestCase): ...@@ -243,6 +249,8 @@ class Test_Kaldi(unittest.TestCase):
# Passing in an empty tensor should result in an error # Passing in an empty tensor should result in an error
self.assertRaises(AssertionError, kaldi.mfcc, torch.empty(0)) self.assertRaises(AssertionError, kaldi.mfcc, torch.empty(0))
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_resample_waveform(self): def test_resample_waveform(self):
def get_output_fn(sound, args): def get_output_fn(sound, args):
output = kaldi.resample_waveform(sound, args[1], args[2]) output = kaldi.resample_waveform(sound, args[1], args[2])
......
import unittest import unittest
import common_utils
import torch import torch
import torch.nn as nn import torch.nn as nn
from torch.utils.data import Dataset, DataLoader from torch.utils.data import Dataset, DataLoader
import torchaudio import torchaudio
import math import math
import os import os
from common_utils import AudioBackendScope, BACKENDS, create_temp_assets_dir
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
class TORCHAUDIODS(Dataset): class TORCHAUDIODS(Dataset):
test_dirpath, test_dir = common_utils.create_temp_assets_dir() test_dirpath, test_dir = create_temp_assets_dir()
def __init__(self): def __init__(self):
self.asset_dirpath = os.path.join(self.test_dirpath, "assets") self.asset_dirpath = os.path.join(self.test_dirpath, "assets")
...@@ -33,6 +34,7 @@ class TORCHAUDIODS(Dataset): ...@@ -33,6 +34,7 @@ class TORCHAUDIODS(Dataset):
return len(self.data) return len(self.data)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
class Test_DataLoader(unittest.TestCase): class Test_DataLoader(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
...@@ -50,4 +52,5 @@ class Test_DataLoader(unittest.TestCase): ...@@ -50,4 +52,5 @@ class Test_DataLoader(unittest.TestCase):
self.assertTrue(x.size() == expected_size) self.assertTrue(x.size() == expected_size)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() with AudioBackendScope("sox"):
unittest.main()
...@@ -9,6 +9,7 @@ import pytest ...@@ -9,6 +9,7 @@ import pytest
import unittest import unittest
import common_utils import common_utils
from common_utils import AudioBackendScope, BACKENDS
from torchaudio.common_utils import IMPORT_LIBROSA from torchaudio.common_utils import IMPORT_LIBROSA
if IMPORT_LIBROSA: if IMPORT_LIBROSA:
...@@ -39,7 +40,7 @@ class TestFunctional(unittest.TestCase): ...@@ -39,7 +40,7 @@ class TestFunctional(unittest.TestCase):
test_dirpath, test_dir = common_utils.create_temp_assets_dir() test_dirpath, test_dir = common_utils.create_temp_assets_dir()
test_filepath = os.path.join(test_dirpath, 'assets', test_filepath = os.path.join(test_dirpath, 'assets',
'steam-train-whistle-daniel_simon.mp3') 'steam-train-whistle-daniel_simon.wav')
waveform_train, sr_train = torchaudio.load(test_filepath) waveform_train, sr_train = torchaudio.load(test_filepath)
def test_torchscript_spectrogram(self): def test_torchscript_spectrogram(self):
...@@ -433,6 +434,8 @@ class TestFunctional(unittest.TestCase): ...@@ -433,6 +434,8 @@ class TestFunctional(unittest.TestCase):
self._test_create_fb(n_mels=56, fmin=1900.0, fmax=900.0) self._test_create_fb(n_mels=56, fmin=1900.0, fmax=900.0)
self._test_create_fb(n_mels=10, fmin=1900.0, fmax=900.0) self._test_create_fb(n_mels=10, fmin=1900.0, fmax=900.0)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_gain(self): def test_gain(self):
waveform_gain = F.gain(self.waveform_train, 3) waveform_gain = F.gain(self.waveform_train, 3)
self.assertTrue(waveform_gain.abs().max().item(), 1.) self.assertTrue(waveform_gain.abs().max().item(), 1.)
...@@ -444,6 +447,8 @@ class TestFunctional(unittest.TestCase): ...@@ -444,6 +447,8 @@ class TestFunctional(unittest.TestCase):
self.assertTrue(torch.allclose(waveform_gain, sox_gain_waveform, atol=1e-04)) self.assertTrue(torch.allclose(waveform_gain, sox_gain_waveform, atol=1e-04))
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_dither(self): def test_dither(self):
waveform_dithered = F.dither(self.waveform_train) waveform_dithered = F.dither(self.waveform_train)
waveform_dithered_noiseshaped = F.dither(self.waveform_train, noise_shaping=True) waveform_dithered_noiseshaped = F.dither(self.waveform_train, noise_shaping=True)
...@@ -461,6 +466,8 @@ class TestFunctional(unittest.TestCase): ...@@ -461,6 +466,8 @@ class TestFunctional(unittest.TestCase):
self.assertTrue(torch.allclose(waveform_dithered_noiseshaped, sox_dither_waveform_ns, atol=1e-02)) self.assertTrue(torch.allclose(waveform_dithered_noiseshaped, sox_dither_waveform_ns, atol=1e-02))
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_vctk_transform_pipeline(self): def test_vctk_transform_pipeline(self):
test_filepath_vctk = os.path.join(self.test_dirpath, "assets/VCTK-Corpus/wav48/p224/", "p224_002.wav") test_filepath_vctk = os.path.join(self.test_dirpath, "assets/VCTK-Corpus/wav48/p224/", "p224_002.wav")
wf_vctk, sr_vctk = torchaudio.load(test_filepath_vctk) wf_vctk, sr_vctk = torchaudio.load(test_filepath_vctk)
......
...@@ -4,8 +4,8 @@ import torch ...@@ -4,8 +4,8 @@ import torch
import torchaudio import torchaudio
import torchaudio.functional as F import torchaudio.functional as F
import unittest import unittest
import common_utils
import time import time
from common_utils import AudioBackendScope, BACKENDS, create_temp_assets_dir
def _test_torchscript_functional(py_method, *args, **kwargs): def _test_torchscript_functional(py_method, *args, **kwargs):
...@@ -18,7 +18,7 @@ def _test_torchscript_functional(py_method, *args, **kwargs): ...@@ -18,7 +18,7 @@ def _test_torchscript_functional(py_method, *args, **kwargs):
class TestFunctionalFiltering(unittest.TestCase): class TestFunctionalFiltering(unittest.TestCase):
test_dirpath, test_dir = common_utils.create_temp_assets_dir() test_dirpath, test_dir = create_temp_assets_dir()
def _test_lfilter_basic(self, dtype, device): def _test_lfilter_basic(self, dtype, device):
""" """
...@@ -91,14 +91,14 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -91,14 +91,14 @@ class TestFunctionalFiltering(unittest.TestCase):
def test_lfilter(self): def test_lfilter(self):
filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
waveform, _ = torchaudio.load(filepath, normalization=True) waveform, _ = torchaudio.load(filepath, normalization=True)
self._test_lfilter(waveform, torch.device("cpu")) self._test_lfilter(waveform, torch.device("cpu"))
def test_lfilter_gpu(self): def test_lfilter_gpu(self):
if torch.cuda.is_available(): if torch.cuda.is_available():
filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
waveform, _ = torchaudio.load(filepath, normalization=True) waveform, _ = torchaudio.load(filepath, normalization=True)
cuda0 = torch.device("cuda:0") cuda0 = torch.device("cuda:0")
cuda_waveform = waveform.cuda(device=cuda0) cuda_waveform = waveform.cuda(device=cuda0)
...@@ -107,6 +107,8 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -107,6 +107,8 @@ class TestFunctionalFiltering(unittest.TestCase):
print("skipping GPU test for lfilter because device not available") print("skipping GPU test for lfilter because device not available")
pass pass
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_lowpass(self): def test_lowpass(self):
""" """
...@@ -115,7 +117,7 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -115,7 +117,7 @@ class TestFunctionalFiltering(unittest.TestCase):
CUTOFF_FREQ = 3000 CUTOFF_FREQ = 3000
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("lowpass", [CUTOFF_FREQ]) E.append_effect_to_chain("lowpass", [CUTOFF_FREQ])
...@@ -127,6 +129,8 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -127,6 +129,8 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.lowpass_biquad, waveform, sample_rate, CUTOFF_FREQ) _test_torchscript_functional(F.lowpass_biquad, waveform, sample_rate, CUTOFF_FREQ)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_highpass(self): def test_highpass(self):
""" """
Test biquad highpass filter, compare to SoX implementation Test biquad highpass filter, compare to SoX implementation
...@@ -134,7 +138,7 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -134,7 +138,7 @@ class TestFunctionalFiltering(unittest.TestCase):
CUTOFF_FREQ = 2000 CUTOFF_FREQ = 2000
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("highpass", [CUTOFF_FREQ]) E.append_effect_to_chain("highpass", [CUTOFF_FREQ])
...@@ -147,6 +151,8 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -147,6 +151,8 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-3) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-3)
_test_torchscript_functional(F.highpass_biquad, waveform, sample_rate, CUTOFF_FREQ) _test_torchscript_functional(F.highpass_biquad, waveform, sample_rate, CUTOFF_FREQ)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_allpass(self): def test_allpass(self):
""" """
Test biquad allpass filter, compare to SoX implementation Test biquad allpass filter, compare to SoX implementation
...@@ -155,7 +161,7 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -155,7 +161,7 @@ class TestFunctionalFiltering(unittest.TestCase):
CENTRAL_FREQ = 1000 CENTRAL_FREQ = 1000
Q = 0.707 Q = 0.707
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("allpass", [CENTRAL_FREQ, str(Q) + 'q']) E.append_effect_to_chain("allpass", [CENTRAL_FREQ, str(Q) + 'q'])
...@@ -167,6 +173,8 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -167,6 +173,8 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.allpass_biquad, waveform, sample_rate, CENTRAL_FREQ, Q) _test_torchscript_functional(F.allpass_biquad, waveform, sample_rate, CENTRAL_FREQ, Q)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_bandpass_with_csg(self): def test_bandpass_with_csg(self):
""" """
Test biquad bandpass filter, compare to SoX implementation Test biquad bandpass filter, compare to SoX implementation
...@@ -176,7 +184,7 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -176,7 +184,7 @@ class TestFunctionalFiltering(unittest.TestCase):
Q = 0.707 Q = 0.707
CONST_SKIRT_GAIN = True CONST_SKIRT_GAIN = True
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("bandpass", ["-c", CENTRAL_FREQ, str(Q) + 'q']) E.append_effect_to_chain("bandpass", ["-c", CENTRAL_FREQ, str(Q) + 'q'])
...@@ -188,6 +196,8 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -188,6 +196,8 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.bandpass_biquad, waveform, sample_rate, CENTRAL_FREQ, Q, CONST_SKIRT_GAIN) _test_torchscript_functional(F.bandpass_biquad, waveform, sample_rate, CENTRAL_FREQ, Q, CONST_SKIRT_GAIN)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_bandpass_without_csg(self): def test_bandpass_without_csg(self):
""" """
Test biquad bandpass filter, compare to SoX implementation Test biquad bandpass filter, compare to SoX implementation
...@@ -197,7 +207,7 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -197,7 +207,7 @@ class TestFunctionalFiltering(unittest.TestCase):
Q = 0.707 Q = 0.707
CONST_SKIRT_GAIN = False CONST_SKIRT_GAIN = False
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("bandpass", [CENTRAL_FREQ, str(Q) + 'q']) E.append_effect_to_chain("bandpass", [CENTRAL_FREQ, str(Q) + 'q'])
...@@ -209,6 +219,8 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -209,6 +219,8 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.bandpass_biquad, waveform, sample_rate, CENTRAL_FREQ, Q, CONST_SKIRT_GAIN) _test_torchscript_functional(F.bandpass_biquad, waveform, sample_rate, CENTRAL_FREQ, Q, CONST_SKIRT_GAIN)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_bandreject(self): def test_bandreject(self):
""" """
Test biquad bandreject filter, compare to SoX implementation Test biquad bandreject filter, compare to SoX implementation
...@@ -217,7 +229,7 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -217,7 +229,7 @@ class TestFunctionalFiltering(unittest.TestCase):
CENTRAL_FREQ = 1000 CENTRAL_FREQ = 1000
Q = 0.707 Q = 0.707
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("bandreject", [CENTRAL_FREQ, str(Q) + 'q']) E.append_effect_to_chain("bandreject", [CENTRAL_FREQ, str(Q) + 'q'])
...@@ -229,6 +241,8 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -229,6 +241,8 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.bandreject_biquad, waveform, sample_rate, CENTRAL_FREQ, Q) _test_torchscript_functional(F.bandreject_biquad, waveform, sample_rate, CENTRAL_FREQ, Q)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_band_with_noise(self): def test_band_with_noise(self):
""" """
Test biquad band filter with noise mode, compare to SoX implementation Test biquad band filter with noise mode, compare to SoX implementation
...@@ -238,7 +252,7 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -238,7 +252,7 @@ class TestFunctionalFiltering(unittest.TestCase):
Q = 0.707 Q = 0.707
NOISE = True NOISE = True
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("band", ["-n", CENTRAL_FREQ, str(Q) + 'q']) E.append_effect_to_chain("band", ["-n", CENTRAL_FREQ, str(Q) + 'q'])
...@@ -250,6 +264,8 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -250,6 +264,8 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.band_biquad, waveform, sample_rate, CENTRAL_FREQ, Q, NOISE) _test_torchscript_functional(F.band_biquad, waveform, sample_rate, CENTRAL_FREQ, Q, NOISE)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_band_without_noise(self): def test_band_without_noise(self):
""" """
Test biquad band filter without noise mode, compare to SoX implementation Test biquad band filter without noise mode, compare to SoX implementation
...@@ -259,7 +275,7 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -259,7 +275,7 @@ class TestFunctionalFiltering(unittest.TestCase):
Q = 0.707 Q = 0.707
NOISE = False NOISE = False
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("band", [CENTRAL_FREQ, str(Q) + 'q']) E.append_effect_to_chain("band", [CENTRAL_FREQ, str(Q) + 'q'])
...@@ -271,6 +287,8 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -271,6 +287,8 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.band_biquad, waveform, sample_rate, CENTRAL_FREQ, Q, NOISE) _test_torchscript_functional(F.band_biquad, waveform, sample_rate, CENTRAL_FREQ, Q, NOISE)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_treble(self): def test_treble(self):
""" """
Test biquad treble filter, compare to SoX implementation Test biquad treble filter, compare to SoX implementation
...@@ -280,7 +298,7 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -280,7 +298,7 @@ class TestFunctionalFiltering(unittest.TestCase):
Q = 0.707 Q = 0.707
GAIN = 40 GAIN = 40
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("treble", [GAIN, CENTRAL_FREQ, str(Q) + 'q']) E.append_effect_to_chain("treble", [GAIN, CENTRAL_FREQ, str(Q) + 'q'])
...@@ -292,12 +310,14 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -292,12 +310,14 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.treble_biquad, waveform, sample_rate, GAIN, CENTRAL_FREQ, Q) _test_torchscript_functional(F.treble_biquad, waveform, sample_rate, GAIN, CENTRAL_FREQ, Q)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_deemph(self): def test_deemph(self):
""" """
Test biquad deemph filter, compare to SoX implementation Test biquad deemph filter, compare to SoX implementation
""" """
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("deemph") E.append_effect_to_chain("deemph")
...@@ -309,12 +329,14 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -309,12 +329,14 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.deemph_biquad, waveform, sample_rate) _test_torchscript_functional(F.deemph_biquad, waveform, sample_rate)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_riaa(self): def test_riaa(self):
""" """
Test biquad riaa filter, compare to SoX implementation Test biquad riaa filter, compare to SoX implementation
""" """
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("riaa") E.append_effect_to_chain("riaa")
...@@ -326,6 +348,8 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -326,6 +348,8 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.riaa_biquad, waveform, sample_rate) _test_torchscript_functional(F.riaa_biquad, waveform, sample_rate)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_equalizer(self): def test_equalizer(self):
""" """
Test biquad peaking equalizer filter, compare to SoX implementation Test biquad peaking equalizer filter, compare to SoX implementation
...@@ -335,7 +359,7 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -335,7 +359,7 @@ class TestFunctionalFiltering(unittest.TestCase):
Q = 0.707 Q = 0.707
GAIN = 1 GAIN = 1
noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") noise_filepath = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
E = torchaudio.sox_effects.SoxEffectsChain() E = torchaudio.sox_effects.SoxEffectsChain()
E.set_input_file(noise_filepath) E.set_input_file(noise_filepath)
E.append_effect_to_chain("equalizer", [CENTER_FREQ, Q, GAIN]) E.append_effect_to_chain("equalizer", [CENTER_FREQ, Q, GAIN])
...@@ -347,9 +371,11 @@ class TestFunctionalFiltering(unittest.TestCase): ...@@ -347,9 +371,11 @@ class TestFunctionalFiltering(unittest.TestCase):
assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4) assert torch.allclose(sox_output_waveform, output_waveform, atol=1e-4)
_test_torchscript_functional(F.equalizer_biquad, waveform, sample_rate, CENTER_FREQ, GAIN, Q) _test_torchscript_functional(F.equalizer_biquad, waveform, sample_rate, CENTER_FREQ, GAIN, Q)
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_perf_biquad_filtering(self): def test_perf_biquad_filtering(self):
fn_sine = os.path.join(self.test_dirpath, "assets", "whitenoise.mp3") fn_sine = os.path.join(self.test_dirpath, "assets", "whitenoise.wav")
b0 = 0.4 b0 = 0.4
b1 = 0.2 b1 = 0.2
......
import unittest import unittest
import common_utils
import torch import torch
import torchaudio import torchaudio
import math import math
import os import os
from common_utils import AudioBackendScope, BACKENDS, create_temp_assets_dir
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
class Test_SoxEffectsChain(unittest.TestCase): class Test_SoxEffectsChain(unittest.TestCase):
test_dirpath, test_dir = common_utils.create_temp_assets_dir() test_dirpath, test_dir = create_temp_assets_dir()
test_filepath = os.path.join(test_dirpath, "assets", test_filepath = os.path.join(test_dirpath, "assets",
"steam-train-whistle-daniel_simon.mp3") "steam-train-whistle-daniel_simon.mp3")
...@@ -259,4 +261,5 @@ class Test_SoxEffectsChain(unittest.TestCase): ...@@ -259,4 +261,5 @@ class Test_SoxEffectsChain(unittest.TestCase):
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() with AudioBackendScope("sox"):
unittest.main()
...@@ -7,7 +7,7 @@ import torchaudio.transforms as transforms ...@@ -7,7 +7,7 @@ import torchaudio.transforms as transforms
import torchaudio.functional as F import torchaudio.functional as F
from torchaudio.common_utils import IMPORT_LIBROSA, IMPORT_SCIPY from torchaudio.common_utils import IMPORT_LIBROSA, IMPORT_SCIPY
import unittest import unittest
import common_utils from common_utils import AudioBackendScope, BACKENDS, create_temp_assets_dir
if IMPORT_LIBROSA: if IMPORT_LIBROSA:
import librosa import librosa
...@@ -52,9 +52,9 @@ class Tester(unittest.TestCase): ...@@ -52,9 +52,9 @@ class Tester(unittest.TestCase):
waveform.unsqueeze_(0) # (1, 64000) waveform.unsqueeze_(0) # (1, 64000)
waveform = (waveform * volume * 2**31).long() waveform = (waveform * volume * 2**31).long()
# file for stereo stft test # file for stereo stft test
test_dirpath, test_dir = common_utils.create_temp_assets_dir() test_dirpath, test_dir = create_temp_assets_dir()
test_filepath = os.path.join(test_dirpath, 'assets', test_filepath = os.path.join(test_dirpath, 'assets',
'steam-train-whistle-daniel_simon.mp3') 'steam-train-whistle-daniel_simon.wav')
def scale(self, waveform, factor=float(2**31)): def scale(self, waveform, factor=float(2**31)):
# scales a waveform by a factor # scales a waveform by a factor
...@@ -530,8 +530,13 @@ class Tester(unittest.TestCase): ...@@ -530,8 +530,13 @@ class Tester(unittest.TestCase):
self.assertTrue(computed.shape == expected.shape, (computed.shape, expected.shape)) self.assertTrue(computed.shape == expected.shape, (computed.shape, expected.shape))
self.assertTrue(torch.allclose(computed, expected)) self.assertTrue(torch.allclose(computed, expected))
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_batch_mfcc(self): def test_batch_mfcc(self):
waveform, sample_rate = torchaudio.load(self.test_filepath) test_filepath = os.path.join(
self.test_dirpath, 'assets', 'steam-train-whistle-daniel_simon.mp3'
)
waveform, sample_rate = torchaudio.load(test_filepath)
# Single then transform then batch # Single then transform then batch
expected = transforms.MFCC()(waveform).repeat(3, 1, 1, 1) expected = transforms.MFCC()(waveform).repeat(3, 1, 1, 1)
...@@ -632,7 +637,7 @@ class TestLibrosaConsistency(unittest.TestCase): ...@@ -632,7 +637,7 @@ class TestLibrosaConsistency(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
cls.test_dirpath, cls.test_dir = common_utils.create_temp_assets_dir() cls.test_dirpath, cls.test_dir = create_temp_assets_dir()
def _to_librosa(self, sound): def _to_librosa(self, sound):
return sound.cpu().numpy().squeeze() return sound.cpu().numpy().squeeze()
...@@ -644,6 +649,8 @@ class TestLibrosaConsistency(unittest.TestCase): ...@@ -644,6 +649,8 @@ class TestLibrosaConsistency(unittest.TestCase):
return sound.mean(dim=0, keepdim=True), sample_rate return sound.mean(dim=0, keepdim=True), sample_rate
@unittest.skipIf(not IMPORT_LIBROSA, 'Librosa is not available') @unittest.skipIf(not IMPORT_LIBROSA, 'Librosa is not available')
@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_MelScale(self): def test_MelScale(self):
"""MelScale transform is comparable to that of librosa""" """MelScale transform is comparable to that of librosa"""
n_fft = 2048 n_fft = 2048
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment