Commit bc54ac8a authored by moto's avatar moto Committed by Facebook GitHub Bot
Browse files

[BC-breaking] Remove file-like object support from sox_io backend (#3035)

Summary:
This commit removes file-like obejct support so that we can remove custom patch

The motivation and plan is outlined in https://github.com/pytorch/audio/issues/2950.

Pull Request resolved: https://github.com/pytorch/audio/pull/3035

Reviewed By: hwangjeff

Differential Revision: D44695647

Pulled By: mthrok

fbshipit-source-id: 13af0234e288c041bc7b490e1f967f85ce7eb8ec
parent cc89f743
......@@ -316,13 +316,6 @@ class TestLoadParams(TempDirMixin, PytorchTestCase):
self._test(torch.ops.torchaudio.sox_io_load_audio_file, frame_offset, num_frames, channels_first, normalize)
# test file-like obj
def func(path, *args):
with open(path, "rb") as fileobj:
return torchaudio.lib._torchaudio_sox.load_audio_fileobj(fileobj, *args)
self._test(func, frame_offset, num_frames, channels_first, normalize)
@nested_params(
[0, 1, 10, 100, 1000],
[-1, 1, 10, 100, 1000],
......
import io
import itertools
import os
import tarfile
from contextlib import contextmanager
from parameterized import parameterized
from torchaudio._internal import module_utils as _mod_utils
from torchaudio.backend import sox_io_backend
from torchaudio.utils.sox_utils import get_buffer_size, set_buffer_size
from torchaudio_unittest.backend.common import get_bits_per_sample, get_encoding
from torchaudio_unittest.backend.common import get_encoding
from torchaudio_unittest.common_utils import (
get_asset_path,
get_wav_data,
HttpServerMixin,
PytorchTestCase,
save_wav,
skipIfNoExec,
skipIfNoModule,
skipIfNoSox,
sox_utils,
TempDirMixin,
......@@ -25,10 +17,6 @@ from torchaudio_unittest.common_utils import (
from .common import name_func
if _mod_utils.is_module_available("requests"):
import requests
@skipIfNoExec("sox")
@skipIfNoSox
class TestInfo(TempDirMixin, PytorchTestCase):
......@@ -329,268 +317,6 @@ class TestLoadWithoutExtension(PytorchTestCase):
assert sinfo.bits_per_sample == 0 # bit_per_sample is irrelevant for compressed formats
assert sinfo.encoding == "MP3"
with open(path, "rb") as fileobj:
sinfo = sox_io_backend.info(fileobj, format="mp3")
assert sinfo.sample_rate == 16000
assert sinfo.num_frames == 80000
assert sinfo.num_channels == 1
assert sinfo.bits_per_sample == 0
assert sinfo.encoding == "MP3"
class FileObjTestBase(TempDirMixin):
def _gen_file(self, ext, dtype, sample_rate, num_channels, num_frames, *, comments=None):
path = self.get_temp_path(f"test.{ext}")
bit_depth = sox_utils.get_bit_depth(dtype)
duration = num_frames / sample_rate
comment_file = self._gen_comment_file(comments) if comments else None
sox_utils.gen_audio_file(
path,
sample_rate,
num_channels=num_channels,
encoding=sox_utils.get_encoding(dtype),
bit_depth=bit_depth,
duration=duration,
comment_file=comment_file,
)
return path
def _gen_comment_file(self, comments):
comment_path = self.get_temp_path("comment.txt")
with open(comment_path, "w") as file_:
file_.writelines(comments)
return comment_path
class Unseekable:
def __init__(self, fileobj):
self.fileobj = fileobj
def read(self, n):
return self.fileobj.read(n)
@skipIfNoSox
@skipIfNoExec("sox")
class TestFileObject(FileObjTestBase, PytorchTestCase):
def _query_fileobj(self, ext, dtype, sample_rate, num_channels, num_frames, *, comments=None):
path = self._gen_file(ext, dtype, sample_rate, num_channels, num_frames, comments=comments)
format_ = ext if ext in ["mp3"] else None
with open(path, "rb") as fileobj:
return sox_io_backend.info(fileobj, format_)
def _query_bytesio(self, ext, dtype, sample_rate, num_channels, num_frames):
path = self._gen_file(ext, dtype, sample_rate, num_channels, num_frames)
format_ = ext if ext in ["mp3"] else None
with open(path, "rb") as file_:
fileobj = io.BytesIO(file_.read())
return sox_io_backend.info(fileobj, format_)
def _query_tarfile(self, ext, dtype, sample_rate, num_channels, num_frames):
audio_path = self._gen_file(ext, dtype, sample_rate, num_channels, num_frames)
audio_file = os.path.basename(audio_path)
archive_path = self.get_temp_path("archive.tar.gz")
with tarfile.TarFile(archive_path, "w") as tarobj:
tarobj.add(audio_path, arcname=audio_file)
format_ = ext if ext in ["mp3"] else None
with tarfile.TarFile(archive_path, "r") as tarobj:
fileobj = tarobj.extractfile(audio_file)
return sox_io_backend.info(fileobj, format_)
@contextmanager
def _set_buffer_size(self, buffer_size):
try:
original_buffer_size = get_buffer_size()
set_buffer_size(buffer_size)
yield
finally:
set_buffer_size(original_buffer_size)
@parameterized.expand(
[
("wav", "float32"),
("wav", "int32"),
("wav", "int16"),
("wav", "uint8"),
("mp3", "float32"),
("flac", "float32"),
("vorbis", "float32"),
("amb", "int16"),
]
)
def test_fileobj(self, ext, dtype):
"""Querying audio via file object works"""
sample_rate = 16000
num_frames = 3 * sample_rate
num_channels = 2
sinfo = self._query_fileobj(ext, dtype, sample_rate, num_channels, num_frames)
bits_per_sample = get_bits_per_sample(ext, dtype)
num_frames = {"vorbis": 0, "mp3": 49536}.get(ext, num_frames)
assert sinfo.sample_rate == sample_rate
assert sinfo.num_channels == num_channels
assert sinfo.num_frames == num_frames
assert sinfo.bits_per_sample == bits_per_sample
assert sinfo.encoding == get_encoding(ext, dtype)
@parameterized.expand(
[
("vorbis", "float32"),
]
)
def test_fileobj_large_header(self, ext, dtype):
"""
For audio file with header size exceeding default buffer size:
- Querying audio via file object without enlarging buffer size fails.
- Querying audio via file object after enlarging buffer size succeeds.
"""
sample_rate = 16000
num_frames = 3 * sample_rate
num_channels = 2
comments = "metadata=" + " ".join(["value" for _ in range(1000)])
with self.assertRaises(RuntimeError):
sinfo = self._query_fileobj(ext, dtype, sample_rate, num_channels, num_frames, comments=comments)
with self._set_buffer_size(16384):
sinfo = self._query_fileobj(ext, dtype, sample_rate, num_channels, num_frames, comments=comments)
bits_per_sample = get_bits_per_sample(ext, dtype)
num_frames = 0 if ext in ["vorbis"] else num_frames
assert sinfo.sample_rate == sample_rate
assert sinfo.num_channels == num_channels
assert sinfo.num_frames == num_frames
assert sinfo.bits_per_sample == bits_per_sample
assert sinfo.encoding == get_encoding(ext, dtype)
@parameterized.expand(
[
("wav", "float32"),
("wav", "int32"),
("wav", "int16"),
("wav", "uint8"),
("mp3", "float32"),
("flac", "float32"),
("vorbis", "float32"),
("amb", "int16"),
]
)
def test_bytesio(self, ext, dtype):
"""Querying audio via ByteIO object works for small data"""
sample_rate = 16000
num_frames = 3 * sample_rate
num_channels = 2
sinfo = self._query_bytesio(ext, dtype, sample_rate, num_channels, num_frames)
bits_per_sample = get_bits_per_sample(ext, dtype)
num_frames = {"vorbis": 0, "mp3": 49536}.get(ext, num_frames)
assert sinfo.sample_rate == sample_rate
assert sinfo.num_channels == num_channels
assert sinfo.num_frames == num_frames
assert sinfo.bits_per_sample == bits_per_sample
assert sinfo.encoding == get_encoding(ext, dtype)
@parameterized.expand(
[
("wav", "float32"),
("wav", "int32"),
("wav", "int16"),
("wav", "uint8"),
("mp3", "float32"),
("flac", "float32"),
("vorbis", "float32"),
("amb", "int16"),
]
)
def test_bytesio_tiny(self, ext, dtype):
"""Querying audio via ByteIO object works for small data"""
sample_rate = 8000
num_frames = 4
num_channels = 2
sinfo = self._query_bytesio(ext, dtype, sample_rate, num_channels, num_frames)
bits_per_sample = get_bits_per_sample(ext, dtype)
num_frames = {"vorbis": 0, "mp3": 1728}.get(ext, num_frames)
assert sinfo.sample_rate == sample_rate
assert sinfo.num_channels == num_channels
assert sinfo.num_frames == num_frames
assert sinfo.bits_per_sample == bits_per_sample
assert sinfo.encoding == get_encoding(ext, dtype)
@parameterized.expand(
[
("wav", "float32"),
("wav", "int32"),
("wav", "int16"),
("wav", "uint8"),
("mp3", "float32"),
("flac", "float32"),
("vorbis", "float32"),
("amb", "int16"),
]
)
def test_tarfile(self, ext, dtype):
"""Querying compressed audio via file-like object works"""
sample_rate = 16000
num_frames = 3.0 * sample_rate
num_channels = 2
sinfo = self._query_tarfile(ext, dtype, sample_rate, num_channels, num_frames)
bits_per_sample = get_bits_per_sample(ext, dtype)
num_frames = {"vorbis": 0, "mp3": 49536}.get(ext, num_frames)
assert sinfo.sample_rate == sample_rate
assert sinfo.num_channels == num_channels
assert sinfo.num_frames == num_frames
assert sinfo.bits_per_sample == bits_per_sample
assert sinfo.encoding == get_encoding(ext, dtype)
@skipIfNoSox
@skipIfNoExec("sox")
@skipIfNoModule("requests")
class TestFileObjectHttp(HttpServerMixin, FileObjTestBase, PytorchTestCase):
def _query_http(self, ext, dtype, sample_rate, num_channels, num_frames):
audio_path = self._gen_file(ext, dtype, sample_rate, num_channels, num_frames)
audio_file = os.path.basename(audio_path)
url = self.get_url(audio_file)
format_ = ext if ext in ["mp3"] else None
with requests.get(url, stream=True) as resp:
return sox_io_backend.info(Unseekable(resp.raw), format=format_)
@parameterized.expand(
[
("wav", "float32"),
("wav", "int32"),
("wav", "int16"),
("wav", "uint8"),
("mp3", "float32"),
("flac", "float32"),
("vorbis", "float32"),
("amb", "int16"),
]
)
def test_requests(self, ext, dtype):
"""Querying compressed audio via requests works"""
sample_rate = 16000
num_frames = 3.0 * sample_rate
num_channels = 2
sinfo = self._query_http(ext, dtype, sample_rate, num_channels, num_frames)
bits_per_sample = get_bits_per_sample(ext, dtype)
num_frames = {"vorbis": 0, "mp3": 49536}.get(ext, num_frames)
assert sinfo.sample_rate == sample_rate
assert sinfo.num_channels == num_channels
assert sinfo.num_frames == num_frames
assert sinfo.bits_per_sample == bits_per_sample
assert sinfo.encoding == get_encoding(ext, dtype)
@skipIfNoSox
class TestInfoNoSuchFile(PytorchTestCase):
......
......@@ -322,13 +322,6 @@ class TestLoadParams(TempDirMixin, PytorchTestCase):
self._test(torch.ops.torchaudio.sox_io_load_audio_file, frame_offset, num_frames, channels_first, normalize)
# test file-like obj
def func(path, *args):
with open(path, "rb") as fileobj:
return torchaudio.lib._torchaudio_sox.load_audio_fileobj(fileobj, *args)
self._test(func, frame_offset, num_frames, channels_first, normalize)
@nested_params(
[0, 1, 10, 100, 1000],
[-1, 1, 10, 100, 1000],
......@@ -365,263 +358,6 @@ class TestLoadWithoutExtension(PytorchTestCase):
_, sr = sox_io_backend.load(path)
assert sr == 16000
with open(path, "rb") as fileobj:
_, sr = sox_io_backend.load(fileobj)
assert sr == 16000
class CloggedFileObj:
def __init__(self, fileobj):
self.fileobj = fileobj
def read(self, _):
return self.fileobj.read(2)
def seek(self, offset, whence):
return self.fileobj.seek(offset, whence)
@skipIfNoSox
@skipIfNoExec("sox")
class TestFileObject(TempDirMixin, PytorchTestCase):
"""
In this test suite, the result of file-like object input is compared against file path input,
because `load` function is rigrously tested for file path inputs to match libsox's result,
"""
@parameterized.expand(
[
("wav", {"bit_depth": 16}),
("wav", {"bit_depth": 24}),
("wav", {"bit_depth": 32}),
("mp3", {"compression": 128}),
("mp3", {"compression": 320}),
("flac", {"compression": 0}),
("flac", {"compression": 5}),
("flac", {"compression": 8}),
("vorbis", {"compression": -1}),
("vorbis", {"compression": 10}),
("amb", {}),
]
)
def test_fileobj(self, ext, kwargs):
"""Loading audio via file object returns the same result as via file path."""
sample_rate = 16000
format_ = ext if ext in ["mp3"] else None
path = self.get_temp_path(f"test.{ext}")
sox_utils.gen_audio_file(path, sample_rate, num_channels=2, **kwargs)
expected, _ = sox_io_backend.load(path)
with open(path, "rb") as fileobj:
found, sr = sox_io_backend.load(fileobj, format=format_)
assert sr == sample_rate
self.assertEqual(expected, found)
@parameterized.expand(
[
("wav", {"bit_depth": 16}),
("wav", {"bit_depth": 24}),
("wav", {"bit_depth": 32}),
("mp3", {"compression": 128}),
("mp3", {"compression": 320}),
("flac", {"compression": 0}),
("flac", {"compression": 5}),
("flac", {"compression": 8}),
("vorbis", {"compression": -1}),
("vorbis", {"compression": 10}),
("amb", {}),
]
)
def test_bytesio(self, ext, kwargs):
"""Loading audio via BytesIO object returns the same result as via file path."""
sample_rate = 16000
format_ = ext if ext in ["mp3"] else None
path = self.get_temp_path(f"test.{ext}")
sox_utils.gen_audio_file(path, sample_rate, num_channels=2, **kwargs)
expected, _ = sox_io_backend.load(path)
with open(path, "rb") as file_:
fileobj = io.BytesIO(file_.read())
found, sr = sox_io_backend.load(fileobj, format=format_)
assert sr == sample_rate
self.assertEqual(expected, found)
@parameterized.expand(
[
("wav", {"bit_depth": 16}),
("wav", {"bit_depth": 24}),
("wav", {"bit_depth": 32}),
("mp3", {"compression": 128}),
("mp3", {"compression": 320}),
("flac", {"compression": 0}),
("flac", {"compression": 5}),
("flac", {"compression": 8}),
("vorbis", {"compression": -1}),
("vorbis", {"compression": 10}),
("amb", {}),
]
)
def test_bytesio_clogged(self, ext, kwargs):
"""Loading audio via clogged file object returns the same result as via file path.
This test case validates the case where fileobject returns shorter bytes than requeted.
"""
sample_rate = 16000
format_ = ext if ext in ["mp3"] else None
path = self.get_temp_path(f"test.{ext}")
sox_utils.gen_audio_file(path, sample_rate, num_channels=2, **kwargs)
expected, _ = sox_io_backend.load(path)
with open(path, "rb") as file_:
fileobj = CloggedFileObj(io.BytesIO(file_.read()))
found, sr = sox_io_backend.load(fileobj, format=format_)
assert sr == sample_rate
self.assertEqual(expected, found)
@parameterized.expand(
[
("wav", {"bit_depth": 16}),
("wav", {"bit_depth": 24}),
("wav", {"bit_depth": 32}),
("mp3", {"compression": 128}),
("mp3", {"compression": 320}),
("flac", {"compression": 0}),
("flac", {"compression": 5}),
("flac", {"compression": 8}),
("vorbis", {"compression": -1}),
("vorbis", {"compression": 10}),
("amb", {}),
]
)
def test_bytesio_tiny(self, ext, kwargs):
"""Loading very small audio via file object returns the same result as via file path."""
sample_rate = 16000
format_ = ext if ext in ["mp3"] else None
path = self.get_temp_path(f"test.{ext}")
sox_utils.gen_audio_file(path, sample_rate, num_channels=2, duration=1 / 1600, **kwargs)
expected, _ = sox_io_backend.load(path)
with open(path, "rb") as file_:
fileobj = io.BytesIO(file_.read())
found, sr = sox_io_backend.load(fileobj, format=format_)
assert sr == sample_rate
self.assertEqual(expected, found)
@parameterized.expand(
[
("wav", {"bit_depth": 16}),
("wav", {"bit_depth": 24}),
("wav", {"bit_depth": 32}),
("mp3", {"compression": 128}),
("mp3", {"compression": 320}),
("flac", {"compression": 0}),
("flac", {"compression": 5}),
("flac", {"compression": 8}),
("vorbis", {"compression": -1}),
("vorbis", {"compression": 10}),
("amb", {}),
]
)
def test_tarfile(self, ext, kwargs):
"""Loading compressed audio via file-like object returns the same result as via file path."""
sample_rate = 16000
format_ = ext if ext in ["mp3"] else None
audio_file = f"test.{ext}"
audio_path = self.get_temp_path(audio_file)
archive_path = self.get_temp_path("archive.tar.gz")
sox_utils.gen_audio_file(audio_path, sample_rate, num_channels=2, **kwargs)
expected, _ = sox_io_backend.load(audio_path)
with tarfile.TarFile(archive_path, "w") as tarobj:
tarobj.add(audio_path, arcname=audio_file)
with tarfile.TarFile(archive_path, "r") as tarobj:
fileobj = tarobj.extractfile(audio_file)
found, sr = sox_io_backend.load(fileobj, format=format_)
assert sr == sample_rate
self.assertEqual(expected, found)
class Unseekable:
def __init__(self, fileobj):
self.fileobj = fileobj
def read(self, n):
return self.fileobj.read(n)
@skipIfNoSox
@skipIfNoExec("sox")
@skipIfNoModule("requests")
class TestFileObjectHttp(HttpServerMixin, PytorchTestCase):
@parameterized.expand(
[
("wav", {"bit_depth": 16}),
("wav", {"bit_depth": 24}),
("wav", {"bit_depth": 32}),
("mp3", {"compression": 128}),
("mp3", {"compression": 320}),
("flac", {"compression": 0}),
("flac", {"compression": 5}),
("flac", {"compression": 8}),
("vorbis", {"compression": -1}),
("vorbis", {"compression": 10}),
("amb", {}),
]
)
def test_requests(self, ext, kwargs):
sample_rate = 16000
format_ = ext if ext in ["mp3"] else None
audio_file = f"test.{ext}"
audio_path = self.get_temp_path(audio_file)
sox_utils.gen_audio_file(audio_path, sample_rate, num_channels=2, **kwargs)
expected, _ = sox_io_backend.load(audio_path)
url = self.get_url(audio_file)
with requests.get(url, stream=True) as resp:
found, sr = sox_io_backend.load(Unseekable(resp.raw), format=format_)
assert sr == sample_rate
if ext != "mp3":
self.assertEqual(expected, found)
@parameterized.expand(
list(
itertools.product(
[0, 1, 10, 100, 1000],
[-1, 1, 10, 100, 1000],
)
),
name_func=name_func,
)
def test_frame(self, frame_offset, num_frames):
"""num_frames and frame_offset correctly specify the region of data"""
sample_rate = 8000
audio_file = "test.wav"
audio_path = self.get_temp_path(audio_file)
original = get_wav_data("float32", num_channels=2)
save_wav(audio_path, original, sample_rate)
frame_end = None if num_frames == -1 else frame_offset + num_frames
expected = original[:, frame_offset:frame_end]
url = self.get_url(audio_file)
with requests.get(url, stream=True) as resp:
found, sr = sox_io_backend.load(resp.raw, frame_offset, num_frames)
assert sr == sample_rate
self.assertEqual(expected, found)
@skipIfNoSox
class TestLoadNoSuchFile(PytorchTestCase):
......
......@@ -43,7 +43,6 @@ class SaveTestBase(TempDirMixin, TorchaudioTestCase):
num_channels: int = 2,
num_frames: float = 3 * 8000,
src_dtype: str = "int32",
test_mode: str = "path",
):
"""`save` function produces file that is comparable with `sox` command
......@@ -97,37 +96,9 @@ class SaveTestBase(TempDirMixin, TorchaudioTestCase):
# 2.1. Convert the original wav to target format with torchaudio
data = load_wav(src_path, normalize=False)[0]
if test_mode == "path":
sox_io_backend.save(
tgt_path, data, sample_rate, compression=compression, encoding=encoding, bits_per_sample=bits_per_sample
)
elif test_mode == "fileobj":
with open(tgt_path, "bw") as file_:
sox_io_backend.save(
file_,
data,
sample_rate,
format=format,
compression=compression,
encoding=encoding,
bits_per_sample=bits_per_sample,
)
elif test_mode == "bytesio":
file_ = io.BytesIO()
sox_io_backend.save(
file_,
data,
sample_rate,
format=format,
compression=compression,
encoding=encoding,
bits_per_sample=bits_per_sample,
)
file_.seek(0)
with open(tgt_path, "bw") as f:
f.write(file_.read())
else:
raise ValueError(f"Unexpected test mode: {test_mode}")
sox_io_backend.save(
tgt_path, data, sample_rate, compression=compression, encoding=encoding, bits_per_sample=bits_per_sample
)
# 2.2. Convert the target format to wav with sox
sox_utils.convert_audio_file(tgt_path, tst_path, encoding=cmp_encoding, bit_depth=cmp_bit_depth)
# 2.3. Load with SciPy
......@@ -150,7 +121,6 @@ class SaveTestBase(TempDirMixin, TorchaudioTestCase):
@skipIfNoSox
class SaveTest(SaveTestBase):
@nested_params(
["path", "fileobj", "bytesio"],
[
("PCM_U", 8),
("PCM_S", 16),
......@@ -161,12 +131,11 @@ class SaveTest(SaveTestBase):
("ALAW", 8),
],
)
def test_save_wav(self, test_mode, enc_params):
def test_save_wav(self, enc_params):
encoding, bits_per_sample = enc_params
self.assert_save_consistency("wav", encoding=encoding, bits_per_sample=bits_per_sample, test_mode=test_mode)
self.assert_save_consistency("wav", encoding=encoding, bits_per_sample=bits_per_sample)
@nested_params(
["path", "fileobj", "bytesio"],
[
("float32",),
("int32",),
......@@ -174,12 +143,11 @@ class SaveTest(SaveTestBase):
("uint8",),
],
)
def test_save_wav_dtype(self, test_mode, params):
def test_save_wav_dtype(self, params):
(dtype,) = params
self.assert_save_consistency("wav", src_dtype=dtype, test_mode=test_mode)
self.assert_save_consistency("wav", src_dtype=dtype)
@nested_params(
["path", "fileobj", "bytesio"],
[8, 16, 24],
[
None,
......@@ -194,19 +162,13 @@ class SaveTest(SaveTestBase):
8,
],
)
def test_save_flac(self, test_mode, bits_per_sample, compression_level):
self.assert_save_consistency(
"flac", compression=compression_level, bits_per_sample=bits_per_sample, test_mode=test_mode
)
def test_save_flac(self, bits_per_sample, compression_level):
self.assert_save_consistency("flac", compression=compression_level, bits_per_sample=bits_per_sample)
@nested_params(
["path", "fileobj", "bytesio"],
)
def test_save_htk(self, test_mode):
self.assert_save_consistency("htk", test_mode=test_mode, num_channels=1)
def test_save_htk(self):
self.assert_save_consistency("htk", num_channels=1)
@nested_params(
["path", "fileobj", "bytesio"],
[
None,
-1,
......@@ -219,11 +181,10 @@ class SaveTest(SaveTestBase):
10,
],
)
def test_save_vorbis(self, test_mode, quality_level):
self.assert_save_consistency("vorbis", compression=quality_level, test_mode=test_mode)
def test_save_vorbis(self, quality_level):
self.assert_save_consistency("vorbis", compression=quality_level)
@nested_params(
["path", "fileobj", "bytesio"],
[
(
"PCM_S",
......@@ -248,12 +209,11 @@ class SaveTest(SaveTestBase):
("ALAW", 32),
],
)
def test_save_sphere(self, test_mode, enc_params):
def test_save_sphere(self, enc_params):
encoding, bits_per_sample = enc_params
self.assert_save_consistency("sph", encoding=encoding, bits_per_sample=bits_per_sample, test_mode=test_mode)
self.assert_save_consistency("sph", encoding=encoding, bits_per_sample=bits_per_sample)
@nested_params(
["path", "fileobj", "bytesio"],
[
(
"PCM_U",
......@@ -289,12 +249,11 @@ class SaveTest(SaveTestBase):
),
],
)
def test_save_amb(self, test_mode, enc_params):
def test_save_amb(self, enc_params):
encoding, bits_per_sample = enc_params
self.assert_save_consistency("amb", encoding=encoding, bits_per_sample=bits_per_sample, test_mode=test_mode)
self.assert_save_consistency("amb", encoding=encoding, bits_per_sample=bits_per_sample)
@nested_params(
["path", "fileobj", "bytesio"],
[
None,
0,
......@@ -307,18 +266,15 @@ class SaveTest(SaveTestBase):
7,
],
)
def test_save_amr_nb(self, test_mode, bit_rate):
self.assert_save_consistency("amr-nb", compression=bit_rate, num_channels=1, test_mode=test_mode)
def test_save_amr_nb(self, bit_rate):
self.assert_save_consistency("amr-nb", compression=bit_rate, num_channels=1)
@nested_params(
["path", "fileobj", "bytesio"],
)
def test_save_gsm(self, test_mode):
self.assert_save_consistency("gsm", num_channels=1, test_mode=test_mode)
def test_save_gsm(self):
self.assert_save_consistency("gsm", num_channels=1)
with self.assertRaises(RuntimeError, msg="gsm format only supports single channel audio."):
self.assert_save_consistency("gsm", num_channels=2, test_mode=test_mode)
self.assert_save_consistency("gsm", num_channels=2)
with self.assertRaises(RuntimeError, msg="gsm format only supports a sampling rate of 8kHz."):
self.assert_save_consistency("gsm", sample_rate=16000, test_mode=test_mode)
self.assert_save_consistency("gsm", sample_rate=16000)
@parameterized.expand(
[
......
......@@ -89,88 +89,3 @@ class SmokeTest(TempDirMixin, TorchaudioTestCase):
def test_flac(self, sample_rate, num_channels, compression_level):
"""Run smoke test on flac format"""
self.run_smoke_test("flac", sample_rate, num_channels, compression=compression_level)
@skipIfNoSox
class SmokeTestFileObj(TorchaudioTestCase):
"""Run smoke test on various audio format
The purpose of this test suite is to verify that sox_io_backend functionalities do not exhibit
abnormal behaviors.
This test suite should be able to run without any additional tools (such as sox command),
however without such tools, the correctness of each function cannot be verified.
"""
def run_smoke_test(self, ext, sample_rate, num_channels, *, compression=None, dtype="float32"):
duration = 1
num_frames = sample_rate * duration
original = get_wav_data(dtype, num_channels, normalize=False, num_frames=num_frames)
fileobj = io.BytesIO()
# 1. run save
sox_io_backend.save(fileobj, original, sample_rate, compression=compression, format=ext)
# 2. run info
fileobj.seek(0)
info = sox_io_backend.info(fileobj, format=ext)
assert info.sample_rate == sample_rate
assert info.num_channels == num_channels
# 3. run load
fileobj.seek(0)
loaded, sr = sox_io_backend.load(fileobj, normalize=False, format=ext)
assert sr == sample_rate
assert loaded.shape[0] == num_channels
@parameterized.expand(
list(
itertools.product(
["float32", "int32", "int16", "uint8"],
[8000, 16000],
[1, 2],
)
),
name_func=name_func,
)
def test_wav(self, dtype, sample_rate, num_channels):
"""Run smoke test on wav format"""
self.run_smoke_test("wav", sample_rate, num_channels, dtype=dtype)
@parameterized.expand(
list(
itertools.product(
[8000, 16000],
[1, 2],
[-4.2, -0.2, 0, 0.2, 96, 128, 160, 192, 224, 256, 320],
)
)
)
def test_mp3(self, sample_rate, num_channels, bit_rate):
"""Run smoke test on mp3 format"""
self.run_smoke_test("mp3", sample_rate, num_channels, compression=bit_rate)
@parameterized.expand(
list(
itertools.product(
[8000, 16000],
[1, 2],
[-1, 0, 1, 2, 3, 3.6, 5, 10],
)
)
)
def test_vorbis(self, sample_rate, num_channels, quality_level):
"""Run smoke test on vorbis format"""
self.run_smoke_test("vorbis", sample_rate, num_channels, compression=quality_level)
@parameterized.expand(
list(
itertools.product(
[8000, 16000],
[1, 2],
list(range(9)),
)
),
name_func=name_func,
)
def test_flac(self, sample_rate, num_channels, compression_level):
"""Run smoke test on flac format"""
self.run_smoke_test("flac", sample_rate, num_channels, compression=compression_level)
......@@ -54,24 +54,3 @@ class SmokeTest(TempDirMixin, TorchaudioTestCase):
_found, _sr = sox_effects.apply_effects_file(
input_path, effects, normalize=False, channels_first=channels_first
)
@parameterized.expand(
load_params("sox_effect_test_args.jsonl"),
name_func=lambda f, i, p: f'{f.__name__}_{i}_{p.args[0]["effects"][0][0]}',
)
def test_apply_effects_fileobj(self, args):
"""`apply_effects_file` should return identical data as sox command"""
dtype = "int32"
channels_first = True
effects = args["effects"]
num_channels = args.get("num_channels", 2)
input_sr = args.get("input_sample_rate", 8000)
input_path = self.get_temp_path("input.wav")
data = get_wav_data(dtype, num_channels, channels_first=channels_first)
save_wav(input_path, data, input_sr, channels_first=channels_first)
with open(input_path, "rb") as fileobj:
_found, _sr = sox_effects.apply_effects_file(
fileobj, effects, normalize=False, channels_first=channels_first
)
import io
import itertools
import tarfile
from pathlib import Path
from parameterized import parameterized
from torchaudio import sox_effects
from torchaudio._internal import module_utils as _mod_utils
from torchaudio_unittest.common_utils import (
get_sinusoid,
get_wav_data,
HttpServerMixin,
load_wav,
PytorchTestCase,
save_wav,
skipIfNoExec,
skipIfNoModule,
skipIfNoSox,
sox_utils,
TempDirMixin,
......@@ -23,10 +17,6 @@ from torchaudio_unittest.common_utils import (
from .common import load_params, name_func
if _mod_utils.is_module_available("requests"):
import requests
@skipIfNoSox
class TestSoxEffects(PytorchTestCase):
def test_init(self):
......@@ -241,136 +231,3 @@ class TestFileFormats(TempDirMixin, PytorchTestCase):
assert sr == expected_sr
self.assertEqual(found, expected)
@skipIfNoExec("sox")
@skipIfNoSox
class TestFileObject(TempDirMixin, PytorchTestCase):
@parameterized.expand(
[
("wav", None),
("flac", 0),
("flac", 5),
("flac", 8),
("vorbis", -1),
("vorbis", 10),
("amb", None),
]
)
def test_fileobj(self, ext, compression):
"""Applying effects via file object works"""
sample_rate = 16000
channels_first = True
effects = [["band", "300", "10"]]
input_path = self.get_temp_path(f"input.{ext}")
reference_path = self.get_temp_path("reference.wav")
sox_utils.gen_audio_file(input_path, sample_rate, num_channels=2, compression=compression)
sox_utils.run_sox_effect(input_path, reference_path, effects, output_bitdepth=32)
expected, expected_sr = load_wav(reference_path)
with open(input_path, "rb") as fileobj:
found, sr = sox_effects.apply_effects_file(fileobj, effects, channels_first=channels_first)
save_wav(self.get_temp_path("result.wav"), found, sr, channels_first=channels_first)
assert sr == expected_sr
self.assertEqual(found, expected)
@parameterized.expand(
[
("wav", None),
("flac", 0),
("flac", 5),
("flac", 8),
("vorbis", -1),
("vorbis", 10),
("amb", None),
]
)
def test_bytesio(self, ext, compression):
"""Applying effects via BytesIO object works"""
sample_rate = 16000
channels_first = True
effects = [["band", "300", "10"]]
input_path = self.get_temp_path(f"input.{ext}")
reference_path = self.get_temp_path("reference.wav")
sox_utils.gen_audio_file(input_path, sample_rate, num_channels=2, compression=compression)
sox_utils.run_sox_effect(input_path, reference_path, effects, output_bitdepth=32)
expected, expected_sr = load_wav(reference_path)
with open(input_path, "rb") as file_:
fileobj = io.BytesIO(file_.read())
found, sr = sox_effects.apply_effects_file(fileobj, effects, channels_first=channels_first)
save_wav(self.get_temp_path("result.wav"), found, sr, channels_first=channels_first)
assert sr == expected_sr
self.assertEqual(found, expected)
@parameterized.expand(
[
("wav", None),
("flac", 0),
("flac", 5),
("flac", 8),
("vorbis", -1),
("vorbis", 10),
("amb", None),
]
)
def test_tarfile(self, ext, compression):
"""Applying effects to compressed audio via file-like file works"""
sample_rate = 16000
channels_first = True
effects = [["band", "300", "10"]]
audio_file = f"input.{ext}"
input_path = self.get_temp_path(audio_file)
reference_path = self.get_temp_path("reference.wav")
archive_path = self.get_temp_path("archive.tar.gz")
sox_utils.gen_audio_file(input_path, sample_rate, num_channels=2, compression=compression)
sox_utils.run_sox_effect(input_path, reference_path, effects, output_bitdepth=32)
expected, expected_sr = load_wav(reference_path)
with tarfile.TarFile(archive_path, "w") as tarobj:
tarobj.add(input_path, arcname=audio_file)
with tarfile.TarFile(archive_path, "r") as tarobj:
fileobj = tarobj.extractfile(audio_file)
found, sr = sox_effects.apply_effects_file(fileobj, effects, channels_first=channels_first)
save_wav(self.get_temp_path("result.wav"), found, sr, channels_first=channels_first)
assert sr == expected_sr
self.assertEqual(found, expected)
@skipIfNoSox
@skipIfNoExec("sox")
@skipIfNoModule("requests")
class TestFileObjectHttp(HttpServerMixin, PytorchTestCase):
@parameterized.expand(
[
("wav", None),
("flac", 0),
("flac", 5),
("flac", 8),
("vorbis", -1),
("vorbis", 10),
("amb", None),
]
)
def test_requests(self, ext, compression):
sample_rate = 16000
channels_first = True
effects = [["band", "300", "10"]]
audio_file = f"input.{ext}"
input_path = self.get_temp_path(audio_file)
reference_path = self.get_temp_path("reference.wav")
sox_utils.gen_audio_file(input_path, sample_rate, num_channels=2, compression=compression)
sox_utils.run_sox_effect(input_path, reference_path, effects, output_bitdepth=32)
expected, expected_sr = load_wav(reference_path)
url = self.get_url(audio_file)
with requests.get(url, stream=True) as resp:
found, sr = sox_effects.apply_effects_file(resp.raw, effects, channels_first=channels_first)
save_wav(self.get_temp_path("result.wav"), found, sr, channels_first=channels_first)
assert sr == expected_sr
self.assertEqual(found, expected)
See https://github.com/pytorch/audio/pull/1297
diff -ru sox/src/formats.c sox/src/formats.c
--- sox/src/formats.c 2014-10-26 19:55:50.000000000 -0700
+++ sox/src/formats.c 2021-02-22 16:01:02.833144070 -0800
@@ -333,6 +333,10 @@
assert(ft);
if (!ft->fp)
return sox_false;
- fstat(fileno((FILE*)ft->fp), &st);
+ int fd = fileno((FILE*)ft->fp);
+ if (fd < 0)
+ return sox_false;
+ if (fstat(fd, &st) < 0)
+ return sox_false;
return ((st.st_mode & S_IFMT) == S_IFREG);
}
......@@ -193,7 +193,7 @@ ExternalProject_Add(sox
DOWNLOAD_DIR ${ARCHIVE_DIR}
URL https://downloads.sourceforge.net/project/sox/sox/14.4.2/sox-14.4.2.tar.bz2
URL_HASH SHA256=81a6956d4330e75b5827316e44ae381e6f1e8928003c6aa45896da9041ea149c
PATCH_COMMAND patch -p1 < ${patch_dir}/sox.patch && cp ${patch_dir}/config.guess ${patch_dir}/config.sub ${CMAKE_CURRENT_BINARY_DIR}/src/sox/
PATCH_COMMAND cp ${patch_dir}/config.guess ${patch_dir}/config.sub ${CMAKE_CURRENT_BINARY_DIR}/src/sox/
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${envs} ${CMAKE_CURRENT_BINARY_DIR}/src/sox/configure ${COMMON_ARGS} ${SOX_OPTIONS}
BUILD_BYPRODUCTS ${SOX_LIBRARIES}
DOWNLOAD_NO_PROGRESS ON
......
......@@ -67,7 +67,7 @@ def _init_sox():
_load_lib("libtorchaudio_sox")
import torchaudio.lib._torchaudio_sox # noqa
torch.ops.torchaudio.sox_utils_set_verbosity(0)
torchaudio.lib._torchaudio_sox.set_verbosity(0)
import atexit
......
import os
import warnings
from typing import Optional, Tuple
import torch
import torchaudio
from torchaudio.utils.sox_utils import get_buffer_size
from .common import AudioMetaData
......@@ -14,10 +12,6 @@ def _fail_info(filepath: str, format: Optional[str]) -> AudioMetaData:
raise RuntimeError("Failed to fetch metadata from {}".format(filepath))
def _fail_info_fileobj(fileobj, format: Optional[str], buffer_size: int) -> AudioMetaData:
raise RuntimeError("Failed to fetch metadata from {}".format(fileobj))
# Note: need to comply TorchScript syntax -- need annotation and no f-string
def _fail_load(
filepath: str,
......@@ -30,30 +24,14 @@ def _fail_load(
raise RuntimeError("Failed to load audio from {}".format(filepath))
def _fail_load_fileobj(fileobj, *args, **kwargs):
raise RuntimeError(f"Failed to load audio from {fileobj}")
if torchaudio._extension._FFMPEG_INITIALIZED:
import torchaudio.io._compat as _compat
_fallback_info = _compat.info_audio
_fallback_info_fileobj = _compat.info_audio_fileobj
_fallback_load = _compat.load_audio
_fallback_load_fileobj = _compat.load_audio_fileobj
else:
_fallback_info = _fail_info
_fallback_info_fileobj = _fail_info_fileobj
_fallback_load = _fail_load
_fallback_load_fileobj = _fail_load_fileobj
_deprecation_message = (
"File-like object support in sox_io backend is deprecated, "
"and will be removed in v2.1. "
"See https://github.com/pytorch/audio/issues/2950 for the detail."
"Please migrate to the new dispatcher, or use soundfile backend."
)
@torchaudio._extension.fail_if_no_sox
......@@ -64,24 +42,8 @@ def info(
"""Get signal information of an audio file.
Args:
filepath (path-like object or file-like object):
Source of audio data. When the function is not compiled by TorchScript,
(e.g. ``torch.jit.script``), the following types are accepted;
* ``path-like``: file path
* ``file-like``: Object with ``read(size: int) -> bytes`` method,
which returns byte string of at most ``size`` length.
When the function is compiled by TorchScript, only ``str`` type is allowed.
Note:
* When the input type is file-like object, this function cannot
get the correct length (``num_samples``) for certain formats,
such as ``vorbis``.
In this case, the value of ``num_samples`` is ``0``.
* This argument is intentionally annotated as ``str`` only due to
TorchScript compiler compatibility.
filepath (str):
Source of audio data.
format (str or None, optional):
Override the format detection with the given format.
......@@ -93,21 +55,7 @@ def info(
"""
if not torch.jit.is_scripting():
if hasattr(filepath, "read"):
# Special case for Backward compatibility
# v0.11 -> v0.12, mp3 handling is moved to FFmpeg.
# file-like objects are not necessarily fallback-able
# when they are not seekable.
# The previous libsox-based implementation required `format="mp3"`
# because internally libsox does not auto-detect the format.
# For the special BC for mp3, we handle mp3 differently.
buffer_size = get_buffer_size()
if format == "mp3":
return _fallback_info_fileobj(filepath, format, buffer_size)
warnings.warn(_deprecation_message)
sinfo = torchaudio.lib._torchaudio_sox.get_info_fileobj(filepath, format)
if sinfo is not None:
return AudioMetaData(*sinfo)
return _fallback_info_fileobj(filepath, format, buffer_size)
raise RuntimeError("sox_io backend does not support file-like object.")
filepath = os.fspath(filepath)
sinfo = torch.ops.torchaudio.sox_io_get_info(filepath, format)
if sinfo is not None:
......@@ -171,18 +119,7 @@ def load(
For these formats, this function always returns ``float32`` Tensor with values.
Args:
filepath (path-like object or file-like object):
Source of audio data. When the function is not compiled by TorchScript,
(e.g. ``torch.jit.script``), the following types are accepted;
* ``path-like``: file path
* ``file-like``: Object with ``read(size: int) -> bytes`` method,
which returns byte string of at most ``size`` length.
When the function is compiled by TorchScript, only ``str`` type is allowed.
Note: This argument is intentionally annotated as ``str`` only due to
TorchScript compiler compatibility.
filepath (path-like object): Source of audio data.
frame_offset (int):
Number of frames to skip before start reading data.
num_frames (int, optional):
......@@ -214,39 +151,7 @@ def load(
"""
if not torch.jit.is_scripting():
if hasattr(filepath, "read"):
# Special case for Backward compatibility
# v0.11 -> v0.12, mp3 handling is moved to FFmpeg.
# file-like objects are not necessarily fallback-able
# when they are not seekable.
# The previous libsox-based implementation required `format="mp3"`
# because internally libsox does not auto-detect the format.
# For the special BC for mp3, we handle mp3 differently.
buffer_size = get_buffer_size()
if format == "mp3":
return _fallback_load_fileobj(
filepath,
frame_offset,
num_frames,
normalize,
channels_first,
format,
buffer_size,
)
warnings.warn(_deprecation_message)
ret = torchaudio.lib._torchaudio_sox.load_audio_fileobj(
filepath, frame_offset, num_frames, normalize, channels_first, format
)
if ret is not None:
return ret
return _fallback_load_fileobj(
filepath,
frame_offset,
num_frames,
normalize,
channels_first,
format,
buffer_size,
)
raise RuntimeError("sox_io backend does not support file-like object.")
filepath = os.fspath(filepath)
ret = torch.ops.torchaudio.sox_io_load_audio_file(
filepath, frame_offset, num_frames, normalize, channels_first, format
......@@ -270,9 +175,7 @@ def save(
"""Save audio data to file.
Args:
filepath (str or pathlib.Path): Path to save file.
This function also handles ``pathlib.Path`` objects, but is annotated
as ``str`` for TorchScript compiler compatibility.
filepath (path-like object): Path to save file.
src (torch.Tensor): Audio data to save. must be 2D tensor.
sample_rate (int): sampling rate
channels_first (bool, optional): If ``True``, the given tensor is interpreted as `[channel, time]`,
......@@ -413,18 +316,7 @@ def save(
"""
if not torch.jit.is_scripting():
if hasattr(filepath, "write"):
warnings.warn(_deprecation_message)
torchaudio.lib._torchaudio_sox.save_audio_fileobj(
filepath,
src,
sample_rate,
channels_first,
compression,
format,
encoding,
bits_per_sample,
)
return
raise RuntimeError("sox_io backend does not handle file-like object.")
filepath = os.fspath(filepath)
torch.ops.torchaudio.sox_io_save_audio_file(
filepath,
......
......@@ -15,17 +15,9 @@ torchaudio_library(
)
if (BUILD_TORCHAUDIO_PYTHON_EXTENSION)
set(
ext_sources
pybind/pybind.cpp
pybind/effects.cpp
pybind/effects_chain.cpp
pybind/io.cpp
pybind/utils.cpp
)
torchaudio_extension(
_torchaudio_sox
"${ext_sources}"
"pybind/pybind.cpp;"
""
"libtorchaudio_sox"
""
......
#include <torch/extension.h>
#include <torchaudio/csrc/sox/utils.h>
#include <torchaudio/csrc/sox/pybind/effects.h>
#include <torchaudio/csrc/sox/pybind/io.h>
namespace torchaudio::sox {
namespace torchaudio {
namespace sox {
namespace {
PYBIND11_MODULE(_torchaudio_sox, m) {
m.def("set_seed", &set_seed, "Set random seed.");
m.def("set_verbosity", &set_verbosity, "Set verbosity.");
m.def("set_use_threads", &set_use_threads, "Set threading.");
m.def("set_buffer_size", &set_buffer_size, "Set buffer size.");
m.def("get_buffer_size", &get_buffer_size, "Get buffer size.");
m.def("list_effects", &list_effects, "List available effects.");
m.def(
"get_info_fileobj",
&get_info_fileobj,
"Get metadata of audio in file object.");
"list_read_formats",
&list_read_formats,
"List supported formats for decoding.");
m.def(
"load_audio_fileobj",
&load_audio_fileobj,
"Load audio from file object.");
m.def("save_audio_fileobj", &save_audio_fileobj, "Save audio to file obj.");
m.def(
"apply_effects_fileobj",
&apply_effects_fileobj,
"Decode audio data from file-like obj and apply effects.");
"list_write_formats",
&list_write_formats,
"List supported formats for encoding.");
}
} // namespace
} // namespace torchaudio::sox
} // namespace sox
} // namespace torchaudio
......@@ -491,18 +491,4 @@ sox_encodinginfo_t get_encodinginfo_for_save(
/*opposite_endian=*/sox_false};
}
namespace {
TORCH_LIBRARY_FRAGMENT(torchaudio, m) {
m.def("torchaudio::sox_utils_set_seed", &set_seed);
m.def("torchaudio::sox_utils_set_verbosity", &set_verbosity);
m.def("torchaudio::sox_utils_set_use_threads", &set_use_threads);
m.def("torchaudio::sox_utils_set_buffer_size", &set_buffer_size);
m.def("torchaudio::sox_utils_list_effects", &list_effects);
m.def("torchaudio::sox_utils_list_read_formats", &list_read_formats);
m.def("torchaudio::sox_utils_list_write_formats", &list_write_formats);
m.def("torchaudio::sox_utils_get_buffer_size", &get_buffer_size);
}
} // namespace
} // namespace torchaudio::sox
import os
import warnings
from typing import List, Optional, Tuple
import torch
......@@ -156,14 +155,6 @@ def apply_effects_tensor(
return torch.ops.torchaudio.sox_effects_apply_effects_tensor(tensor, sample_rate, effects, channels_first)
_deprecation_message = (
"File-like object support in sox_io backend is deprecated, "
"and will be removed in v2.1. "
"See https://github.com/pytorch/audio/issues/2950 for the detail."
"Please migrate to the new dispatcher, or use soundfile backend."
)
@torchaudio._extension.fail_if_no_sox
def apply_effects_file(
path: str,
......@@ -187,18 +178,8 @@ def apply_effects_file(
rate and leave samples untouched.
Args:
path (path-like object or file-like object):
Source of audio data. When the function is not compiled by TorchScript,
(e.g. ``torch.jit.script``), the following types are accepted:
* ``path-like``: file path
* ``file-like``: Object with ``read(size: int) -> bytes`` method,
which returns byte string of at most ``size`` length.
When the function is compiled by TorchScript, only ``str`` type is allowed.
Note: This argument is intentionally annotated as ``str`` only for
TorchScript compiler compatibility.
path (path-like object):
Source of audio data.
effects (List[List[str]]): List of effects.
normalize (bool, optional):
When ``True``, this function converts the native sample type to ``float32``.
......@@ -283,11 +264,10 @@ def apply_effects_file(
"""
if not torch.jit.is_scripting():
if hasattr(path, "read"):
warnings.warn(_deprecation_message)
ret = torchaudio.lib._torchaudio_sox.apply_effects_fileobj(path, effects, normalize, channels_first, format)
if ret is None:
raise RuntimeError("Failed to load audio from {}".format(path))
return ret
raise RuntimeError(
"apply_effects_file function does not support file-like object. "
"Please use torchaudio.io.AudioEffector."
)
path = os.fspath(path)
ret = torch.ops.torchaudio.sox_effects_apply_effects_file(path, effects, normalize, channels_first, format)
if ret is not None:
......
......@@ -4,7 +4,6 @@
from typing import Dict, List
import torch
import torchaudio
......@@ -18,7 +17,7 @@ def set_seed(seed: int):
See Also:
http://sox.sourceforge.net/sox.html
"""
torch.ops.torchaudio.sox_utils_set_seed(seed)
torchaudio.lib._torchaudio_sox.set_seed(seed)
@torchaudio._extension.fail_if_no_sox
......@@ -36,7 +35,7 @@ def set_verbosity(verbosity: int):
See Also:
http://sox.sourceforge.net/sox.html
"""
torch.ops.torchaudio.sox_utils_set_verbosity(verbosity)
torchaudio.lib._torchaudio_sox.set_verbosity(verbosity)
@torchaudio._extension.fail_if_no_sox
......@@ -49,7 +48,7 @@ def set_buffer_size(buffer_size: int):
See Also:
http://sox.sourceforge.net/sox.html
"""
torch.ops.torchaudio.sox_utils_set_buffer_size(buffer_size)
torchaudio.lib._torchaudio_sox.set_buffer_size(buffer_size)
@torchaudio._extension.fail_if_no_sox
......@@ -63,7 +62,7 @@ def set_use_threads(use_threads: bool):
See Also:
http://sox.sourceforge.net/sox.html
"""
torch.ops.torchaudio.sox_utils_set_use_threads(use_threads)
torchaudio.lib._torchaudio_sox.set_use_threads(use_threads)
@torchaudio._extension.fail_if_no_sox
......@@ -73,7 +72,7 @@ def list_effects() -> Dict[str, str]:
Returns:
Dict[str, str]: Mapping from ``effect name`` to ``usage``
"""
return dict(torch.ops.torchaudio.sox_utils_list_effects())
return dict(torchaudio.lib._torchaudio_sox.list_effects())
@torchaudio._extension.fail_if_no_sox
......@@ -83,7 +82,7 @@ def list_read_formats() -> List[str]:
Returns:
List[str]: List of supported audio formats
"""
return torch.ops.torchaudio.sox_utils_list_read_formats()
return torchaudio.lib._torchaudio_sox.list_read_formats()
@torchaudio._extension.fail_if_no_sox
......@@ -93,7 +92,7 @@ def list_write_formats() -> List[str]:
Returns:
List[str]: List of supported audio formats
"""
return torch.ops.torchaudio.sox_utils_list_write_formats()
return torchaudio.lib._torchaudio_sox.list_write_formats()
@torchaudio._extension.fail_if_no_sox
......@@ -103,4 +102,4 @@ def get_buffer_size() -> int:
Returns:
int: size in bytes of buffers used for processing audio.
"""
return torch.ops.torchaudio.sox_utils_get_buffer_size()
return torchaudio.lib._torchaudio_sox.get_buffer_size()
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