Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

testing with sox only when sox is available #419

Merged
merged 24 commits into from
Mar 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added test/assets/whitenoise.wav
Binary file not shown.
37 changes: 36 additions & 1 deletion test/common_utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import os
from shutil import copytree
import tempfile
from contextlib import contextmanager
from shutil import copytree

import torch
import torchaudio

TEST_DIR_PATH = os.path.dirname(os.path.realpath(__file__))
BACKENDS = torchaudio._backend._audio_backends


def create_temp_assets_dir():
Expand Down Expand Up @@ -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)
"""
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)
37 changes: 12 additions & 25 deletions test/test.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,25 @@
import unittest
import common_utils
import torch
import torchaudio
import math
import os


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)
from common_utils import AudioBackendScope, BACKENDS, BACKENDS_MP3, create_temp_assets_dir


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",
"steam-train-whistle-daniel_simon.mp3")
test_filepath_wav = os.path.join(test_dirpath, "assets",
"steam-train-whistle-daniel_simon.wav")

def test_1_save(self):
for backend in ["sox"]:
for backend in BACKENDS_MP3:
with self.subTest():
with AudioBackendScope(backend):
self._test_1_save(self.test_filepath, False)

for backend in ["sox", "soundfile"]:
for backend in BACKENDS:
with self.subTest():
with AudioBackendScope(backend):
self._test_1_save(self.test_filepath_wav, True)
Expand Down Expand Up @@ -79,7 +65,7 @@ def _test_1_save(self, test_filepath, normalization):
torchaudio.save(new_filepath, x, sr)

def test_1_save_sine(self):
for backend in ["sox", "soundfile"]:
for backend in BACKENDS:
with self.subTest():
with AudioBackendScope(backend):
self._test_1_save_sine()
Expand Down Expand Up @@ -112,12 +98,12 @@ def _test_1_save_sine(self):
os.unlink(new_filepath)

def test_2_load(self):
for backend in ["sox"]:
for backend in BACKENDS_MP3:
with self.subTest():
with AudioBackendScope(backend):
self._test_2_load(self.test_filepath, 278756)

for backend in ["sox", "soundfile"]:
for backend in BACKENDS:
with self.subTest():
with AudioBackendScope(backend):
self._test_2_load(self.test_filepath_wav, 276858)
Expand Down Expand Up @@ -153,7 +139,7 @@ def _test_2_load(self, test_filepath, length):
torchaudio.load(tdir)

def test_2_load_nonormalization(self):
for backend in ["sox"]:
for backend in BACKENDS_MP3:
with self.subTest():
with AudioBackendScope(backend):
self._test_2_load_nonormalization(self.test_filepath, 278756)
Expand All @@ -170,7 +156,7 @@ def _test_2_load_nonormalization(self, test_filepath, length):
self.assertTrue(isinstance(x, torch.LongTensor))

def test_3_load_and_save_is_identity(self):
for backend in ["sox", "soundfile"]:
for backend in BACKENDS:
with self.subTest():
with AudioBackendScope(backend):
self._test_3_load_and_save_is_identity()
Expand All @@ -185,6 +171,7 @@ def _test_3_load_and_save_is_identity(self):
self.assertEqual(sample_rate, sample_rate2)
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):
with self.subTest():
self._test_3_load_and_save_is_identity_across_backend("sox", "soundfile")
Expand All @@ -208,7 +195,7 @@ def _test_3_load_and_save_is_identity_across_backend(self, backend1, backend2):
os.unlink(output_path)

def test_4_load_partial(self):
for backend in ["sox"]:
for backend in BACKENDS_MP3:
with self.subTest():
with AudioBackendScope(backend):
self._test_4_load_partial()
Expand Down Expand Up @@ -250,7 +237,7 @@ def _test_4_load_partial(self):
torchaudio.load(input_sine_path, offset=100000)

def test_5_get_info(self):
for backend in ["sox", "soundfile"]:
for backend in BACKENDS:
with self.subTest():
with AudioBackendScope(backend):
self._test_5_get_info()
Expand Down
12 changes: 10 additions & 2 deletions test/test_compliance_kaldi.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import math
import os
import common_utils
import compliance.utils
import torch
import torchaudio
import torchaudio.compliance.kaldi as kaldi
import unittest
from common_utils import AudioBackendScope, BACKENDS, create_temp_assets_dir


def extract_window(window, wave, f, frame_length, frame_shift, snip_edges):
Expand Down Expand Up @@ -45,7 +45,7 @@ def first_sample_of_frame(frame, window_size, window_shift, snip_edges):


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_8000_filepath = os.path.join(test_dirpath, 'assets', 'kaldi_file_8000.wav')
kaldi_output_dir = os.path.join(test_dirpath, 'assets', 'kaldi')
Expand Down Expand Up @@ -159,6 +159,8 @@ def _compliance_test_helper(self, sound_filepath, filepath_key, expected_num_fil
self.assertTrue(output.shape, kaldi_output.shape)
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 get_output_fn(sound, args):
output = kaldi.spectrogram(
Expand All @@ -179,6 +181,8 @@ def get_output_fn(sound, args):

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 get_output_fn(sound, args):
output = kaldi.fbank(
Expand Down Expand Up @@ -209,6 +213,8 @@ def get_output_fn(sound, args):

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 get_output_fn(sound, args):
output = kaldi.mfcc(
Expand Down Expand Up @@ -243,6 +249,8 @@ def test_mfcc_empty(self):
# Passing in an empty tensor should result in an error
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 get_output_fn(sound, args):
output = kaldi.resample_waveform(sound, args[1], args[2])
Expand Down
9 changes: 6 additions & 3 deletions test/test_dataloader.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import unittest
import common_utils
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
import torchaudio
import math
import os
from common_utils import AudioBackendScope, BACKENDS, create_temp_assets_dir


@unittest.skipIf("sox" not in BACKENDS, "sox not available")
class TORCHAUDIODS(Dataset):

test_dirpath, test_dir = common_utils.create_temp_assets_dir()
test_dirpath, test_dir = create_temp_assets_dir()

def __init__(self):
self.asset_dirpath = os.path.join(self.test_dirpath, "assets")
Expand All @@ -33,6 +34,7 @@ def __len__(self):
return len(self.data)


@unittest.skipIf("sox" not in BACKENDS, "sox not available")
class Test_DataLoader(unittest.TestCase):
@classmethod
def setUpClass(cls):
Expand All @@ -50,4 +52,5 @@ def test_1(self):
self.assertTrue(x.size() == expected_size)

if __name__ == '__main__':
unittest.main()
with AudioBackendScope("sox"):
unittest.main()
9 changes: 8 additions & 1 deletion test/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import unittest
import common_utils

from common_utils import AudioBackendScope, BACKENDS
from torchaudio.common_utils import IMPORT_LIBROSA

if IMPORT_LIBROSA:
Expand Down Expand Up @@ -39,7 +40,7 @@ class TestFunctional(unittest.TestCase):
test_dirpath, test_dir = common_utils.create_temp_assets_dir()

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)

def test_torchscript_spectrogram(self):
Expand Down Expand Up @@ -433,6 +434,8 @@ def test_create_fb(self):
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)

@unittest.skipIf("sox" not in BACKENDS, "sox not available")
@AudioBackendScope("sox")
def test_gain(self):
waveform_gain = F.gain(self.waveform_train, 3)
self.assertTrue(waveform_gain.abs().max().item(), 1.)
Expand All @@ -444,6 +447,8 @@ def test_gain(self):

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):
waveform_dithered = F.dither(self.waveform_train)
waveform_dithered_noiseshaped = F.dither(self.waveform_train, noise_shaping=True)
Expand All @@ -461,6 +466,8 @@ def test_dither(self):

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):
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)
Expand Down
Loading