Skip to content

Backend switch #355

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

Merged
merged 33 commits into from
Dec 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
fffcdc0
move sox inside function calls.
vincentqb Nov 25, 2019
aa30033
add backend switch mechanism.
vincentqb Dec 4, 2019
e69001d
import sox at runtime, not import.
vincentqb Dec 4, 2019
3b16e04
add backend list.
vincentqb Dec 4, 2019
ff2497f
backend tests.
vincentqb Dec 4, 2019
523b7c2
creating hidden modules for backend.
vincentqb Dec 5, 2019
11a02a0
naming backend same as file: soundfile.
vincentqb Dec 5, 2019
ecdac3b
remove docstring in backend file.
vincentqb Dec 5, 2019
cbafd09
test soundfile info.
vincentqb Dec 5, 2019
fd51aa2
soundfile doesn't support int64.
vincentqb Dec 5, 2019
5459965
test only specified backend.
vincentqb Dec 5, 2019
55bac5d
add support for precision.
vincentqb Dec 5, 2019
41d0f8f
remove inplace out support.
vincentqb Dec 5, 2019
823138e
flake8.
vincentqb Dec 5, 2019
ea7a827
explicitly convert from numpy.
vincentqb Dec 5, 2019
0a54a38
adding test for wav file.
vincentqb Dec 6, 2019
300096d
standardizing tests.
vincentqb Dec 6, 2019
15de2fc
getattr to load module.
vincentqb Dec 6, 2019
0202cf5
soundfile info follows sox.
vincentqb Dec 6, 2019
16179e8
error with incorrect parameter instead of silent ignore.
vincentqb Dec 6, 2019
45d214d
correct name of test.
vincentqb Dec 6, 2019
3285c8b
normalization required for soundfile.
vincentqb Dec 6, 2019
2f5caf2
flake8.
vincentqb Dec 6, 2019
0d9b3d5
no need to change.
vincentqb Dec 6, 2019
6905086
no need to change.
vincentqb Dec 6, 2019
fa50b00
no need to change.
vincentqb Dec 6, 2019
45b65ec
no need to change.
vincentqb Dec 6, 2019
4a9064b
add equivalent wav file.
vincentqb Dec 6, 2019
7aac175
oneliner.
vincentqb Dec 6, 2019
d0690ae
adding test across backend. using float32 as done in sox.
vincentqb Dec 13, 2019
5f6494f
backend guard decorator.
vincentqb Dec 17, 2019
00066ef
move to backend file, for easier import.
vincentqb Dec 18, 2019
bac898b
remove commented out line
vincentqb Dec 19, 2019
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/steam-train-whistle-daniel_simon.wav
Binary file not shown.
128 changes: 111 additions & 17 deletions test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,41 @@
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)


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

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

for backend in ["sox", "soundfile"]:
with self.subTest():
with AudioBackendScope(backend):
self._test_1_save(self.test_filepath_wav, True)

def _test_1_save(self, test_filepath, normalization):
# load signal
x, sr = torchaudio.load(self.test_filepath, normalization=False)
x, sr = torchaudio.load(test_filepath, normalization=normalization)

# check save
new_filepath = os.path.join(self.test_dirpath, "test.wav")
Expand Down Expand Up @@ -52,6 +79,14 @@ def test_1_save(self):
"test.wav")
torchaudio.save(new_filepath, x, sr)

def test_1_save_sine(self):
for backend in ["sox", "soundfile"]:
with self.subTest():
with AudioBackendScope(backend):
self._test_1_save_sine()

def _test_1_save_sine(self):

# save created file
sinewave_filepath = os.path.join(self.test_dirpath, "assets",
"sinewave.wav")
Expand All @@ -78,34 +113,36 @@ def test_1_save(self):
os.unlink(new_filepath)

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

for backend in ["sox", "soundfile"]:
with self.subTest():
with AudioBackendScope(backend):
self._test_2_load(self.test_filepath_wav, 276858)

def _test_2_load(self, test_filepath, length):
# check normal loading
x, sr = torchaudio.load(self.test_filepath)
x, sr = torchaudio.load(test_filepath)
self.assertEqual(sr, 44100)
self.assertEqual(x.size(), (2, 278756))

# check no normalizing
x, _ = torchaudio.load(self.test_filepath, normalization=False)
self.assertTrue(x.min() <= -1.0)
self.assertTrue(x.max() >= 1.0)
self.assertEqual(x.size(), (2, length))

# check offset
offset = 15
x, _ = torchaudio.load(self.test_filepath)
x_offset, _ = torchaudio.load(self.test_filepath, offset=offset)
x, _ = torchaudio.load(test_filepath)
x_offset, _ = torchaudio.load(test_filepath, offset=offset)
self.assertTrue(x[:, offset:].allclose(x_offset))

# check number of frames
n = 201
x, _ = torchaudio.load(self.test_filepath, num_frames=n)
x, _ = torchaudio.load(test_filepath, num_frames=n)
self.assertTrue(x.size(), (2, n))

# check channels first
x, _ = torchaudio.load(self.test_filepath, channels_first=False)
self.assertEqual(x.size(), (278756, 2))

# check different input tensor type
x, _ = torchaudio.load(self.test_filepath, torch.LongTensor(), normalization=False)
self.assertTrue(isinstance(x, torch.LongTensor))
x, _ = torchaudio.load(test_filepath, channels_first=False)
self.assertEqual(x.size(), (length, 2))

# check raising errors
with self.assertRaises(OSError):
Expand All @@ -116,7 +153,30 @@ def test_2_load(self):
os.path.dirname(self.test_dirpath), "torchaudio")
torchaudio.load(tdir)

def test_2_load_nonormalization(self):
for backend in ["sox"]:
with self.subTest():
with AudioBackendScope(backend):
self._test_2_load_nonormalization(self.test_filepath, 278756)

def _test_2_load_nonormalization(self, test_filepath, length):

# check no normalizing
x, _ = torchaudio.load(test_filepath, normalization=False)
self.assertTrue(x.min() <= -1.0)
self.assertTrue(x.max() >= 1.0)

# check different input tensor type
x, _ = torchaudio.load(test_filepath, torch.LongTensor(), normalization=False)
self.assertTrue(isinstance(x, torch.LongTensor))

def test_3_load_and_save_is_identity(self):
for backend in ["sox", "soundfile"]:
with self.subTest():
with AudioBackendScope(backend):
self._test_3_load_and_save_is_identity()

def _test_3_load_and_save_is_identity(self):
input_path = os.path.join(self.test_dirpath, 'assets', 'sinewave.wav')
tensor, sample_rate = torchaudio.load(input_path)
output_path = os.path.join(self.test_dirpath, 'test.wav')
Expand All @@ -126,7 +186,35 @@ def test_3_load_and_save_is_identity(self):
self.assertEqual(sample_rate, sample_rate2)
os.unlink(output_path)

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")
with self.subTest():
self._test_3_load_and_save_is_identity_across_backend("soundfile", "sox")

def _test_3_load_and_save_is_identity_across_backend(self, backend1, backend2):
with AudioBackendScope(backend1):

input_path = os.path.join(self.test_dirpath, 'assets', 'sinewave.wav')
tensor1, sample_rate1 = torchaudio.load(input_path)

output_path = os.path.join(self.test_dirpath, 'test.wav')
torchaudio.save(output_path, tensor1, sample_rate1)

with AudioBackendScope(backend2):
tensor2, sample_rate2 = torchaudio.load(output_path)

self.assertTrue(tensor1.allclose(tensor2))
self.assertEqual(sample_rate1, sample_rate2)
os.unlink(output_path)

def test_4_load_partial(self):
for backend in ["sox"]:
with self.subTest():
with AudioBackendScope(backend):
self._test_4_load_partial()

def _test_4_load_partial(self):
num_frames = 101
offset = 201
# load entire mono sinewave wav file, load a partial copy and then compare
Expand Down Expand Up @@ -163,6 +251,12 @@ def test_4_load_partial(self):
torchaudio.load(input_sine_path, offset=100000)

def test_5_get_info(self):
for backend in ["sox", "soundfile"]:
with self.subTest():
with AudioBackendScope(backend):
self._test_5_get_info()

def _test_5_get_info(self):
input_path = os.path.join(self.test_dirpath, 'assets', 'sinewave.wav')
channels, samples, rate, precision = (1, 64000, 16000, 16)
si, ei = torchaudio.info(input_path)
Expand Down
Loading