From c24a6dee84c89ae3a49bf9cdfd94dffb79007538 Mon Sep 17 00:00:00 2001 From: Moto Hira Date: Tue, 14 Jul 2020 14:11:51 -0700 Subject: [PATCH] Import torchaudio 20200714 #782 Summary: - Import torchaudio. - Change test util module name from test_case_utils to case_utils Differential Revision: D22261638 fbshipit-source-id: 4735290c021c177515e8a526a91182de51e3b785 --- README.md | 4 +- .../setup_helpers/build_third_party.sh | 50 --- .../setup_helpers/build_third_party_helper.sh | 217 ----------- build_tools/setup_helpers/extension.py | 36 +- packaging/build_conda.sh | 2 +- packaging/build_wheel.sh | 2 +- packaging/pkg_helpers.bash | 3 +- setup.py | 2 +- test/README.md | 52 +++ .../tt/clips/common_voice_tt_00000000.mp3 | Bin 57136 -> 0 bytes .../tt/clips/common_voice_tt_00000000.wav | Bin 0 -> 80700 bytes .../cv-corpus-4-2019-12-10/tt/train.tsv | 4 +- test/assets/dtmf_30s_stereo.mp3 | Bin 228984 -> 0 bytes test/assets/io/96k_0_1ch.opus | Bin 0 -> 8259 bytes test/assets/io/96k_0_2ch.opus | Bin 0 -> 6740 bytes test/assets/io/96k_10_1ch.opus | Bin 0 -> 15033 bytes test/assets/io/96k_10_2ch.opus | Bin 0 -> 15160 bytes test/assets/io/96k_5_1ch.opus | Bin 0 -> 13074 bytes test/assets/io/96k_5_2ch.opus | Bin 0 -> 10618 bytes test/assets/io/generate_opus.py | 50 +++ test/common_utils.py | 171 --------- test/common_utils/__init__.py | 31 ++ test/common_utils/backend_utils.py | 41 ++ test/common_utils/case_utils.py | 75 ++++ test/common_utils/data_utils.py | 94 +++++ test/common_utils/parameterized_utils.py | 10 + test/common_utils/sox_utils.py | 79 ++++ test/common_utils/wav_utils.py | 86 +++++ test/functional_cpu_test.py | 35 +- test/kaldi_compatibility_impl.py | 52 ++- test/sox_io_backend/__init__.py | 0 test/sox_io_backend/common.py | 2 + test/sox_io_backend/test_info.py | 125 +++++++ test/sox_io_backend/test_load.py | 263 +++++++++++++ test/sox_io_backend/test_roundtrip.py | 52 +++ test/sox_io_backend/test_save.py | 304 +++++++++++++++ test/sox_io_backend/test_torchscript.py | 149 ++++++++ test/test_backend.py | 15 +- test/test_datasets.py | 3 +- test/test_io.py | 33 +- test/test_librosa_compatibility.py | 9 +- test/test_models.py | 117 +++++- test/test_sox_compatibility.py | 206 +++++------ test/test_sox_effects.py | 4 +- test/test_transforms.py | 6 +- test/torchscript_consistency_impl.py | 4 +- third_party/CMakeLists.txt | 80 ++++ third_party/build_codec_helper.sh | 13 + third_party/patch/libmad.patch | 86 +++++ torchaudio/backend/sox_io_backend.py | 134 +++++++ torchaudio/backend/utils.py | 6 + torchaudio/csrc/register.cpp | 59 ++- torchaudio/csrc/sox.cpp | 33 -- torchaudio/csrc/sox.h | 7 - torchaudio/csrc/sox_effects.cpp | 54 +++ torchaudio/csrc/sox_effects.h | 18 + torchaudio/csrc/sox_io.cpp | 170 +++++++++ torchaudio/csrc/sox_io.h | 41 ++ torchaudio/csrc/sox_utils.cpp | 245 ++++++++++++ torchaudio/csrc/sox_utils.h | 100 +++++ torchaudio/csrc/typedefs.cpp | 23 -- torchaudio/csrc/typedefs.h | 23 -- torchaudio/extension/extension.py | 29 -- torchaudio/functional.py | 7 +- torchaudio/models/_wavernn.py | 350 ++++++++++++++---- torchaudio/sox_effects/__init__.py | 2 + torchaudio/sox_effects/sox_effects.py | 54 +-- 67 files changed, 3049 insertions(+), 873 deletions(-) delete mode 100755 build_tools/setup_helpers/build_third_party.sh delete mode 100644 build_tools/setup_helpers/build_third_party_helper.sh delete mode 100644 test/assets/CommonVoice/cv-corpus-4-2019-12-10/tt/clips/common_voice_tt_00000000.mp3 create mode 100644 test/assets/CommonVoice/cv-corpus-4-2019-12-10/tt/clips/common_voice_tt_00000000.wav delete mode 100644 test/assets/dtmf_30s_stereo.mp3 create mode 100644 test/assets/io/96k_0_1ch.opus create mode 100644 test/assets/io/96k_0_2ch.opus create mode 100644 test/assets/io/96k_10_1ch.opus create mode 100644 test/assets/io/96k_10_2ch.opus create mode 100644 test/assets/io/96k_5_1ch.opus create mode 100644 test/assets/io/96k_5_2ch.opus create mode 100644 test/assets/io/generate_opus.py delete mode 100644 test/common_utils.py create mode 100644 test/common_utils/__init__.py create mode 100644 test/common_utils/backend_utils.py create mode 100644 test/common_utils/case_utils.py create mode 100644 test/common_utils/data_utils.py create mode 100644 test/common_utils/parameterized_utils.py create mode 100644 test/common_utils/sox_utils.py create mode 100644 test/common_utils/wav_utils.py create mode 100644 test/sox_io_backend/__init__.py create mode 100644 test/sox_io_backend/common.py create mode 100644 test/sox_io_backend/test_info.py create mode 100644 test/sox_io_backend/test_load.py create mode 100644 test/sox_io_backend/test_roundtrip.py create mode 100644 test/sox_io_backend/test_save.py create mode 100644 test/sox_io_backend/test_torchscript.py create mode 100644 third_party/CMakeLists.txt create mode 100755 third_party/build_codec_helper.sh create mode 100644 third_party/patch/libmad.patch create mode 100644 torchaudio/backend/sox_io_backend.py create mode 100644 torchaudio/csrc/sox_effects.cpp create mode 100644 torchaudio/csrc/sox_effects.h create mode 100644 torchaudio/csrc/sox_io.cpp create mode 100644 torchaudio/csrc/sox_io.h create mode 100644 torchaudio/csrc/sox_utils.cpp create mode 100644 torchaudio/csrc/sox_utils.h delete mode 100644 torchaudio/csrc/typedefs.cpp delete mode 100644 torchaudio/csrc/typedefs.h diff --git a/README.md b/README.md index 94f993ddaa..290bb73543 100644 --- a/README.md +++ b/README.md @@ -113,8 +113,8 @@ python setup.py install MACOSX_DEPLOYMENT_TARGET=10.9 CC=clang CXX=clang++ python setup.py install ``` -Alternatively, the build process can build SoX (and codecs such as libmad, lame and flac) statically and torchaudio can link them, by setting environment variable `BUILD_SOX=1`. -The build process will fetch and build SoX, liblame, libmad, flac before building extension. +Alternatively, the build process can build libsox and some optional codecs statically and torchaudio can link them, by setting environment variable `BUILD_SOX=1`. +The build process will fetch and build libmad, lame, flac, vorbis, opus, and libsox before building extension. This process requires `cmake` and `pkg-config`. ```bash # Linux diff --git a/build_tools/setup_helpers/build_third_party.sh b/build_tools/setup_helpers/build_third_party.sh deleted file mode 100755 index 9577776cc9..0000000000 --- a/build_tools/setup_helpers/build_third_party.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash -# Build third party libraries (SoX, lame, libmad, and flac) -# Usage: ./build_thid_parth.sh [prefix] [download_only?=false] - -set -e - -this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -root_dir="${this_dir}/../.." - -prefix="${1:-}" -if [ -z "${prefix}" ]; then - prefix="${root_dir}" -fi -download_only="${2:-false}" - -tp_dir="${prefix}/third_party" -tmp_dir="${tp_dir}/tmp" -build_dir="${tp_dir}/build" - -mkdir -p "${tmp_dir}" "${build_dir}" - -. "${this_dir}/build_third_party_helper.sh" - -if ! found_lame "${build_dir}" ; then - get_lame "${tmp_dir}" - if [ "${download_only}" = "false" ]; then - build_lame "${tmp_dir}" "${build_dir}" - fi -fi - -if ! found_flac "${build_dir}" ; then - get_flac "${tmp_dir}" - if [ "${download_only}" = "false" ]; then - build_flac "${tmp_dir}" "${build_dir}" - fi -fi - -if ! found_mad "${build_dir}" ; then - get_mad "${tmp_dir}" - if [ "${download_only}" = "false" ]; then - build_mad "${tmp_dir}" "${build_dir}" - fi -fi - -if ! found_sox "${build_dir}" ; then - get_sox "${tmp_dir}" - if [ "${download_only}" = "false" ]; then - build_sox "${tmp_dir}" "${build_dir}" - fi -fi diff --git a/build_tools/setup_helpers/build_third_party_helper.sh b/build_tools/setup_helpers/build_third_party_helper.sh deleted file mode 100644 index 7cca812409..0000000000 --- a/build_tools/setup_helpers/build_third_party_helper.sh +++ /dev/null @@ -1,217 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# Global options -CURL_OPTS="-L --retry 10 --connect-timeout 5 --max-time 180" -MAKE_OPTS="-j" -CONFIG_OPTS="" - -if [ -z ${DEBUG+x} ]; then - CURL_OPTS="${CURL_OPTS} --silent --show-error" - MAKE_OPTS="${MAKE_OPTS} --quiet" - CONFIG_OPTS="${CONFIG_OPTS} --quiet" -fi - -all_found() { - dir="$1" - shift - while [ "$#" -gt 0 ]; do - if [ ! -f "${dir}/$1" ]; then - return 1 - fi - shift - done -} - - -found_lame() { - all_found "$1" 'include/lame/lame.h' 'lib/libmp3lame.a' -} - -found_flac() { - all_found "$1" \ - 'include/FLAC/format.h' \ - 'include/FLAC/stream_decoder.h' \ - 'include/FLAC/export.h' \ - 'include/FLAC/ordinals.h' \ - 'include/FLAC/all.h' \ - 'include/FLAC/assert.h' \ - 'include/FLAC/callback.h' \ - 'include/FLAC/metadata.h' \ - 'include/FLAC/stream_encoder.h' \ - 'include/FLAC++/export.h' \ - 'include/FLAC++/decoder.h' \ - 'include/FLAC++/all.h' \ - 'include/FLAC++/metadata.h' \ - 'include/FLAC++/encoder.h' \ - 'lib/libFLAC++.a' \ - 'lib/libFLAC.a' -} - -found_mad() { - all_found "$1" 'include/mad.h' 'lib/libmad.a' -} - -found_sox() { - all_found "$1" 'include/sox.h' 'lib/libsox.a' -} - -LAME="lame-3.99.5" -LAME_ARCHIVE="${LAME}.tar.gz" - -get_lame() { - work_dir="$1" - url="https://downloads.sourceforge.net/project/lame/lame/3.99/${LAME_ARCHIVE}" - ( - cd "${work_dir}" - if [ ! -d "${LAME}" ]; then - if [ ! -f "${LAME_ARCHIVE}" ]; then - printf "Fetching liblame from %s\n" "${url}" - curl $CURL_OPTS -O "${url}" - fi - fi - ) -} - -build_lame() { - work_dir="$1" - install_dir="$2" - ( - cd "${work_dir}" - if [ ! -d "${LAME}" ]; then - tar xfp "${LAME_ARCHIVE}" - fi - cd "${LAME}" - # build statically - printf "Building liblame\n" - if [ ! -f Makefile ]; then - ./configure ${CONFIG_OPTS} \ - --disable-shared --enable-static --prefix="${install_dir}" CFLAGS=-fPIC CXXFLAGS=-fPIC \ - --with-pic --disable-debug --disable-dependency-tracking --enable-nasm - fi - make ${MAKE_OPTS} > make.log 2>&1 - make ${MAKE_OPTS} install - ) -} - -FLAC="flac-1.3.2" -FLAC_ARCHIVE="${FLAC}.tar.xz" - -get_flac() { - work_dir="$1" - url="https://downloads.sourceforge.net/project/flac/flac-src/${FLAC_ARCHIVE}" - ( - cd "${work_dir}" - if [ ! -d "${FLAC}" ]; then - if [ ! -f "${FLAC_ARCHIVE}" ]; then - printf "Fetching flac from %s\n" "${url}" - curl $CURL_OPTS -O "${url}" - fi - fi - ) -} - -build_flac() { - work_dir="$1" - install_dir="$2" - ( - cd "${work_dir}" - if [ ! -d "${FLAC}" ]; then - tar xfp "${FLAC_ARCHIVE}" - fi - cd "${FLAC}" - # build statically - printf "Building flac\n" - if [ ! -f Makefile ]; then - ./configure ${CONFIG_OPTS} \ - --disable-shared --enable-static --prefix="${install_dir}" CFLAGS=-fPIC CXXFLAGS=-fPIC \ - --with-pic --disable-debug --disable-dependency-tracking - fi - make ${MAKE_OPTS} > make.log 2>&1 - make ${MAKE_OPTS} install - ) -} - -LIBMAD="libmad-0.15.1b" -LIBMAD_ARCHIVE="${LIBMAD}.tar.gz" - -get_mad() { - work_dir="$1" - url="https://downloads.sourceforge.net/project/mad/libmad/0.15.1b/${LIBMAD_ARCHIVE}" - ( - cd "${work_dir}" - if [ ! -d "${LIBMAD}" ]; then - if [ ! -f "${LIBMAD_ARCHIVE}" ]; then - printf "Fetching mad from %s\n" "${url}" - curl $CURL_OPTS -O "${url}" - fi - fi - ) -} - -build_mad() { - work_dir="$1" - install_dir="$2" - ( - cd "${work_dir}" - if [ ! -d "${LIBMAD}" ]; then - tar xfp "${LIBMAD_ARCHIVE}" - fi - cd "${LIBMAD}" - # build statically - printf "Building mad\n" - if [ ! -f Makefile ]; then - # See https://stackoverflow.com/a/12864879/23845 - sed -i.bak 's/-march=i486//' configure - ./configure ${CONFIG_OPTS} \ - --disable-shared --enable-static --prefix="${install_dir}" CFLAGS=-fPIC CXXFLAGS=-fPIC \ - --with-pic --disable-debug --disable-dependency-tracking - fi - make ${MAKE_OPTS} > make.log 2>&1 - make ${MAKE_OPTS} install - ) -} - -SOX="sox-14.4.2" -SOX_ARCHIVE="${SOX}.tar.bz2" - -get_sox() { - work_dir="$1" - url="https://downloads.sourceforge.net/project/sox/sox/14.4.2/${SOX_ARCHIVE}" - ( - cd "${work_dir}" - if [ ! -d "${SOX}" ]; then - if [ ! -f "${SOX_ARCHIVE}" ]; then - printf "Fetching SoX from %s\n" "${url}" - curl $CURL_OPTS -O "${url}" - fi - fi - ) -} - -build_sox() { - work_dir="$1" - install_dir="$2" - ( - cd "${work_dir}" - if [ ! -d "${SOX}" ]; then - tar xfp "${SOX_ARCHIVE}" - fi - cd "${SOX}" - # build statically - printf "Building SoX\n" - if [ ! -f Makefile ]; then - # --without-png makes OS X build less hazardous; somehow the build - # finds png and enables it. We don't want it; we'd need to package - # it statically if we do. - ./configure ${CONFIG_OPTS} --disable-shared --enable-static --prefix="${install_dir}" \ - LDFLAGS="-L${install_dir}/lib" CPPFLAGS="-I${install_dir}/include" \ - --with-lame --with-flac --with-mad --without-alsa --without-coreaudio \ - --without-png --without-oggvorbis --without-oss --without-sndfile \ - CFLAGS=-fPIC CXXFLAGS=-fPIC --with-pic --disable-debug --disable-dependency-tracking - fi - make ${MAKE_OPTS} > make.log 2>&1 - make ${MAKE_OPTS} install - ) -} diff --git a/build_tools/setup_helpers/extension.py b/build_tools/setup_helpers/extension.py index dcf61ab259..b9fb30e114 100644 --- a/build_tools/setup_helpers/extension.py +++ b/build_tools/setup_helpers/extension.py @@ -17,7 +17,7 @@ _ROOT_DIR = _THIS_DIR.parent.parent.resolve() _CSRC_DIR = _ROOT_DIR / 'torchaudio' / 'csrc' _TP_BASE_DIR = _ROOT_DIR / 'third_party' -_TP_INSTALL_DIR = _TP_BASE_DIR / 'build' +_TP_INSTALL_DIR = _TP_BASE_DIR / 'install' def _get_build_sox(): @@ -76,8 +76,20 @@ def _get_extra_objects(): # NOTE: The order of the library listed bellow matters. # # (the most important thing is that dependencies come after a library - # e.g., sox comes first) - libs = ['libsox.a', 'libmad.a', 'libFLAC.a', 'libmp3lame.a'] + # e.g., sox comes first, flac/vorbis comes before ogg, and + # vorbisenc/vorbisfile comes before vorbis + libs = [ + 'libsox.a', + 'libmad.a', + 'libFLAC.a', + 'libmp3lame.a', + 'libopusfile.a', + 'libopus.a', + 'libvorbisenc.a', + 'libvorbisfile.a', + 'libvorbis.a', + 'libogg.a', + ] for lib in libs: objs.append(str(_TP_INSTALL_DIR / 'lib' / lib)) return objs @@ -87,15 +99,19 @@ def _get_libraries(): return [] if _BUILD_SOX else ['sox'] -def _build_codecs(): +def _build_third_party(): + build_dir = str(_TP_BASE_DIR / 'build') + os.makedirs(build_dir, exist_ok=True) subprocess.run( - args=[str(_THIS_DIR / 'build_third_party.sh')], + args=['cmake', '..'], + cwd=build_dir, + check=True, + ) + subprocess.run( + args=['cmake', '--build', '.'], + cwd=build_dir, check=True, ) - - -def _configure_third_party(): - _build_codecs() _EXT_NAME = 'torchaudio._torchaudio' @@ -120,5 +136,5 @@ def get_ext_modules(debug=False): class BuildExtension(TorchBuildExtension): def build_extension(self, ext): if ext.name == _EXT_NAME and _BUILD_SOX: - _configure_third_party() + _build_third_party() super().build_extension(ext) diff --git a/packaging/build_conda.sh b/packaging/build_conda.sh index 3e011d312f..628eaf0bf8 100755 --- a/packaging/build_conda.sh +++ b/packaging/build_conda.sh @@ -6,7 +6,7 @@ script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" export BUILD_TYPE="conda" export NO_CUDA_PACKAGE=1 -setup_env 0.6.0 +setup_env 0.7.0 export SOURCE_ROOT_DIR="$PWD" setup_conda_pytorch_constraint conda build $CONDA_CHANNEL_FLAGS --no-anaconda-upload --python "$PYTHON_VERSION" packaging/torchaudio diff --git a/packaging/build_wheel.sh b/packaging/build_wheel.sh index d08196cb20..3b25c00cd2 100755 --- a/packaging/build_wheel.sh +++ b/packaging/build_wheel.sh @@ -6,7 +6,7 @@ script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" export BUILD_TYPE="wheel" export NO_CUDA_PACKAGE=1 -setup_env 0.6.0 +setup_env 0.7.0 setup_wheel_python pip_install numpy future setup_pip_pytorch_version diff --git a/packaging/pkg_helpers.bash b/packaging/pkg_helpers.bash index 4030128a98..3ec49a0269 100644 --- a/packaging/pkg_helpers.bash +++ b/packaging/pkg_helpers.bash @@ -171,6 +171,7 @@ setup_pip_pytorch_version() { else pip_install "torch==$PYTORCH_VERSION$PYTORCH_VERSION_SUFFIX" \ -f https://download.pytorch.org/whl/torch_stable.html \ + -f https://download.pytorch.org/whl/test/torch_test.html \ -f https://download.pytorch.org/whl/nightly/torch_nightly.html fi } @@ -184,7 +185,7 @@ setup_conda_pytorch_constraint() { export CONDA_CHANNEL_FLAGS="-c pytorch-nightly" export PYTORCH_VERSION="$(conda search --json 'pytorch[channel=pytorch-nightly]' | python -c "import sys, json, re; print(re.sub(r'\\+.*$', '', json.load(sys.stdin)['pytorch'][-1]['version']))")" else - export CONDA_CHANNEL_FLAGS="-c pytorch -c pytorch-nightly" + export CONDA_CHANNEL_FLAGS="-c pytorch -c pytorch-test -c pytorch-nightly" fi if [[ "$CU_VERSION" == cpu ]]; then export CONDA_PYTORCH_BUILD_CONSTRAINT="- pytorch==$PYTORCH_VERSION${PYTORCH_VERSION_SUFFIX}" diff --git a/setup.py b/setup.py index 5cf1ad680a..aab59b4d8a 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ # Creating the version file -version = '0.6.0a0' +version = '0.7.0a0' sha = 'Unknown' try: diff --git a/test/README.md b/test/README.md index 35a926c120..304bfa9c8e 100644 --- a/test/README.md +++ b/test/README.md @@ -41,6 +41,58 @@ The following test modules are defined for corresponding `torchaudio` module/fun - [assets/kaldi](./assets/kaldi): Contains Kaldi format matrix files used in [./test_compliance_kaldi.py](./test_compliance_kaldi.py). - [compliance](./compliance): Scripts used to generate above Kaldi matrix files. +### Waveforms for Testing Purposes + +When testing transforms we often need waveforms of specific type (ex: pure tone, noise, or voice), with specific bitrate (ex. 8 or 16 kHz) and number of channels (ex. mono, stereo). Below are some tips on how to construct waveforms and guidance around existing audio files. + +#### Load a Waveform from a File + +```python +filepath = common_utils.get_asset_path('filename.wav') +waveform, sample_rate = common_utils.load_wav(filepath) +``` + +*Note: Should you choose to contribute an audio file, please leave a comment in the issue or pull request, mentioning content source and licensing information. WAV files are preferred. Other formats should be used only when there is no alternative. (i.e. dataset implementation comes with hardcoded non-wav extension).* + +#### Pure Tone + +Code: + +```python +waveform = common_utils.get_sinusoid( + frequency=300, + sample_rate=16000, + duration=1, # seconds + n_channels=1, + dtype="float32", + device="cpu", +) +``` + +#### Noise + +Code: + +```python +tensor = common_utils.get_whitenoise() +``` + +Files: + +* `steam-train-whistle-daniel_simon.wav` + +#### Voice + +Files: + +* `CommonVoice/cv-corpus-4-2019-12-10/tt/clips/common_voice_tt_00000000.wav` +* `LibriSpeech/dev-clean/1272/128104/1272-128104-0000.flac` +* `LJSpeech-1.1/wavs/LJ001-0001.wav` +* `SpeechCommands/speech_commands_v0.02/go/0a9f9af7_nohash_0.wav` +* `VCTK-Corpus/wav48/p224/p224_002.wav` +* `waves_yesno/0_1_0_1_0_1_1_0.wav` +* `vad-go-stereo-44100.wav` +* `vad-go-mono-32000.wav` ## Adding test diff --git a/test/assets/CommonVoice/cv-corpus-4-2019-12-10/tt/clips/common_voice_tt_00000000.mp3 b/test/assets/CommonVoice/cv-corpus-4-2019-12-10/tt/clips/common_voice_tt_00000000.mp3 deleted file mode 100644 index d6fe9f44b90bb0e03d7b3ebfb8f46858f888bc3a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57136 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 diff --git a/test/assets/CommonVoice/cv-corpus-4-2019-12-10/tt/clips/common_voice_tt_00000000.wav b/test/assets/CommonVoice/cv-corpus-4-2019-12-10/tt/clips/common_voice_tt_00000000.wav new file mode 100644 index 0000000000000000000000000000000000000000..8f9d80d7e152b418703d0421f8ea5e0b710d6a89 GIT binary patch literal 80700 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 literal 0 HcmV?d00001 diff --git a/test/assets/CommonVoice/cv-corpus-4-2019-12-10/tt/train.tsv b/test/assets/CommonVoice/cv-corpus-4-2019-12-10/tt/train.tsv index 2b677dbf7f..a5244b01f2 100644 --- a/test/assets/CommonVoice/cv-corpus-4-2019-12-10/tt/train.tsv +++ b/test/assets/CommonVoice/cv-corpus-4-2019-12-10/tt/train.tsv @@ -1,3 +1,3 @@ client_id path sentence up_votes down_votes age gender accent -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 common_voice_tt_00000000.mp3 test. 1 0 thirties female -00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 common_voice_tt_00000000.mp3 test. 1 0 thirties female +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 common_voice_tt_00000000.wav test. 1 0 thirties female +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 common_voice_tt_00000000.wav test. 1 0 thirties female diff --git a/test/assets/dtmf_30s_stereo.mp3 b/test/assets/dtmf_30s_stereo.mp3 deleted file mode 100644 index 6c97835ec0dedc5273f1aeee4d5d4bdd7c541b41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 228984 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%0Dpm;`O%JVx#`VwGdAP%kJv+INes^| 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�o}ou>L#n&!)STAN?mwDlk$4QPHK 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 diff --git a/test/assets/io/96k_0_1ch.opus b/test/assets/io/96k_0_1ch.opus new file mode 100644 index 0000000000000000000000000000000000000000..df95474ddb67499f9223537f0081c689b0be654a GIT binary patch literal 8259 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 literal 0 HcmV?d00001 diff --git a/test/assets/io/96k_0_2ch.opus b/test/assets/io/96k_0_2ch.opus new file mode 100644 index 0000000000000000000000000000000000000000..b8837e81e26b579d984f2b871523322d4e8b5399 GIT binary patch literal 6740 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 LtBkx?x;Fd|2;dDu literal 0 HcmV?d00001 diff --git a/test/assets/io/96k_10_1ch.opus b/test/assets/io/96k_10_1ch.opus new file mode 100644 index 0000000000000000000000000000000000000000..56b170d380376604f308a28cb2ca92ed1f1481cc GIT binary patch literal 15033 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 literal 0 HcmV?d00001 diff --git a/test/assets/io/96k_5_2ch.opus b/test/assets/io/96k_5_2ch.opus new file mode 100644 index 0000000000000000000000000000000000000000..007bc813cea92c6555cde19b2ff0f8e779a59614 GIT binary patch literal 10618 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 literal 0 HcmV?d00001 diff --git a/test/assets/io/generate_opus.py b/test/assets/io/generate_opus.py new file mode 100644 index 0000000000..e6b99c471c --- /dev/null +++ b/test/assets/io/generate_opus.py @@ -0,0 +1,50 @@ +"""Generate opus file for testing load functions""" + +import argparse +import subprocess + +import scipy.io.wavfile +import torch + + +def _parse_args(): + parser = argparse.ArgumentParser( + description='Generate opus files for test' + ) + parser.add_argument('--num-channels', required=True, type=int) + parser.add_argument('--compression-level', required=True, type=int, choices=list(range(11))) + parser.add_argument('--bitrate', default='96k') + return parser.parse_args() + + +def convert_to_opus( + src_path, dst_path, + *, bitrate, compression_level): + """Convert audio file with `ffmpeg` command.""" + command = ['ffmpeg', '-y', '-i', src_path, '-c:a', 'libopus', '-b:a', bitrate] + if compression_level is not None: + command += ['-compression_level', str(compression_level)] + command += [dst_path] + print(' '.join(command)) + subprocess.run(command, check=True) + + +def _generate(num_channels, compression_level, bitrate): + org_path = 'original.wav' + ops_path = f'{bitrate}_{compression_level}_{num_channels}ch.opus' + + # Note: ffmpeg forces sample rate 48k Hz for opus https://stackoverflow.com/a/39186779 + # 1. generate original wav + data = torch.linspace(-32768, 32767, 32768, dtype=torch.int16).repeat([num_channels, 1]).t() + scipy.io.wavfile.write(org_path, 48000, data.numpy()) + # 2. convert to opus + convert_to_opus(org_path, ops_path, bitrate=bitrate, compression_level=compression_level) + + +def _main(): + args = _parse_args() + _generate(args.num_channels, args.compression_level, args.bitrate) + + +if __name__ == '__main__': + _main() diff --git a/test/common_utils.py b/test/common_utils.py deleted file mode 100644 index fe045d9db8..0000000000 --- a/test/common_utils.py +++ /dev/null @@ -1,171 +0,0 @@ -import os -import tempfile -import unittest -from typing import Union -from shutil import copytree - -import torch -from torch.testing._internal.common_utils import TestCase as PytorchTestCase -import torchaudio - -_TEST_DIR_PATH = os.path.dirname(os.path.realpath(__file__)) -BACKENDS = torchaudio.list_audio_backends() - - -def get_asset_path(*paths): - """Return full path of a test asset""" - return os.path.join(_TEST_DIR_PATH, 'assets', *paths) - - -def create_temp_assets_dir(): - """ - Creates a temporary directory and moves all files from test/assets there. - Returns a Tuple[string, TemporaryDirectory] which is the folder path - and object. - """ - tmp_dir = tempfile.TemporaryDirectory() - copytree(os.path.join(_TEST_DIR_PATH, "assets"), - os.path.join(tmp_dir.name, "assets")) - return tmp_dir.name, tmp_dir - - -def random_float_tensor(seed, size, a=22695477, c=1, m=2 ** 32): - """ Generates random tensors given a seed and size - https://en.wikipedia.org/wiki/Linear_congruential_generator - X_{n + 1} = (a * X_n + c) % m - Using Borland C/C++ values - - The tensor will have values between [0,1) - Inputs: - seed (int): an int - size (Tuple[int]): the size of the output tensor - a (int): the multiplier constant to the generator - c (int): the additive constant to the generator - m (int): the modulus constant to the generator - """ - num_elements = 1 - for s in size: - num_elements *= s - - arr = [(a * seed + c) % m] - for i in range(num_elements - 1): - arr.append((a * arr[i] + c) % m) - - return torch.tensor(arr).float().view(size) / m - - -def filter_backends_with_mp3(backends): - # Filter out backends that do not support mp3 - test_filepath = get_asset_path('steam-train-whistle-daniel_simon.mp3') - - def supports_mp3(backend): - torchaudio.set_audio_backend(backend) - try: - torchaudio.load(test_filepath) - return True - except (RuntimeError, ImportError): - return False - - return [backend for backend in backends if supports_mp3(backend)] - - -BACKENDS_MP3 = filter_backends_with_mp3(BACKENDS) - - -def set_audio_backend(backend): - """Allow additional backend value, 'default'""" - if backend == 'default': - if 'sox' in BACKENDS: - be = 'sox' - elif 'soundfile' in BACKENDS: - be = 'soundfile' - else: - raise unittest.SkipTest('No default backend available') - else: - be = backend - - torchaudio.set_audio_backend(be) - - -class TestBaseMixin: - """Mixin to provide consistent way to define device/dtype/backend aware TestCase""" - dtype = None - device = None - backend = None - - def setUp(self): - super().setUp() - set_audio_backend(self.backend) - - -class TorchaudioTestCase(TestBaseMixin, PytorchTestCase): - pass - - -skipIfNoSoxBackend = unittest.skipIf('sox' not in BACKENDS, 'Sox backend not available') -skipIfNoCuda = unittest.skipIf(not torch.cuda.is_available(), reason='CUDA not available') - - -def get_whitenoise( - *, - sample_rate: int = 16000, - duration: float = 1, # seconds - n_channels: int = 1, - seed: int = 0, - dtype: Union[str, torch.dtype] = "float32", - device: Union[str, torch.device] = "cpu", -): - """Generate pseudo audio data with whitenoise - - Args: - sample_rate: Sampling rate - duration: Length of the resulting Tensor in seconds. - n_channels: Number of channels - seed: Seed value used for random number generation. - Note that this function does not modify global random generator state. - dtype: Torch dtype - device: device - Returns: - Tensor: shape of (n_channels, sample_rate * duration) - """ - if isinstance(dtype, str): - dtype = getattr(torch, dtype) - shape = [n_channels, sample_rate * duration] - # According to the doc, folking rng on all CUDA devices is slow when there are many CUDA devices, - # so we only folk on CPU, generate values and move the data to the given device - with torch.random.fork_rng([]): - torch.random.manual_seed(seed) - tensor = torch.randn(shape, dtype=dtype, device='cpu') - tensor /= 2.0 - tensor.clamp_(-1.0, 1.0) - return tensor.to(device=device) - - -def get_sinusoid( - *, - frequency: float = 300, - sample_rate: int = 16000, - duration: float = 1, # seconds - n_channels: int = 1, - dtype: Union[str, torch.dtype] = "float32", - device: Union[str, torch.device] = "cpu", -): - """Generate pseudo audio data with sine wave. - - Args: - frequency: Frequency of sine wave - sample_rate: Sampling rate - duration: Length of the resulting Tensor in seconds. - n_channels: Number of channels - dtype: Torch dtype - device: device - - Returns: - Tensor: shape of (n_channels, sample_rate * duration) - """ - if isinstance(dtype, str): - dtype = getattr(torch, dtype) - pie2 = 2 * 3.141592653589793 - end = pie2 * frequency * duration - theta = torch.linspace(0, end, sample_rate * duration, dtype=dtype, device=device) - return torch.sin(theta, out=None).repeat([n_channels, 1]) diff --git a/test/common_utils/__init__.py b/test/common_utils/__init__.py new file mode 100644 index 0000000000..841cd26713 --- /dev/null +++ b/test/common_utils/__init__.py @@ -0,0 +1,31 @@ +from .data_utils import ( + get_asset_path, + get_whitenoise, + get_sinusoid, +) +from .backend_utils import ( + set_audio_backend, + BACKENDS, + BACKENDS_MP3, +) +from .case_utils import ( + TempDirMixin, + TestBaseMixin, + PytorchTestCase, + TorchaudioTestCase, + skipIfNoCuda, + skipIfNoExec, + skipIfNoModule, + skipIfNoExtension, + skipIfNoSoxBackend, +) +from .wav_utils import ( + get_wav_data, + normalize_wav, + load_wav, + save_wav, +) +from .parameterized_utils import ( + load_params, +) +from . import sox_utils diff --git a/test/common_utils/backend_utils.py b/test/common_utils/backend_utils.py new file mode 100644 index 0000000000..158fde87ed --- /dev/null +++ b/test/common_utils/backend_utils.py @@ -0,0 +1,41 @@ +import unittest + +import torchaudio + +from .import data_utils + + +BACKENDS = torchaudio.list_audio_backends() + + +def _filter_backends_with_mp3(backends): + # Filter out backends that do not support mp3 + test_filepath = data_utils.get_asset_path('steam-train-whistle-daniel_simon.mp3') + + def supports_mp3(backend): + torchaudio.set_audio_backend(backend) + try: + torchaudio.load(test_filepath) + return True + except (RuntimeError, ImportError): + return False + + return [backend for backend in backends if supports_mp3(backend)] + + +BACKENDS_MP3 = _filter_backends_with_mp3(BACKENDS) + + +def set_audio_backend(backend): + """Allow additional backend value, 'default'""" + if backend == 'default': + if 'sox' in BACKENDS: + be = 'sox' + elif 'soundfile' in BACKENDS: + be = 'soundfile' + else: + raise unittest.SkipTest('No default backend available') + else: + be = backend + + torchaudio.set_audio_backend(be) diff --git a/test/common_utils/case_utils.py b/test/common_utils/case_utils.py new file mode 100644 index 0000000000..f3b0c343a6 --- /dev/null +++ b/test/common_utils/case_utils.py @@ -0,0 +1,75 @@ +import shutil +import os.path +import tempfile +import unittest + +import torch +from torch.testing._internal.common_utils import TestCase as PytorchTestCase +import torchaudio +from torchaudio._internal.module_utils import is_module_available + +from .backend_utils import set_audio_backend + + +class TempDirMixin: + """Mixin to provide easy access to temp dir""" + temp_dir_ = None + base_temp_dir = None + temp_dir = None + + @classmethod + def setUpClass(cls): + super().setUpClass() + # If TORCHAUDIO_TEST_TEMP_DIR is set, use it instead of temporary directory. + # this is handy for debugging. + key = 'TORCHAUDIO_TEST_TEMP_DIR' + if key in os.environ: + cls.base_temp_dir = os.environ[key] + else: + cls.temp_dir_ = tempfile.TemporaryDirectory() + cls.base_temp_dir = cls.temp_dir_.name + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + if isinstance(cls.temp_dir_, tempfile.TemporaryDirectory): + cls.temp_dir_.cleanup() + + def setUp(self): + super().setUp() + self.temp_dir = os.path.join(self.base_temp_dir, self.id()) + + def get_temp_path(self, *paths): + path = os.path.join(self.temp_dir, *paths) + os.makedirs(os.path.dirname(path), exist_ok=True) + return path + + +class TestBaseMixin: + """Mixin to provide consistent way to define device/dtype/backend aware TestCase""" + dtype = None + device = None + backend = None + + def setUp(self): + super().setUp() + set_audio_backend(self.backend) + + +class TorchaudioTestCase(TestBaseMixin, PytorchTestCase): + pass + + +def skipIfNoExec(cmd): + return unittest.skipIf(shutil.which(cmd) is None, f'`{cmd}` is not available') + + +def skipIfNoModule(module, display_name=None): + display_name = display_name or module + return unittest.skipIf(not is_module_available(module), f'"{display_name}" is not available') + + +skipIfNoSoxBackend = unittest.skipIf( + 'sox' not in torchaudio.list_audio_backends(), 'Sox backend not available') +skipIfNoCuda = unittest.skipIf(not torch.cuda.is_available(), reason='CUDA not available') +skipIfNoExtension = skipIfNoModule('torchaudio._torchaudio', 'torchaudio C++ extension') diff --git a/test/common_utils/data_utils.py b/test/common_utils/data_utils.py new file mode 100644 index 0000000000..b948ce334a --- /dev/null +++ b/test/common_utils/data_utils.py @@ -0,0 +1,94 @@ +import os.path +from typing import Union + +import torch + + +_TEST_DIR_PATH = os.path.realpath( + os.path.join(os.path.dirname(__file__), '..')) + + +def get_asset_path(*paths): + """Return full path of a test asset""" + return os.path.join(_TEST_DIR_PATH, 'assets', *paths) + + +def get_whitenoise( + *, + sample_rate: int = 16000, + duration: float = 1, # seconds + n_channels: int = 1, + seed: int = 0, + dtype: Union[str, torch.dtype] = "float32", + device: Union[str, torch.device] = "cpu", + channels_first=True, + scale_factor: float = 1, +): + """Generate pseudo audio data with whitenoise + Args: + sample_rate: Sampling rate + duration: Length of the resulting Tensor in seconds. + n_channels: Number of channels + seed: Seed value used for random number generation. + Note that this function does not modify global random generator state. + dtype: Torch dtype + device: device + channels_first: whether first dimension is n_channels + scale_factor: scale the Tensor before clamping and quantization + Returns: + Tensor: shape of (n_channels, sample_rate * duration) + """ + if isinstance(dtype, str): + dtype = getattr(torch, dtype) + if dtype not in [torch.float32, torch.int32, torch.int16, torch.uint8]: + raise NotImplementedError(f'dtype {dtype} is not supported.') + # According to the doc, folking rng on all CUDA devices is slow when there are many CUDA devices, + # so we only folk on CPU, generate values and move the data to the given device + with torch.random.fork_rng([]): + torch.random.manual_seed(seed) + tensor = torch.randn([sample_rate * duration], dtype=torch.float32, device='cpu') + tensor /= 2.0 + tensor *= scale_factor + tensor.clamp_(-1.0, 1.0) + if dtype == torch.int32: + tensor *= (tensor > 0) * 2147483647 + (tensor < 0) * 2147483648 + if dtype == torch.int16: + tensor *= (tensor > 0) * 32767 + (tensor < 0) * 32768 + if dtype == torch.uint8: + tensor *= (tensor > 0) * 127 + (tensor < 0) * 128 + tensor += 128 + tensor = tensor.to(dtype) + tensor = tensor.repeat([n_channels, 1]) + if not channels_first: + tensor = tensor.t() + return tensor.to(device=device) + + +def get_sinusoid( + *, + frequency: float = 300, + sample_rate: int = 16000, + duration: float = 1, # seconds + n_channels: int = 1, + dtype: Union[str, torch.dtype] = "float32", + device: Union[str, torch.device] = "cpu", +): + """Generate pseudo audio data with sine wave. + + Args: + frequency: Frequency of sine wave + sample_rate: Sampling rate + duration: Length of the resulting Tensor in seconds. + n_channels: Number of channels + dtype: Torch dtype + device: device + + Returns: + Tensor: shape of (n_channels, sample_rate * duration) + """ + if isinstance(dtype, str): + dtype = getattr(torch, dtype) + pie2 = 2 * 3.141592653589793 + end = pie2 * frequency * duration + theta = torch.linspace(0, end, sample_rate * duration, dtype=dtype, device=device) + return torch.sin(theta, out=None).repeat([n_channels, 1]) diff --git a/test/common_utils/parameterized_utils.py b/test/common_utils/parameterized_utils.py new file mode 100644 index 0000000000..24404a6edd --- /dev/null +++ b/test/common_utils/parameterized_utils.py @@ -0,0 +1,10 @@ +import json + +from parameterized import param + +from .data_utils import get_asset_path + + +def load_params(*paths): + with open(get_asset_path(*paths), 'r') as file: + return [param(json.loads(line)) for line in file] diff --git a/test/common_utils/sox_utils.py b/test/common_utils/sox_utils.py new file mode 100644 index 0000000000..cd1c247b72 --- /dev/null +++ b/test/common_utils/sox_utils.py @@ -0,0 +1,79 @@ +import subprocess + + +def get_encoding(dtype): + encodings = { + 'float32': 'floating-point', + 'int32': 'signed-integer', + 'int16': 'signed-integer', + 'uint8': 'unsigned-integer', + } + return encodings[dtype] + + +def get_bit_depth(dtype): + bit_depths = { + 'float32': 32, + 'int32': 32, + 'int16': 16, + 'uint8': 8, + } + return bit_depths[dtype] + + +def gen_audio_file( + path, sample_rate, num_channels, + *, encoding=None, bit_depth=None, compression=None, attenuation=None, duration=1, +): + """Generate synthetic audio file with `sox` command.""" + if path.endswith('.wav'): + raise RuntimeError( + 'Use get_wav_data and save_wav to generate wav file for accurate result.') + command = [ + 'sox', + '-V3', # verbose + '-R', + # -R is supposed to be repeatable, though the implementation looks suspicious + # and not setting the seed to a fixed value. + # https://fossies.org/dox/sox-14.4.2/sox_8c_source.html + # search "sox_globals.repeatable" + ] + if bit_depth is not None: + command += ['--bits', str(bit_depth)] + command += [ + '--rate', str(sample_rate), + '--null', # no input + '--channels', str(num_channels), + ] + if compression is not None: + command += ['--compression', str(compression)] + if bit_depth is not None: + command += ['--bits', str(bit_depth)] + if encoding is not None: + command += ['--encoding', str(encoding)] + command += [ + str(path), + 'synth', str(duration), # synthesizes for the given duration [sec] + 'sawtooth', '1', + # saw tooth covers the both ends of value range, which is a good property for test. + # similar to linspace(-1., 1.) + # this introduces bigger boundary effect than sine when converted to mp3 + ] + if attenuation is not None: + command += ['vol', f'-{attenuation}dB'] + print(' '.join(command)) + subprocess.run(command, check=True) + + +def convert_audio_file( + src_path, dst_path, + *, bit_depth=None, compression=None): + """Convert audio file with `sox` command.""" + command = ['sox', '-V3', '-R', str(src_path)] + if bit_depth is not None: + command += ['--bits', str(bit_depth)] + if compression is not None: + command += ['--compression', str(compression)] + command += [dst_path] + print(' '.join(command)) + subprocess.run(command, check=True) diff --git a/test/common_utils/wav_utils.py b/test/common_utils/wav_utils.py new file mode 100644 index 0000000000..bc122ec6cb --- /dev/null +++ b/test/common_utils/wav_utils.py @@ -0,0 +1,86 @@ +from typing import Optional + +import torch +import scipy.io.wavfile + + +def normalize_wav(tensor: torch.Tensor) -> torch.Tensor: + if tensor.dtype == torch.float32: + pass + elif tensor.dtype == torch.int32: + tensor = tensor.to(torch.float32) + tensor[tensor > 0] /= 2147483647. + tensor[tensor < 0] /= 2147483648. + elif tensor.dtype == torch.int16: + tensor = tensor.to(torch.float32) + tensor[tensor > 0] /= 32767. + tensor[tensor < 0] /= 32768. + elif tensor.dtype == torch.uint8: + tensor = tensor.to(torch.float32) - 128 + tensor[tensor > 0] /= 127. + tensor[tensor < 0] /= 128. + return tensor + + +def get_wav_data( + dtype: str, + num_channels: int, + *, + num_frames: Optional[int] = None, + normalize: bool = True, + channels_first: bool = True, +): + """Generate linear signal of the given dtype and num_channels + + Data range is + [-1.0, 1.0] for float32, + [-2147483648, 2147483647] for int32 + [-32768, 32767] for int16 + [0, 255] for uint8 + + num_frames allow to change the linear interpolation parameter. + Default values are 256 for uint8, else 1 << 16. + 1 << 16 as default is so that int16 value range is completely covered. + """ + dtype_ = getattr(torch, dtype) + + if num_frames is None: + if dtype == 'uint8': + num_frames = 256 + else: + num_frames = 1 << 16 + + if dtype == 'uint8': + base = torch.linspace(0, 255, num_frames, dtype=dtype_) + if dtype == 'float32': + base = torch.linspace(-1., 1., num_frames, dtype=dtype_) + if dtype == 'int32': + base = torch.linspace(-2147483648, 2147483647, num_frames, dtype=dtype_) + if dtype == 'int16': + base = torch.linspace(-32768, 32767, num_frames, dtype=dtype_) + data = base.repeat([num_channels, 1]) + if not channels_first: + data = data.transpose(1, 0) + if normalize: + data = normalize_wav(data) + return data + + +def load_wav(path: str, normalize=True, channels_first=True) -> torch.Tensor: + """Load wav file without torchaudio""" + sample_rate, data = scipy.io.wavfile.read(path) + data = torch.from_numpy(data.copy()) + if data.ndim == 1: + data = data.unsqueeze(1) + if normalize: + data = normalize_wav(data) + if channels_first: + data = data.transpose(1, 0) + return data, sample_rate + + +def save_wav(path, data, sample_rate, channels_first=True): + """Save wav file without torchaudio""" + if channels_first: + data = data.transpose(1, 0) + scipy.io.wavfile.write(path, sample_rate, data.numpy()) diff --git a/test/functional_cpu_test.py b/test/functional_cpu_test.py index 470d6ab770..ab5fdaed95 100644 --- a/test/functional_cpu_test.py +++ b/test/functional_cpu_test.py @@ -10,6 +10,31 @@ from .functional_impl import Lfilter +def random_float_tensor(seed, size, a=22695477, c=1, m=2 ** 32): + """ Generates random tensors given a seed and size + https://en.wikipedia.org/wiki/Linear_congruential_generator + X_{n + 1} = (a * X_n + c) % m + Using Borland C/C++ values + + The tensor will have values between [0,1) + Inputs: + seed (int): an int + size (Tuple[int]): the size of the output tensor + a (int): the multiplier constant to the generator + c (int): the additive constant to the generator + m (int): the modulus constant to the generator + """ + num_elements = 1 + for s in size: + num_elements *= s + + arr = [(a * seed + c) % m] + for i in range(num_elements - 1): + arr.append((a * arr[i] + c) % m) + + return torch.tensor(arr).float().view(size) / m + + class TestLFilterFloat32(Lfilter, common_utils.PytorchTestCase): dtype = torch.float32 device = torch.device('cpu') @@ -49,7 +74,7 @@ def _test_istft_is_inverse_of_stft(kwargs): for data_size in [(2, 20), (3, 15), (4, 10)]: for i in range(100): - sound = common_utils.random_float_tensor(i, data_size) + sound = random_float_tensor(i, data_size) stft = torch.stft(sound, **kwargs) estimate = torchaudio.functional.istft(stft, length=sound.size(1), **kwargs) @@ -211,8 +236,8 @@ def test_istft_of_sine(self): def _test_linearity_of_istft(self, data_size, kwargs, atol=1e-6, rtol=1e-8): for i in range(self.number_of_trials): - tensor1 = common_utils.random_float_tensor(i, data_size) - tensor2 = common_utils.random_float_tensor(i * 2, data_size) + tensor1 = random_float_tensor(i, data_size) + tensor2 = random_float_tensor(i * 2, data_size) a, b = torch.rand(2) istft1 = torchaudio.functional.istft(tensor1, **kwargs) istft2 = torchaudio.functional.istft(tensor2, **kwargs) @@ -274,8 +299,6 @@ def test_linearity_of_istft4(self): class TestDetectPitchFrequency(common_utils.TorchaudioTestCase): - backend = 'default' - def test_pitch(self): test_filepath_100 = common_utils.get_asset_path("100Hz_44100Hz_16bit_05sec.wav") test_filepath_440 = common_utils.get_asset_path("440Hz_44100Hz_16bit_05sec.wav") @@ -287,7 +310,7 @@ def test_pitch(self): ] for filename, freq_ref in tests: - waveform, sample_rate = torchaudio.load(filename) + waveform, sample_rate = common_utils.load_wav(filename) freq = torchaudio.functional.detect_pitch_frequency(waveform, sample_rate) diff --git a/test/kaldi_compatibility_impl.py b/test/kaldi_compatibility_impl.py index ec58a3fa44..7e51620f63 100644 --- a/test/kaldi_compatibility_impl.py +++ b/test/kaldi_compatibility_impl.py @@ -1,20 +1,19 @@ """Test suites for checking numerical compatibility against Kaldi""" -import json -import shutil -import unittest import subprocess import kaldi_io import torch import torchaudio.functional as F import torchaudio.compliance.kaldi +from parameterized import parameterized -from . import common_utils -from parameterized import parameterized, param - - -def _not_available(cmd): - return shutil.which(cmd) is None +from .common_utils import ( + TestBaseMixin, + load_params, + skipIfNoExec, + get_asset_path, + load_wav +) def _convert_args(**kwargs): @@ -49,19 +48,12 @@ def _run_kaldi(command, input_type, input_value): return torch.from_numpy(result.copy()) # copy supresses some torch warning -def _load_params(path): - with open(path, 'r') as file: - return [param(json.loads(line)) for line in file] - - -class Kaldi(common_utils.TestBaseMixin): - backend = 'sox' - +class Kaldi(TestBaseMixin): def assert_equal(self, output, *, expected, rtol=None, atol=None): expected = expected.to(dtype=self.dtype, device=self.device) self.assertEqual(output, expected, rtol=rtol, atol=atol) - @unittest.skipIf(_not_available('apply-cmvn-sliding'), '`apply-cmvn-sliding` not available') + @skipIfNoExec('apply-cmvn-sliding') def test_sliding_window_cmn(self): """sliding_window_cmn should be numerically compatible with apply-cmvn-sliding""" kwargs = { @@ -77,34 +69,34 @@ def test_sliding_window_cmn(self): kaldi_result = _run_kaldi(command, 'ark', tensor) self.assert_equal(result, expected=kaldi_result) - @parameterized.expand(_load_params(common_utils.get_asset_path('kaldi_test_fbank_args.json'))) - @unittest.skipIf(_not_available('compute-fbank-feats'), '`compute-fbank-feats` not available') + @parameterized.expand(load_params('kaldi_test_fbank_args.json')) + @skipIfNoExec('compute-fbank-feats') def test_fbank(self, kwargs): """fbank should be numerically compatible with compute-fbank-feats""" - wave_file = common_utils.get_asset_path('kaldi_file.wav') - waveform = torchaudio.load_wav(wave_file)[0].to(dtype=self.dtype, device=self.device) + wave_file = get_asset_path('kaldi_file.wav') + waveform = load_wav(wave_file, normalize=False)[0].to(dtype=self.dtype, device=self.device) result = torchaudio.compliance.kaldi.fbank(waveform, **kwargs) command = ['compute-fbank-feats'] + _convert_args(**kwargs) + ['scp:-', 'ark:-'] kaldi_result = _run_kaldi(command, 'scp', wave_file) self.assert_equal(result, expected=kaldi_result, rtol=1e-4, atol=1e-8) - @parameterized.expand(_load_params(common_utils.get_asset_path('kaldi_test_spectrogram_args.json'))) - @unittest.skipIf(_not_available('compute-spectrogram-feats'), '`compute-spectrogram-feats` not available') + @parameterized.expand(load_params('kaldi_test_spectrogram_args.json')) + @skipIfNoExec('compute-spectrogram-feats') def test_spectrogram(self, kwargs): """spectrogram should be numerically compatible with compute-spectrogram-feats""" - wave_file = common_utils.get_asset_path('kaldi_file.wav') - waveform = torchaudio.load_wav(wave_file)[0].to(dtype=self.dtype, device=self.device) + wave_file = get_asset_path('kaldi_file.wav') + waveform = load_wav(wave_file, normalize=False)[0].to(dtype=self.dtype, device=self.device) result = torchaudio.compliance.kaldi.spectrogram(waveform, **kwargs) command = ['compute-spectrogram-feats'] + _convert_args(**kwargs) + ['scp:-', 'ark:-'] kaldi_result = _run_kaldi(command, 'scp', wave_file) self.assert_equal(result, expected=kaldi_result, rtol=1e-4, atol=1e-8) - @parameterized.expand(_load_params(common_utils.get_asset_path('kaldi_test_mfcc_args.json'))) - @unittest.skipIf(_not_available('compute-mfcc-feats'), '`compute-mfcc-feats` not available') + @parameterized.expand(load_params('kaldi_test_mfcc_args.json')) + @skipIfNoExec('compute-mfcc-feats') def test_mfcc(self, kwargs): """mfcc should be numerically compatible with compute-mfcc-feats""" - wave_file = common_utils.get_asset_path('kaldi_file.wav') - waveform = torchaudio.load_wav(wave_file)[0].to(dtype=self.dtype, device=self.device) + wave_file = get_asset_path('kaldi_file.wav') + waveform = load_wav(wave_file, normalize=False)[0].to(dtype=self.dtype, device=self.device) result = torchaudio.compliance.kaldi.mfcc(waveform, **kwargs) command = ['compute-mfcc-feats'] + _convert_args(**kwargs) + ['scp:-', 'ark:-'] kaldi_result = _run_kaldi(command, 'scp', wave_file) diff --git a/test/sox_io_backend/__init__.py b/test/sox_io_backend/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/sox_io_backend/common.py b/test/sox_io_backend/common.py new file mode 100644 index 0000000000..eb85937236 --- /dev/null +++ b/test/sox_io_backend/common.py @@ -0,0 +1,2 @@ +def name_func(func, _, params): + return f'{func.__name__}_{"_".join(str(arg) for arg in params.args)}' diff --git a/test/sox_io_backend/test_info.py b/test/sox_io_backend/test_info.py new file mode 100644 index 0000000000..da5207a7e5 --- /dev/null +++ b/test/sox_io_backend/test_info.py @@ -0,0 +1,125 @@ +import itertools +from parameterized import parameterized + +from torchaudio.backend import sox_io_backend + +from ..common_utils import ( + TempDirMixin, + PytorchTestCase, + skipIfNoExec, + skipIfNoExtension, + get_asset_path, + get_wav_data, + save_wav, + sox_utils, +) +from .common import ( + name_func, +) + + +@skipIfNoExec('sox') +@skipIfNoExtension +class TestInfo(TempDirMixin, PytorchTestCase): + @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): + """`sox_io_backend.info` can check wav file correctly""" + duration = 1 + path = self.get_temp_path('data.wav') + data = get_wav_data(dtype, num_channels, normalize=False, num_frames=duration * sample_rate) + save_wav(path, data, sample_rate) + info = sox_io_backend.info(path) + assert info.sample_rate == sample_rate + assert info.num_frames == sample_rate * duration + assert info.num_channels == num_channels + + @parameterized.expand(list(itertools.product( + ['float32', 'int32', 'int16', 'uint8'], + [8000, 16000], + [4, 8, 16, 32], + )), name_func=name_func) + def test_wav_multiple_channels(self, dtype, sample_rate, num_channels): + """`sox_io_backend.info` can check wav file with channels more than 2 correctly""" + duration = 1 + path = self.get_temp_path('data.wav') + data = get_wav_data(dtype, num_channels, normalize=False, num_frames=duration * sample_rate) + save_wav(path, data, sample_rate) + info = sox_io_backend.info(path) + assert info.sample_rate == sample_rate + assert info.num_frames == sample_rate * duration + assert info.num_channels == num_channels + + @parameterized.expand(list(itertools.product( + [8000, 16000], + [1, 2], + [96, 128, 160, 192, 224, 256, 320], + )), name_func=name_func) + def test_mp3(self, sample_rate, num_channels, bit_rate): + """`sox_io_backend.info` can check mp3 file correctly""" + duration = 1 + path = self.get_temp_path('data.mp3') + sox_utils.gen_audio_file( + path, sample_rate, num_channels, + compression=bit_rate, duration=duration, + ) + info = sox_io_backend.info(path) + assert info.sample_rate == sample_rate + # mp3 does not preserve the number of samples + # assert info.num_frames == sample_rate * duration + assert info.num_channels == num_channels + + @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): + """`sox_io_backend.info` can check flac file correctly""" + duration = 1 + path = self.get_temp_path('data.flac') + sox_utils.gen_audio_file( + path, sample_rate, num_channels, + compression=compression_level, duration=duration, + ) + info = sox_io_backend.info(path) + assert info.sample_rate == sample_rate + assert info.num_frames == sample_rate * duration + assert info.num_channels == num_channels + + @parameterized.expand(list(itertools.product( + [8000, 16000], + [1, 2], + [-1, 0, 1, 2, 3, 3.6, 5, 10], + )), name_func=name_func) + def test_vorbis(self, sample_rate, num_channels, quality_level): + """`sox_io_backend.info` can check vorbis file correctly""" + duration = 1 + path = self.get_temp_path('data.vorbis') + sox_utils.gen_audio_file( + path, sample_rate, num_channels, + compression=quality_level, duration=duration, + ) + info = sox_io_backend.info(path) + assert info.sample_rate == sample_rate + assert info.num_frames == sample_rate * duration + assert info.num_channels == num_channels + + +@skipIfNoExtension +class TestInfoOpus(PytorchTestCase): + @parameterized.expand(list(itertools.product( + ['96k'], + [1, 2], + [0, 5, 10], + )), name_func=name_func) + def test_opus(self, bitrate, num_channels, compression_level): + """`sox_io_backend.info` can check opus file correcty""" + path = get_asset_path('io', f'{bitrate}_{compression_level}_{num_channels}ch.opus') + info = sox_io_backend.info(path) + assert info.sample_rate == 48000 + assert info.num_frames == 32768 + assert info.num_channels == num_channels diff --git a/test/sox_io_backend/test_load.py b/test/sox_io_backend/test_load.py new file mode 100644 index 0000000000..8366a01f83 --- /dev/null +++ b/test/sox_io_backend/test_load.py @@ -0,0 +1,263 @@ +import itertools + +from torchaudio.backend import sox_io_backend +from parameterized import parameterized + +from ..common_utils import ( + TempDirMixin, + PytorchTestCase, + skipIfNoExec, + skipIfNoExtension, + get_asset_path, + get_wav_data, + load_wav, + save_wav, + sox_utils, +) +from .common import ( + name_func, +) + + +class LoadTestBase(TempDirMixin, PytorchTestCase): + def assert_wav(self, dtype, sample_rate, num_channels, normalize, duration): + """`sox_io_backend.load` can load wav format correctly. + + Wav data loaded with sox_io backend should match those with scipy + """ + path = self.get_temp_path('reference.wav') + data = get_wav_data(dtype, num_channels, normalize=normalize, num_frames=duration * sample_rate) + save_wav(path, data, sample_rate) + expected = load_wav(path, normalize=normalize)[0] + data, sr = sox_io_backend.load(path, normalize=normalize) + assert sr == sample_rate + self.assertEqual(data, expected) + + def assert_mp3(self, sample_rate, num_channels, bit_rate, duration): + """`sox_io_backend.load` can load mp3 format. + + mp3 encoding introduces delay and boundary effects so + we create reference wav file from mp3 + + x + | + | 1. Generate mp3 with Sox + | + v 2. Convert to wav with Sox + mp3 ------------------------------> wav + | | + | 3. Load with torchaudio | 4. Load with scipy + | | + v v + tensor ----------> x <----------- tensor + 5. Compare + + Underlying assumptions are; + i. Conversion of mp3 to wav with Sox preserves data. + ii. Loading wav file with scipy is correct. + + By combining i & ii, step 2. and 4. allows to load reference mp3 data + without using torchaudio + """ + path = self.get_temp_path('1.original.mp3') + ref_path = self.get_temp_path('2.reference.wav') + + # 1. Generate mp3 with sox + sox_utils.gen_audio_file( + path, sample_rate, num_channels, + compression=bit_rate, duration=duration) + # 2. Convert to wav with sox + sox_utils.convert_audio_file(path, ref_path) + # 3. Load mp3 with torchaudio + data, sr = sox_io_backend.load(path) + # 4. Load wav with scipy + data_ref = load_wav(ref_path)[0] + # 5. Compare + assert sr == sample_rate + self.assertEqual(data, data_ref, atol=3e-03, rtol=1.3e-06) + + def assert_flac(self, sample_rate, num_channels, compression_level, duration): + """`sox_io_backend.load` can load flac format. + + This test takes the same strategy as mp3 to compare the result + """ + path = self.get_temp_path('1.original.flac') + ref_path = self.get_temp_path('2.reference.wav') + + # 1. Generate flac with sox + sox_utils.gen_audio_file( + path, sample_rate, num_channels, + compression=compression_level, bit_depth=16, duration=duration) + # 2. Convert to wav with sox + sox_utils.convert_audio_file(path, ref_path) + # 3. Load flac with torchaudio + data, sr = sox_io_backend.load(path) + # 4. Load wav with scipy + data_ref = load_wav(ref_path)[0] + # 5. Compare + assert sr == sample_rate + self.assertEqual(data, data_ref, atol=4e-05, rtol=1.3e-06) + + def assert_vorbis(self, sample_rate, num_channels, quality_level, duration): + """`sox_io_backend.load` can load vorbis format. + + This test takes the same strategy as mp3 to compare the result + """ + path = self.get_temp_path('1.original.vorbis') + ref_path = self.get_temp_path('2.reference.wav') + + # 1. Generate vorbis with sox + sox_utils.gen_audio_file( + path, sample_rate, num_channels, + compression=quality_level, bit_depth=16, duration=duration) + # 2. Convert to wav with sox + sox_utils.convert_audio_file(path, ref_path) + # 3. Load vorbis with torchaudio + data, sr = sox_io_backend.load(path) + # 4. Load wav with scipy + data_ref = load_wav(ref_path)[0] + # 5. Compare + assert sr == sample_rate + self.assertEqual(data, data_ref, atol=4e-05, rtol=1.3e-06) + + +@skipIfNoExec('sox') +@skipIfNoExtension +class TestLoad(LoadTestBase): + """Test the correctness of `sox_io_backend.load` for various formats""" + @parameterized.expand(list(itertools.product( + ['float32', 'int32', 'int16', 'uint8'], + [8000, 16000], + [1, 2], + [False, True], + )), name_func=name_func) + def test_wav(self, dtype, sample_rate, num_channels, normalize): + """`sox_io_backend.load` can load wav format correctly.""" + self.assert_wav(dtype, sample_rate, num_channels, normalize, duration=1) + + @parameterized.expand(list(itertools.product( + ['int16'], + [16000], + [2], + [False], + )), name_func=name_func) + def test_wav_large(self, dtype, sample_rate, num_channels, normalize): + """`sox_io_backend.load` can load large wav file correctly.""" + two_hours = 2 * 60 * 60 + self.assert_wav(dtype, sample_rate, num_channels, normalize, two_hours) + + @parameterized.expand(list(itertools.product( + ['float32', 'int32', 'int16', 'uint8'], + [4, 8, 16, 32], + )), name_func=name_func) + def test_multiple_channels(self, dtype, num_channels): + """`sox_io_backend.load` can load wav file with more than 2 channels.""" + sample_rate = 8000 + normalize = False + self.assert_wav(dtype, sample_rate, num_channels, normalize, duration=1) + + @parameterized.expand(list(itertools.product( + [8000, 16000, 44100], + [1, 2], + [96, 128, 160, 192, 224, 256, 320], + )), name_func=name_func) + def test_mp3(self, sample_rate, num_channels, bit_rate): + """`sox_io_backend.load` can load mp3 format correctly.""" + self.assert_mp3(sample_rate, num_channels, bit_rate, duration=1) + + @parameterized.expand(list(itertools.product( + [16000], + [2], + [128], + )), name_func=name_func) + def test_mp3_large(self, sample_rate, num_channels, bit_rate): + """`sox_io_backend.load` can load large mp3 file correctly.""" + two_hours = 2 * 60 * 60 + self.assert_mp3(sample_rate, num_channels, bit_rate, two_hours) + + @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): + """`sox_io_backend.load` can load flac format correctly.""" + self.assert_flac(sample_rate, num_channels, compression_level, duration=1) + + @parameterized.expand(list(itertools.product( + [16000], + [2], + [0], + )), name_func=name_func) + def test_flac_large(self, sample_rate, num_channels, compression_level): + """`sox_io_backend.load` can load large flac file correctly.""" + two_hours = 2 * 60 * 60 + self.assert_flac(sample_rate, num_channels, compression_level, two_hours) + + @parameterized.expand(list(itertools.product( + [8000, 16000], + [1, 2], + [-1, 0, 1, 2, 3, 3.6, 5, 10], + )), name_func=name_func) + def test_vorbis(self, sample_rate, num_channels, quality_level): + """`sox_io_backend.load` can load vorbis format correctly.""" + self.assert_vorbis(sample_rate, num_channels, quality_level, duration=1) + + @parameterized.expand(list(itertools.product( + [16000], + [2], + [10], + )), name_func=name_func) + def test_vorbis_large(self, sample_rate, num_channels, quality_level): + """`sox_io_backend.load` can load large vorbis file correctly.""" + two_hours = 2 * 60 * 60 + self.assert_vorbis(sample_rate, num_channels, quality_level, two_hours) + + @parameterized.expand(list(itertools.product( + ['96k'], + [1, 2], + [0, 5, 10], + )), name_func=name_func) + def test_opus(self, bitrate, num_channels, compression_level): + """`sox_io_backend.load` can load opus file correctly.""" + ops_path = get_asset_path('io', f'{bitrate}_{compression_level}_{num_channels}ch.opus') + wav_path = self.get_temp_path(f'{bitrate}_{compression_level}_{num_channels}ch.opus.wav') + sox_utils.convert_audio_file(ops_path, wav_path) + + expected, sample_rate = load_wav(wav_path) + found, sr = sox_io_backend.load(ops_path) + + assert sample_rate == sr + self.assertEqual(expected, found) + + +@skipIfNoExec('sox') +@skipIfNoExtension +class TestLoadParams(TempDirMixin, PytorchTestCase): + """Test the correctness of frame parameters of `sox_io_backend.load`""" + original = None + path = None + + def setUp(self): + super().setUp() + sample_rate = 8000 + self.original = get_wav_data('float32', num_channels=2) + self.path = self.get_temp_path('test.wave') + save_wav(self.path, self.original, sample_rate) + + @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""" + found, _ = sox_io_backend.load(self.path, frame_offset, num_frames) + frame_end = None if num_frames == -1 else frame_offset + num_frames + self.assertEqual(found, self.original[:, frame_offset:frame_end]) + + @parameterized.expand([(True, ), (False, )], name_func=name_func) + def test_channels_first(self, channels_first): + """channels_first swaps axes""" + found, _ = sox_io_backend.load(self.path, channels_first=channels_first) + expected = self.original if channels_first else self.original.transpose(1, 0) + self.assertEqual(found, expected) diff --git a/test/sox_io_backend/test_roundtrip.py b/test/sox_io_backend/test_roundtrip.py new file mode 100644 index 0000000000..2a051bebd5 --- /dev/null +++ b/test/sox_io_backend/test_roundtrip.py @@ -0,0 +1,52 @@ +import itertools + +from torchaudio.backend import sox_io_backend +from parameterized import parameterized + +from ..common_utils import ( + TempDirMixin, + PytorchTestCase, + skipIfNoExec, + skipIfNoExtension, + get_wav_data, +) +from .common import ( + name_func, +) + + +@skipIfNoExec('sox') +@skipIfNoExtension +class TestRoundTripIO(TempDirMixin, PytorchTestCase): + """save/load round trip should not degrade data for lossless formats""" + @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): + """save/load round trip should not degrade data for wav formats""" + original = get_wav_data(dtype, num_channels, normalize=False) + data = original + for i in range(10): + path = self.get_temp_path(f'{i}.wav') + sox_io_backend.save(path, data, sample_rate) + data, sr = sox_io_backend.load(path, normalize=False) + assert sr == sample_rate + self.assertEqual(original, data) + + @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): + """save/load round trip should not degrade data for flac formats""" + original = get_wav_data('float32', num_channels) + data = original + for i in range(10): + path = self.get_temp_path(f'{i}.flac') + sox_io_backend.save(path, data, sample_rate, compression=compression_level) + data, sr = sox_io_backend.load(path) + assert sr == sample_rate + self.assertEqual(original, data) diff --git a/test/sox_io_backend/test_save.py b/test/sox_io_backend/test_save.py new file mode 100644 index 0000000000..53588c456b --- /dev/null +++ b/test/sox_io_backend/test_save.py @@ -0,0 +1,304 @@ +import itertools + +from torchaudio.backend import sox_io_backend +from parameterized import parameterized + +from ..common_utils import ( + TempDirMixin, + PytorchTestCase, + skipIfNoExec, + skipIfNoExtension, + get_wav_data, + load_wav, + save_wav, + sox_utils, +) +from .common import ( + name_func, +) + + +class SaveTestBase(TempDirMixin, PytorchTestCase): + def assert_wav(self, dtype, sample_rate, num_channels, num_frames): + """`sox_io_backend.save` can save wav format.""" + path = self.get_temp_path('data.wav') + expected = get_wav_data(dtype, num_channels, num_frames=num_frames) + sox_io_backend.save(path, expected, sample_rate) + found, sr = load_wav(path) + assert sample_rate == sr + self.assertEqual(found, expected) + + def assert_mp3(self, sample_rate, num_channels, bit_rate, duration): + """`sox_io_backend.save` can save mp3 format. + + mp3 encoding introduces delay and boundary effects so + we convert the resulting mp3 to wav and compare the results there + + | + | 1. Generate original wav file with SciPy + | + v + -------------- wav ---------------- + | | + | 2.1. load with scipy | 3.1. Convert to mp3 with Sox + | then save with torchaudio | + v v + mp3 mp3 + | | + | 2.2. Convert to wav with Sox | 3.2. Convert to wav with Sox + | | + v v + wav wav + | | + | 2.3. load with scipy | 3.3. load with scipy + | | + v v + tensor -------> compare <--------- tensor + + """ + src_path = self.get_temp_path('1.reference.wav') + mp3_path = self.get_temp_path('2.1.torchaudio.mp3') + wav_path = self.get_temp_path('2.2.torchaudio.wav') + mp3_path_sox = self.get_temp_path('3.1.sox.mp3') + wav_path_sox = self.get_temp_path('3.2.sox.wav') + + # 1. Generate original wav + data = get_wav_data('float32', num_channels, normalize=True, num_frames=duration * sample_rate) + save_wav(src_path, data, sample_rate) + # 2.1. Convert the original wav to mp3 with torchaudio + sox_io_backend.save( + mp3_path, load_wav(src_path)[0], sample_rate, compression=bit_rate) + # 2.2. Convert the mp3 to wav with Sox + sox_utils.convert_audio_file(mp3_path, wav_path) + # 2.3. Load + found = load_wav(wav_path)[0] + + # 3.1. Convert the original wav to mp3 with SoX + sox_utils.convert_audio_file(src_path, mp3_path_sox, compression=bit_rate) + # 3.2. Convert the mp3 to wav with Sox + sox_utils.convert_audio_file(mp3_path_sox, wav_path_sox) + # 3.3. Load + expected = load_wav(wav_path_sox)[0] + + self.assertEqual(found, expected) + + def assert_flac(self, sample_rate, num_channels, compression_level, duration): + """`sox_io_backend.save` can save flac format. + + This test takes the same strategy as mp3 to compare the result + """ + src_path = self.get_temp_path('1.reference.wav') + flc_path = self.get_temp_path('2.1.torchaudio.flac') + wav_path = self.get_temp_path('2.2.torchaudio.wav') + flc_path_sox = self.get_temp_path('3.1.sox.flac') + wav_path_sox = self.get_temp_path('3.2.sox.wav') + + # 1. Generate original wav + data = get_wav_data('float32', num_channels, normalize=True, num_frames=duration * sample_rate) + save_wav(src_path, data, sample_rate) + # 2.1. Convert the original wav to flac with torchaudio + sox_io_backend.save( + flc_path, load_wav(src_path)[0], sample_rate, compression=compression_level) + # 2.2. Convert the flac to wav with Sox + # converting to 32 bit because flac file has 24 bit depth which scipy cannot handle. + sox_utils.convert_audio_file(flc_path, wav_path, bit_depth=32) + # 2.3. Load + found = load_wav(wav_path)[0] + + # 3.1. Convert the original wav to flac with SoX + sox_utils.convert_audio_file(src_path, flc_path_sox, compression=compression_level) + # 3.2. Convert the flac to wav with Sox + # converting to 32 bit because flac file has 24 bit depth which scipy cannot handle. + sox_utils.convert_audio_file(flc_path_sox, wav_path_sox, bit_depth=32) + # 3.3. Load + expected = load_wav(wav_path_sox)[0] + + self.assertEqual(found, expected) + + def _assert_vorbis(self, sample_rate, num_channels, quality_level, duration): + """`sox_io_backend.save` can save vorbis format. + + This test takes the same strategy as mp3 to compare the result + """ + src_path = self.get_temp_path('1.reference.wav') + vbs_path = self.get_temp_path('2.1.torchaudio.vorbis') + wav_path = self.get_temp_path('2.2.torchaudio.wav') + vbs_path_sox = self.get_temp_path('3.1.sox.vorbis') + wav_path_sox = self.get_temp_path('3.2.sox.wav') + + # 1. Generate original wav + data = get_wav_data('int16', num_channels, normalize=False, num_frames=duration * sample_rate) + save_wav(src_path, data, sample_rate) + # 2.1. Convert the original wav to vorbis with torchaudio + sox_io_backend.save( + vbs_path, load_wav(src_path)[0], sample_rate, compression=quality_level) + # 2.2. Convert the vorbis to wav with Sox + sox_utils.convert_audio_file(vbs_path, wav_path) + # 2.3. Load + found = load_wav(wav_path)[0] + + # 3.1. Convert the original wav to vorbis with SoX + sox_utils.convert_audio_file(src_path, vbs_path_sox, compression=quality_level) + # 3.2. Convert the vorbis to wav with Sox + sox_utils.convert_audio_file(vbs_path_sox, wav_path_sox) + # 3.3. Load + expected = load_wav(wav_path_sox)[0] + + # sox's vorbis encoding has some random boundary effect, which cause small number of + # samples yields higher descrepency than the others. + # so we allow small portions of data to be outside of absolute torelance. + # make sure to pass somewhat long duration + atol = 1.0e-4 + max_failure_allowed = 0.01 # this percent of samples are allowed to outside of atol. + failure_ratio = ((found - expected).abs() > atol).sum().item() / found.numel() + if failure_ratio > max_failure_allowed: + # it's failed and this will give a better error message. + self.assertEqual(found, expected, atol=atol, rtol=1.3e-6) + + def assert_vorbis(self, *args, **kwargs): + # sox's vorbis encoding has some randomness, so we run tests multiple time + max_retry = 5 + error = None + for _ in range(max_retry): + try: + self._assert_vorbis(*args, **kwargs) + break + except AssertionError as e: + error = e + else: + raise error + + +@skipIfNoExec('sox') +@skipIfNoExtension +class TestSave(SaveTestBase): + @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): + """`sox_io_backend.save` can save wav format.""" + self.assert_wav(dtype, sample_rate, num_channels, num_frames=None) + + @parameterized.expand(list(itertools.product( + ['float32'], + [16000], + [2], + )), name_func=name_func) + def test_wav_large(self, dtype, sample_rate, num_channels): + """`sox_io_backend.save` can save large wav file.""" + two_hours = 2 * 60 * 60 * sample_rate + self.assert_wav(dtype, sample_rate, num_channels, num_frames=two_hours) + + @parameterized.expand(list(itertools.product( + ['float32', 'int32', 'int16', 'uint8'], + [4, 8, 16, 32], + )), name_func=name_func) + def test_multiple_channels(self, dtype, num_channels): + """`sox_io_backend.save` can save wav with more than 2 channels.""" + sample_rate = 8000 + self.assert_wav(dtype, sample_rate, num_channels, num_frames=None) + + @parameterized.expand(list(itertools.product( + [8000, 16000], + [1, 2], + [-4.2, -0.2, 0, 0.2, 96, 128, 160, 192, 224, 256, 320], + )), name_func=name_func) + def test_mp3(self, sample_rate, num_channels, bit_rate): + """`sox_io_backend.save` can save mp3 format.""" + self.assert_mp3(sample_rate, num_channels, bit_rate, duration=1) + + @parameterized.expand(list(itertools.product( + [16000], + [2], + [128], + )), name_func=name_func) + def test_mp3_large(self, sample_rate, num_channels, bit_rate): + """`sox_io_backend.save` can save large mp3 file.""" + two_hours = 2 * 60 * 60 + self.assert_mp3(sample_rate, num_channels, bit_rate, duration=two_hours) + + @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): + """`sox_io_backend.save` can save flac format.""" + self.assert_flac(sample_rate, num_channels, compression_level, duration=1) + + @parameterized.expand(list(itertools.product( + [16000], + [2], + [0], + )), name_func=name_func) + def test_flac_large(self, sample_rate, num_channels, compression_level): + """`sox_io_backend.save` can save large flac file.""" + two_hours = 2 * 60 * 60 + self.assert_flac(sample_rate, num_channels, compression_level, duration=two_hours) + + @parameterized.expand(list(itertools.product( + [8000, 16000], + [1, 2], + [-1, 0, 1, 2, 3, 3.6, 5, 10], + )), name_func=name_func) + def test_vorbis(self, sample_rate, num_channels, quality_level): + """`sox_io_backend.save` can save vorbis format.""" + self.assert_vorbis(sample_rate, num_channels, quality_level, duration=20) + + # note: torchaudio can load large vorbis file, but cannot save large volbis file + # the following test causes Segmentation fault + # + ''' + @parameterized.expand(list(itertools.product( + [16000], + [2], + [10], + )), name_func=name_func) + def test_vorbis_large(self, sample_rate, num_channels, quality_level): + """`sox_io_backend.save` can save large vorbis file correctly.""" + two_hours = 2 * 60 * 60 + self.assert_vorbis(sample_rate, num_channels, quality_level, two_hours) + ''' + + +@skipIfNoExec('sox') +@skipIfNoExtension +class TestSaveParams(TempDirMixin, PytorchTestCase): + """Test the correctness of optional parameters of `sox_io_backend.save`""" + @parameterized.expand([(True, ), (False, )], name_func=name_func) + def test_channels_first(self, channels_first): + """channels_first swaps axes""" + path = self.get_temp_path('data.wav') + data = get_wav_data('int32', 2, channels_first=channels_first) + sox_io_backend.save( + path, data, 8000, channels_first=channels_first) + found = load_wav(path)[0] + expected = data if channels_first else data.transpose(1, 0) + self.assertEqual(found, expected) + + @parameterized.expand([ + 'float32', 'int32', 'int16', 'uint8' + ], name_func=name_func) + def test_noncontiguous(self, dtype): + """Noncontiguous tensors are saved correctly""" + path = self.get_temp_path('data.wav') + expected = get_wav_data(dtype, 4)[::2, ::2] + assert not expected.is_contiguous() + sox_io_backend.save(path, expected, 8000) + found = load_wav(path)[0] + self.assertEqual(found, expected) + + @parameterized.expand([ + 'float32', 'int32', 'int16', 'uint8', + ]) + def test_tensor_preserve(self, dtype): + """save function should not alter Tensor""" + path = self.get_temp_path('data.wav') + expected = get_wav_data(dtype, 4)[::2, ::2] + + data = expected.clone() + sox_io_backend.save(path, data, 8000) + + self.assertEqual(data, expected) diff --git a/test/sox_io_backend/test_torchscript.py b/test/sox_io_backend/test_torchscript.py new file mode 100644 index 0000000000..9a30aab0d2 --- /dev/null +++ b/test/sox_io_backend/test_torchscript.py @@ -0,0 +1,149 @@ +import itertools +from typing import Optional + +import torch +import torchaudio +from parameterized import parameterized + +from ..common_utils import ( + TempDirMixin, + TorchaudioTestCase, + skipIfNoExec, + skipIfNoExtension, + get_wav_data, + save_wav, + load_wav, + sox_utils, +) +from .common import ( + name_func, +) + + +def py_info_func(filepath: str) -> torchaudio.backend.sox_io_backend.AudioMetaData: + return torchaudio.info(filepath) + + +def py_load_func(filepath: str, normalize: bool, channels_first: bool): + return torchaudio.load( + filepath, normalize=normalize, channels_first=channels_first) + + +def py_save_func( + filepath: str, + tensor: torch.Tensor, + sample_rate: int, + channels_first: bool = True, + compression: Optional[float] = None, +): + torchaudio.save(filepath, tensor, sample_rate, channels_first, compression) + + +@skipIfNoExec('sox') +@skipIfNoExtension +class SoxIO(TempDirMixin, TorchaudioTestCase): + """TorchScript-ability Test suite for `sox_io_backend`""" + backend = 'sox_io' + + @parameterized.expand(list(itertools.product( + ['float32', 'int32', 'int16', 'uint8'], + [8000, 16000], + [1, 2], + )), name_func=name_func) + def test_info_wav(self, dtype, sample_rate, num_channels): + """`sox_io_backend.info` is torchscript-able and returns the same result""" + audio_path = self.get_temp_path(f'{dtype}_{sample_rate}_{num_channels}.wav') + data = get_wav_data(dtype, num_channels, normalize=False, num_frames=1 * sample_rate) + save_wav(audio_path, data, sample_rate) + + script_path = self.get_temp_path('info_func.zip') + torch.jit.script(py_info_func).save(script_path) + ts_info_func = torch.jit.load(script_path) + + py_info = py_info_func(audio_path) + ts_info = ts_info_func(audio_path) + + assert py_info.sample_rate == ts_info.sample_rate + assert py_info.num_frames == ts_info.num_frames + assert py_info.num_channels == ts_info.num_channels + + @parameterized.expand(list(itertools.product( + ['float32', 'int32', 'int16', 'uint8'], + [8000, 16000], + [1, 2], + [False, True], + [False, True], + )), name_func=name_func) + def test_load_wav(self, dtype, sample_rate, num_channels, normalize, channels_first): + """`sox_io_backend.load` is torchscript-able and returns the same result""" + audio_path = self.get_temp_path(f'test_load_{dtype}_{sample_rate}_{num_channels}_{normalize}.wav') + data = get_wav_data(dtype, num_channels, normalize=False, num_frames=1 * sample_rate) + save_wav(audio_path, data, sample_rate) + + script_path = self.get_temp_path('load_func.zip') + torch.jit.script(py_load_func).save(script_path) + ts_load_func = torch.jit.load(script_path) + + py_data, py_sr = py_load_func( + audio_path, normalize=normalize, channels_first=channels_first) + ts_data, ts_sr = ts_load_func( + audio_path, normalize=normalize, channels_first=channels_first) + + self.assertEqual(py_sr, ts_sr) + self.assertEqual(py_data, ts_data) + + @parameterized.expand(list(itertools.product( + ['float32', 'int32', 'int16', 'uint8'], + [8000, 16000], + [1, 2], + )), name_func=name_func) + def test_save_wav(self, dtype, sample_rate, num_channels): + script_path = self.get_temp_path('save_func.zip') + torch.jit.script(py_save_func).save(script_path) + ts_save_func = torch.jit.load(script_path) + + expected = get_wav_data(dtype, num_channels) + py_path = self.get_temp_path(f'test_save_py_{dtype}_{sample_rate}_{num_channels}.wav') + ts_path = self.get_temp_path(f'test_save_ts_{dtype}_{sample_rate}_{num_channels}.wav') + + py_save_func(py_path, expected, sample_rate, True, None) + ts_save_func(ts_path, expected, sample_rate, True, None) + + py_data, py_sr = load_wav(py_path) + ts_data, ts_sr = load_wav(ts_path) + + self.assertEqual(sample_rate, py_sr) + self.assertEqual(sample_rate, ts_sr) + self.assertEqual(expected, py_data) + self.assertEqual(expected, ts_data) + + @parameterized.expand(list(itertools.product( + [8000, 16000], + [1, 2], + list(range(9)), + )), name_func=name_func) + def test_save_flac(self, sample_rate, num_channels, compression_level): + script_path = self.get_temp_path('save_func.zip') + torch.jit.script(py_save_func).save(script_path) + ts_save_func = torch.jit.load(script_path) + + expected = get_wav_data('float32', num_channels) + py_path = self.get_temp_path(f'test_save_py_{sample_rate}_{num_channels}_{compression_level}.flac') + ts_path = self.get_temp_path(f'test_save_ts_{sample_rate}_{num_channels}_{compression_level}.flac') + + py_save_func(py_path, expected, sample_rate, True, compression_level) + ts_save_func(ts_path, expected, sample_rate, True, compression_level) + + # converting to 32 bit because flac file has 24 bit depth which scipy cannot handle. + py_path_wav = f'{py_path}.wav' + ts_path_wav = f'{ts_path}.wav' + sox_utils.convert_audio_file(py_path, py_path_wav, bit_depth=32) + sox_utils.convert_audio_file(ts_path, ts_path_wav, bit_depth=32) + + py_data, py_sr = load_wav(py_path_wav, normalize=True) + ts_data, ts_sr = load_wav(ts_path_wav, normalize=True) + + self.assertEqual(sample_rate, py_sr) + self.assertEqual(sample_rate, ts_sr) + self.assertEqual(expected, py_data) + self.assertEqual(expected, ts_data) diff --git a/test/test_backend.py b/test/test_backend.py index 1e8f9e4fd6..6b67cb2898 100644 --- a/test/test_backend.py +++ b/test/test_backend.py @@ -1,7 +1,4 @@ -import unittest - import torchaudio -from torchaudio._internal.module_utils import is_module_available from . import common_utils @@ -28,15 +25,19 @@ class TestBackendSwitch_NoBackend(BackendSwitchMixin, common_utils.TorchaudioTes backend_module = torchaudio.backend.no_backend -@unittest.skipIf( - not is_module_available('torchaudio._torchaudio'), - 'torchaudio C++ extension not available') +@common_utils.skipIfNoExtension class TestBackendSwitch_SoX(BackendSwitchMixin, common_utils.TorchaudioTestCase): backend = 'sox' backend_module = torchaudio.backend.sox_backend -@unittest.skipIf(not is_module_available('soundfile'), '"soundfile" not available') +@common_utils.skipIfNoExtension +class TestBackendSwitch_SoXIO(BackendSwitchMixin, common_utils.TorchaudioTestCase): + backend = 'sox_io' + backend_module = torchaudio.backend.sox_io_backend + + +@common_utils.skipIfNoModule('soundfile') class TestBackendSwitch_soundfile(BackendSwitchMixin, common_utils.TorchaudioTestCase): backend = 'soundfile' backend_module = torchaudio.backend.soundfile_backend diff --git a/test/test_datasets.py b/test/test_datasets.py index 3ac7fae8ac..c3b0c917da 100644 --- a/test/test_datasets.py +++ b/test/test_datasets.py @@ -46,9 +46,8 @@ def test_cmuarctic(self): data[0] -@common_utils.skipIfNoSoxBackend class TestCommonVoice(common_utils.TorchaudioTestCase): - backend = 'sox' + backend = 'default' path = common_utils.get_asset_path() def test_commonvoice(self): diff --git a/test/test_io.py b/test/test_io.py index f58f66ed11..2c8aece85e 100644 --- a/test/test_io.py +++ b/test/test_io.py @@ -1,11 +1,24 @@ import os import math +import shutil +import tempfile import unittest import torch import torchaudio -from .common_utils import BACKENDS, BACKENDS_MP3, create_temp_assets_dir +from .common_utils import BACKENDS, BACKENDS_MP3, get_asset_path + + +def create_temp_assets_dir(): + """ + Creates a temporary directory and moves all files from test/assets there. + Returns a Tuple[string, TemporaryDirectory] which is the folder path + and object. + """ + tmp_dir = tempfile.TemporaryDirectory() + shutil.copytree(get_asset_path(), os.path.join(tmp_dir.name, "assets")) + return tmp_dir.name, tmp_dir class Test_LoadSave(unittest.TestCase): @@ -17,11 +30,15 @@ class Test_LoadSave(unittest.TestCase): def test_1_save(self): for backend in BACKENDS_MP3: + if backend == 'sox_io': + continue with self.subTest(): torchaudio.set_audio_backend(backend) self._test_1_save(self.test_filepath, False) for backend in BACKENDS: + if backend == 'sox_io': + continue with self.subTest(): torchaudio.set_audio_backend(backend) self._test_1_save(self.test_filepath_wav, True) @@ -68,6 +85,8 @@ def _test_1_save(self, test_filepath, normalization): def test_1_save_sine(self): for backend in BACKENDS: + if backend == 'sox_io': + continue with self.subTest(): torchaudio.set_audio_backend(backend) self._test_1_save_sine() @@ -101,11 +120,15 @@ def _test_1_save_sine(self): def test_2_load(self): for backend in BACKENDS_MP3: + if backend == 'sox_io': + continue with self.subTest(): torchaudio.set_audio_backend(backend) self._test_2_load(self.test_filepath, 278756) for backend in BACKENDS: + if backend == 'sox_io': + continue with self.subTest(): torchaudio.set_audio_backend(backend) self._test_2_load(self.test_filepath_wav, 276858) @@ -142,6 +165,8 @@ def _test_2_load(self, test_filepath, length): def test_2_load_nonormalization(self): for backend in BACKENDS_MP3: + if backend == 'sox_io': + continue with self.subTest(): torchaudio.set_audio_backend(backend) self._test_2_load_nonormalization(self.test_filepath, 278756) @@ -159,6 +184,8 @@ def _test_2_load_nonormalization(self, test_filepath, length): def test_3_load_and_save_is_identity(self): for backend in BACKENDS: + if backend == 'sox_io': + continue with self.subTest(): torchaudio.set_audio_backend(backend) self._test_3_load_and_save_is_identity() @@ -197,6 +224,8 @@ def _test_3_load_and_save_is_identity_across_backend(self, backend1, backend2): def test_4_load_partial(self): for backend in BACKENDS_MP3: + if backend == 'sox_io': + continue with self.subTest(): torchaudio.set_audio_backend(backend) self._test_4_load_partial() @@ -239,6 +268,8 @@ def _test_4_load_partial(self): def test_5_get_info(self): for backend in BACKENDS: + if backend == 'sox_io': + continue with self.subTest(): torchaudio.set_audio_backend(backend) self._test_5_get_info() diff --git a/test/test_librosa_compatibility.py b/test/test_librosa_compatibility.py index 62e9d3ca88..aa933535e8 100644 --- a/test/test_librosa_compatibility.py +++ b/test/test_librosa_compatibility.py @@ -160,7 +160,8 @@ class TestTransforms(common_utils.TorchaudioTestCase): """Test suite for functions in `transforms` module.""" def assert_compatibilities(self, n_fft, hop_length, power, n_mels, n_mfcc, sample_rate): common_utils.set_audio_backend('default') - sound, sample_rate = _load_audio_asset('sinewave.wav') + path = common_utils.get_asset_path('sinewave.wav') + sound, sample_rate = common_utils.load_wav(path) sound_librosa = sound.cpu().numpy().squeeze() # (64000) # test core spectrogram @@ -300,9 +301,9 @@ def test_InverseMelScale(self): hop_length = n_fft // 4 # Prepare mel spectrogram input. We use torchaudio to compute one. - common_utils.set_audio_backend('default') - sound, sample_rate = _load_audio_asset( - 'steam-train-whistle-daniel_simon.wav', offset=2**10, num_frames=2**14) + path = common_utils.get_asset_path('steam-train-whistle-daniel_simon.wav') + sound, sample_rate = common_utils.load_wav(path) + sound = sound[:, 2**10:2**10 + 2**14] sound = sound.mean(dim=0, keepdim=True) spec_orig = F.spectrogram( sound, pad=0, window=torch.hann_window(n_fft), n_fft=n_fft, diff --git a/test/test_models.py b/test/test_models.py index 7bd3f3819d..c54a57cebd 100644 --- a/test/test_models.py +++ b/test/test_models.py @@ -1,8 +1,10 @@ import torch -from torchaudio.models import Wav2Letter, _MelResNet +from torchaudio.models import Wav2Letter, _MelResNet, _UpsampleNetwork, _WaveRNN +from . import common_utils -class TestWav2Letter: + +class TestWav2Letter(common_utils.TorchaudioTestCase): def test_waveform(self): batch_size = 2 @@ -31,21 +33,110 @@ def test_mfcc(self): assert out.size() == (batch_size, num_classes, 2) -class TestMelResNet: +class TestMelResNet(common_utils.TorchaudioTestCase): def test_waveform(self): + """Validate the output dimensions of a _MelResNet block. + """ - batch_size = 2 - num_features = 200 - input_dims = 100 - output_dims = 128 - res_blocks = 10 - hidden_dims = 128 - pad = 2 + n_batch = 2 + n_time = 200 + n_freq = 100 + n_output = 128 + n_res_block = 10 + n_hidden = 128 + kernel_size = 5 - model = _MelResNet(res_blocks, input_dims, hidden_dims, output_dims, pad) + model = _MelResNet(n_res_block, n_freq, n_hidden, n_output, kernel_size) - x = torch.rand(batch_size, input_dims, num_features) + x = torch.rand(n_batch, n_freq, n_time) out = model(x) - assert out.size() == (batch_size, output_dims, num_features - pad * 2) + assert out.size() == (n_batch, n_output, n_time - kernel_size + 1) + + +class TestUpsampleNetwork(common_utils.TorchaudioTestCase): + + def test_waveform(self): + """Validate the output dimensions of a _UpsampleNetwork block. + """ + + upsample_scales = [5, 5, 8] + n_batch = 2 + n_time = 200 + n_freq = 100 + n_output = 256 + n_res_block = 10 + n_hidden = 128 + kernel_size = 5 + + total_scale = 1 + for upsample_scale in upsample_scales: + total_scale *= upsample_scale + + model = _UpsampleNetwork(upsample_scales, n_res_block, n_freq, n_hidden, n_output, kernel_size) + + x = torch.rand(n_batch, n_freq, n_time) + out1, out2 = model(x) + + assert out1.size() == (n_batch, n_freq, total_scale * (n_time - kernel_size + 1)) + assert out2.size() == (n_batch, n_output, total_scale * (n_time - kernel_size + 1)) + + +class TestWaveRNN(common_utils.TorchaudioTestCase): + + def test_waveform(self): + """Validate the output dimensions of a _WaveRNN model in waveform mode. + """ + + upsample_scales = [5, 5, 8] + n_rnn = 512 + n_fc = 512 + n_bits = 9 + sample_rate = 24000 + hop_length = 200 + n_batch = 2 + n_time = 200 + n_freq = 100 + n_output = 256 + n_res_block = 10 + n_hidden = 128 + kernel_size = 5 + mode = 'waveform' + + model = _WaveRNN(upsample_scales, n_bits, sample_rate, hop_length, n_res_block, + n_rnn, n_fc, kernel_size, n_freq, n_hidden, n_output, mode) + + x = torch.rand(n_batch, 1, hop_length * (n_time - kernel_size + 1)) + mels = torch.rand(n_batch, 1, n_freq, n_time) + out = model(x, mels) + + assert out.size() == (n_batch, 1, hop_length * (n_time - kernel_size + 1), 2 ** n_bits) + + def test_mol(self): + """Validate the output dimensions of a _WaveRNN model in mol mode. + """ + + upsample_scales = [5, 5, 8] + n_rnn = 512 + n_fc = 512 + n_bits = 9 + sample_rate = 24000 + hop_length = 200 + n_batch = 2 + n_time = 200 + n_freq = 100 + n_output = 256 + n_res_block = 10 + n_hidden = 128 + kernel_size = 5 + mode = 'mol' + + model = _WaveRNN(upsample_scales, n_bits, sample_rate, hop_length, n_res_block, + n_rnn, n_fc, kernel_size, n_freq, n_hidden, n_output, mode) + + x = torch.rand(n_batch, 1, hop_length * (n_time - kernel_size + 1)) + mels = torch.rand(n_batch, 1, n_freq, n_time) + out = model(x, mels) + + assert out.size() == (n_batch, 1, hop_length * (n_time - kernel_size + 1), 30) diff --git a/test/test_sox_compatibility.py b/test/test_sox_compatibility.py index 23d58a3fb1..a5d9f8633c 100644 --- a/test/test_sox_compatibility.py +++ b/test/test_sox_compatibility.py @@ -9,12 +9,30 @@ @common_utils.skipIfNoSoxBackend -class TestFunctionalFiltering(common_utils.TorchaudioTestCase): +class TestFunctionalFiltering(common_utils.TempDirMixin, common_utils.TorchaudioTestCase): backend = 'sox' + def setUp(self): + # 1. Create int16 signal to save as PCM wav + # 2. Write to temp file + # 3. Load temp file into tensor to reuse in downstream tests + # Prefer to use common_utils.load_wav() but this implementation does + # not match torchaudio.load and errors on downstream tests + super().setUp() + + self.NOISE_SAMPLE_RATE = 44100 # N.B. 44.1 kHz required by SoX deemph effect + noise_waveform_as_int = common_utils.get_whitenoise( + sample_rate=self.NOISE_SAMPLE_RATE, duration=5, dtype=torch.int16, scale_factor=0.9, + ) + self.noise_filepath = self.get_temp_path("whitenoise.wav") + common_utils.save_wav( + self.noise_filepath, noise_waveform_as_int, self.NOISE_SAMPLE_RATE + ) + self.noise_waveform, _ = torchaudio.load(self.noise_filepath, normalization=True) + def test_gain(self): test_filepath = common_utils.get_asset_path('steam-train-whistle-daniel_simon.wav') - waveform, _ = torchaudio.load(test_filepath) + waveform, _ = common_utils.load_wav(test_filepath) waveform_gain = F.gain(waveform, 3) self.assertTrue(waveform_gain.abs().max().item(), 1.) @@ -28,7 +46,7 @@ def test_gain(self): def test_dither(self): test_filepath = common_utils.get_asset_path('steam-train-whistle-daniel_simon.wav') - waveform, _ = torchaudio.load(test_filepath) + waveform, _ = common_utils.load_wav(test_filepath) waveform_dithered = F.dither(waveform) waveform_dithered_noiseshaped = F.dither(waveform, noise_shaping=True) @@ -48,7 +66,7 @@ def test_dither(self): def test_vctk_transform_pipeline(self): test_filepath_vctk = common_utils.get_asset_path('VCTK-Corpus', 'wav48', 'p224', 'p224_002.wav') - wf_vctk, sr_vctk = torchaudio.load(test_filepath_vctk) + wf_vctk, sr_vctk = common_utils.load_wav(test_filepath_vctk) # rate sample = T.Resample(sr_vctk, 16000, resampling_method='sinc_interpolation') @@ -71,17 +89,14 @@ def test_lowpass(self): """ Test biquad lowpass filter, compare to SoX implementation """ - cutoff_freq = 3000 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("lowpass", [cutoff_freq]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.lowpass_biquad(waveform, sample_rate, cutoff_freq) + output_waveform = F.lowpass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, cutoff_freq) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -89,37 +104,30 @@ def test_highpass(self): """ Test biquad highpass filter, compare to SoX implementation """ - cutoff_freq = 2000 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("highpass", [cutoff_freq]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.highpass_biquad(waveform, sample_rate, cutoff_freq) + output_waveform = F.highpass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, cutoff_freq) - # TBD - this fails at the 1e-4 level, debug why - self.assertEqual(output_waveform, sox_output_waveform, atol=1e-3, rtol=1e-5) + self.assertEqual(output_waveform, sox_output_waveform, atol=1.5e-3, rtol=1e-5) def test_allpass(self): """ Test biquad allpass filter, compare to SoX implementation """ - central_freq = 1000 q = 0.707 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("allpass", [central_freq, str(q) + 'q']) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.allpass_biquad(waveform, sample_rate, central_freq, q) + output_waveform = F.allpass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, central_freq, q) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -127,19 +135,17 @@ def test_bandpass_with_csg(self): """ Test biquad bandpass filter, compare to SoX implementation """ - central_freq = 1000 q = 0.707 const_skirt_gain = True - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("bandpass", ["-c", central_freq, str(q) + 'q']) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.bandpass_biquad(waveform, sample_rate, central_freq, q, const_skirt_gain) + output_waveform = F.bandpass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, + central_freq, q, const_skirt_gain) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -147,19 +153,17 @@ def test_bandpass_without_csg(self): """ Test biquad bandpass filter, compare to SoX implementation """ - central_freq = 1000 q = 0.707 const_skirt_gain = False - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("bandpass", [central_freq, str(q) + 'q']) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.bandpass_biquad(waveform, sample_rate, central_freq, q, const_skirt_gain) + output_waveform = F.bandpass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, + central_freq, q, const_skirt_gain) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -167,18 +171,16 @@ def test_bandreject(self): """ Test biquad bandreject filter, compare to SoX implementation """ - central_freq = 1000 q = 0.707 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("bandreject", [central_freq, str(q) + 'q']) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.bandreject_biquad(waveform, sample_rate, central_freq, q) + output_waveform = F.bandreject_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, + central_freq, q) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -186,19 +188,16 @@ def test_band_with_noise(self): """ Test biquad band filter with noise mode, compare to SoX implementation """ - central_freq = 1000 q = 0.707 noise = True - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("band", ["-n", central_freq, str(q) + 'q']) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.band_biquad(waveform, sample_rate, central_freq, q, noise) + output_waveform = F.band_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, central_freq, q, noise) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -211,14 +210,12 @@ def test_band_without_noise(self): q = 0.707 noise = False - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("band", [central_freq, str(q) + 'q']) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.band_biquad(waveform, sample_rate, central_freq, q, noise) + output_waveform = F.band_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, central_freq, q, noise) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -231,14 +228,12 @@ def test_treble(self): q = 0.707 gain = 40 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("treble", [gain, central_freq, str(q) + 'q']) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.treble_biquad(waveform, sample_rate, gain, central_freq, q) + output_waveform = F.treble_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, gain, central_freq, q) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -251,14 +246,12 @@ def test_bass(self): q = 0.707 gain = 40 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("bass", [gain, central_freq, str(q) + 'q']) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.bass_biquad(waveform, sample_rate, gain, central_freq, q) + output_waveform = F.bass_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, gain, central_freq, q) self.assertEqual(output_waveform, sox_output_waveform, atol=1.5e-4, rtol=1e-5) @@ -266,15 +259,12 @@ def test_deemph(self): """ Test biquad deemph filter, compare to SoX implementation """ - - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("deemph") sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.deemph_biquad(waveform, sample_rate) + output_waveform = F.deemph_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -282,15 +272,12 @@ def test_riaa(self): """ Test biquad riaa filter, compare to SoX implementation """ - - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("riaa") sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.riaa_biquad(waveform, sample_rate) + output_waveform = F.riaa_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -299,14 +286,13 @@ def test_contrast(self): Test contrast effect, compare to SoX implementation """ enhancement_amount = 80. - noise_filepath = common_utils.get_asset_path('whitenoise.wav') + E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("contrast", [enhancement_amount]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.contrast(waveform, enhancement_amount) + output_waveform = F.contrast(self.noise_waveform, enhancement_amount) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -316,14 +302,13 @@ def test_dcshift_with_limiter(self): """ shift = 0.5 limiter_gain = 0.05 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') + E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("dcshift", [shift, limiter_gain]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, _ = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.dcshift(waveform, shift, limiter_gain) + output_waveform = F.dcshift(self.noise_waveform, shift, limiter_gain) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -332,14 +317,13 @@ def test_dcshift_without_limiter(self): Test dcshift effect, compare to SoX implementation """ shift = 0.6 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') + E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("dcshift", [shift]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, _ = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.dcshift(waveform, shift) + output_waveform = F.dcshift(self.noise_waveform, shift) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -349,14 +333,13 @@ def test_overdrive(self): """ gain = 30 colour = 40 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') + E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("overdrive", [gain, colour]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, _ = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.overdrive(waveform, gain, colour) + output_waveform = F.overdrive(self.noise_waveform, gain, colour) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -369,14 +352,14 @@ def test_phaser_sine(self): delay_ms = 2.0 decay = 0.4 speed = 0.5 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') + E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("phaser", [gain_in, gain_out, delay_ms, decay, speed, "-s"]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.phaser(waveform, sample_rate, gain_in, gain_out, delay_ms, decay, speed, sinusoidal=True) + output_waveform = F.phaser(self.noise_waveform, self.NOISE_SAMPLE_RATE, + gain_in, gain_out, delay_ms, decay, speed, sinusoidal=True) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -389,14 +372,14 @@ def test_phaser_triangle(self): delay_ms = 2.0 decay = 0.4 speed = 0.5 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') + E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("phaser", [gain_in, gain_out, delay_ms, decay, speed, "-t"]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.phaser(waveform, sample_rate, gain_in, gain_out, delay_ms, decay, speed, sinusoidal=False) + output_waveform = F.phaser(self.noise_waveform, self.NOISE_SAMPLE_RATE, + gain_in, gain_out, delay_ms, decay, speed, sinusoidal=False) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -410,15 +393,14 @@ def test_flanger_triangle_linear(self): width = 0.9 speed = 0.5 phase = 30 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') + E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("flanger", [delay, depth, regen, width, speed, "triangle", phase, "linear"]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.flanger(waveform, sample_rate, delay, depth, regen, width, speed, phase, - modulation='triangular', interpolation='linear') + output_waveform = F.flanger(self.noise_waveform, self.NOISE_SAMPLE_RATE, delay, depth, regen, + width, speed, phase, modulation='triangular', interpolation='linear') torch.testing.assert_allclose(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -432,15 +414,14 @@ def test_flanger_triangle_quad(self): width = 0.4 speed = 0.5 phase = 40 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') + E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("flanger", [delay, depth, regen, width, speed, "triangle", phase, "quadratic"]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.flanger(waveform, sample_rate, delay, depth, regen, width, speed, phase, - modulation='triangular', interpolation='quadratic') + output_waveform = F.flanger(self.noise_waveform, self.NOISE_SAMPLE_RATE, delay, depth, + regen, width, speed, phase, modulation='triangular', interpolation='quadratic') torch.testing.assert_allclose(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -454,15 +435,14 @@ def test_flanger_sine_linear(self): width = 0.23 speed = 1.3 phase = 60 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') + E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("flanger", [delay, depth, regen, width, speed, "sine", phase, "linear"]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.flanger(waveform, sample_rate, delay, depth, regen, width, speed, phase, - modulation='sinusoidal', interpolation='linear') + output_waveform = F.flanger(self.noise_waveform, self.NOISE_SAMPLE_RATE, delay, depth, + regen, width, speed, phase, modulation='sinusoidal', interpolation='linear') torch.testing.assert_allclose(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -476,15 +456,14 @@ def test_flanger_sine_quad(self): width = 0.23 speed = 1.3 phase = 25 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') + E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("flanger", [delay, depth, regen, width, speed, "sine", phase, "quadratic"]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.flanger(waveform, sample_rate, delay, depth, regen, width, speed, phase, - modulation='sinusoidal', interpolation='quadratic') + output_waveform = F.flanger(self.noise_waveform, self.NOISE_SAMPLE_RATE, delay, depth, + regen, width, speed, phase, modulation='sinusoidal', interpolation='quadratic') torch.testing.assert_allclose(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) @@ -497,21 +476,17 @@ def test_equalizer(self): q = 0.707 gain = 1 - noise_filepath = common_utils.get_asset_path('whitenoise.wav') E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(noise_filepath) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("equalizer", [center_freq, q, gain]) sox_output_waveform, sr = E.sox_build_flow_effects() - waveform, sample_rate = torchaudio.load(noise_filepath, normalization=True) - output_waveform = F.equalizer_biquad(waveform, sample_rate, center_freq, gain, q) + output_waveform = F.equalizer_biquad(self.noise_waveform, self.NOISE_SAMPLE_RATE, center_freq, gain, q) self.assertEqual(output_waveform, sox_output_waveform, atol=1e-4, rtol=1e-5) def test_perf_biquad_filtering(self): - fn_sine = common_utils.get_asset_path('whitenoise.wav') - b0 = 0.4 b1 = 0.2 b2 = 0.9 @@ -521,13 +496,12 @@ def test_perf_biquad_filtering(self): # SoX method E = torchaudio.sox_effects.SoxEffectsChain() - E.set_input_file(fn_sine) + E.set_input_file(self.noise_filepath) E.append_effect_to_chain("biquad", [b0, b1, b2, a0, a1, a2]) waveform_sox_out, _ = E.sox_build_flow_effects() - waveform, _ = torchaudio.load(fn_sine, normalization=True) waveform_lfilter_out = F.lfilter( - waveform, torch.tensor([a0, a1, a2]), torch.tensor([b0, b1, b2]) + self.noise_waveform, torch.tensor([a0, a1, a2]), torch.tensor([b0, b1, b2]) ) self.assertEqual(waveform_lfilter_out, waveform_sox_out, atol=1e-4, rtol=1e-5) diff --git a/test/test_sox_effects.py b/test/test_sox_effects.py index 68440db8d2..6b12d7cd06 100644 --- a/test/test_sox_effects.py +++ b/test/test_sox_effects.py @@ -1,3 +1,4 @@ +import sys import math import unittest @@ -11,7 +12,7 @@ class Test_SoxEffectsChain(common_utils.TorchaudioTestCase): backend = 'sox' - test_filepath = common_utils.get_asset_path("steam-train-whistle-daniel_simon.mp3") + test_filepath = common_utils.get_asset_path("steam-train-whistle-daniel_simon.wav") def test_single_channel(self): fn_sine = common_utils.get_asset_path("sinewave.wav") @@ -34,6 +35,7 @@ def test_rate_channels(self): self.assertEqual(sr, target_rate) self.assertEqual(x.size(0), target_channels) + @unittest.skipIf(sys.platform == 'darwin', 'This test is known to fail on macOS') def test_lowpass_speed(self): speed = .8 si, _ = torchaudio.info(self.test_filepath) diff --git a/test/test_transforms.py b/test/test_transforms.py index af2b834fdb..6df9562bc8 100644 --- a/test/test_transforms.py +++ b/test/test_transforms.py @@ -45,7 +45,7 @@ def test_mu_law_companding(self): def test_AmplitudeToDB(self): filepath = common_utils.get_asset_path('steam-train-whistle-daniel_simon.wav') - waveform, sample_rate = torchaudio.load(filepath) + waveform = common_utils.load_wav(filepath)[0] mag_to_db_transform = transforms.AmplitudeToDB('magnitude', 80.) power_to_db_transform = transforms.AmplitudeToDB('power', 80.) @@ -115,7 +115,7 @@ def test_mel2(self): self.assertTrue(mel_transform2.mel_scale.fb.sum(1).ge(0.).all()) # check on multi-channel audio filepath = common_utils.get_asset_path('steam-train-whistle-daniel_simon.wav') - x_stereo, sr_stereo = torchaudio.load(filepath) # (2, 278756), 44100 + x_stereo = common_utils.load_wav(filepath)[0] # (2, 278756), 44100 spectrogram_stereo = s2db(mel_transform(x_stereo)) # (2, 128, 1394) self.assertTrue(spectrogram_stereo.dim() == 3) self.assertTrue(spectrogram_stereo.size(0) == 2) @@ -166,7 +166,7 @@ def test_mfcc(self): def test_resample_size(self): input_path = common_utils.get_asset_path('sinewave.wav') - waveform, sample_rate = torchaudio.load(input_path) + waveform, sample_rate = common_utils.load_wav(input_path) upsample_rate = sample_rate * 2 downsample_rate = sample_rate // 2 diff --git a/test/torchscript_consistency_impl.py b/test/torchscript_consistency_impl.py index 2527cd5fbf..76444dc18a 100644 --- a/test/torchscript_consistency_impl.py +++ b/test/torchscript_consistency_impl.py @@ -2,7 +2,6 @@ import unittest import torch -import torchaudio import torchaudio.functional as F import torchaudio.transforms as T @@ -616,6 +615,5 @@ def test_SlidingWindowCmn(self): def test_Vad(self): filepath = common_utils.get_asset_path("vad-go-mono-32000.wav") - common_utils.set_audio_backend('default') - waveform, sample_rate = torchaudio.load(filepath) + waveform, sample_rate = common_utils.load_wav(filepath) self._assert_consistency(T.Vad(sample_rate=sample_rate), waveform) diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt new file mode 100644 index 0000000000..c4be4cb7b0 --- /dev/null +++ b/third_party/CMakeLists.txt @@ -0,0 +1,80 @@ +cmake_minimum_required(VERSION 3.1) + +project(torchaudio_third_parties) +include(ExternalProject) + +set(INSTALL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/install) +set(ARCHIVE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/archives) +set(COMMON_ARGS --quiet --disable-shared --enable-static --prefix=${INSTALL_DIR} --with-pic --disable-dependency-tracking --disable-debug --disable-examples --disable-doc) + +ExternalProject_Add(libmad + PREFIX ${CMAKE_CURRENT_SOURCE_DIR} + DOWNLOAD_DIR ${ARCHIVE_DIR} + URL https://downloads.sourceforge.net/project/mad/libmad/0.15.1b/libmad-0.15.1b.tar.gz + URL_HASH SHA256=bbfac3ed6bfbc2823d3775ebb931087371e142bb0e9bb1bee51a76a6e0078690 + PATCH_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/patch/libmad.patch + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/src/libmad/configure ${COMMON_ARGS} +) + +ExternalProject_Add(libmp3lame + PREFIX ${CMAKE_CURRENT_SOURCE_DIR} + DOWNLOAD_DIR ${ARCHIVE_DIR} + URL https://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz + URL_HASH SHA256=24346b4158e4af3bd9f2e194bb23eb473c75fb7377011523353196b19b9a23ff + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/src/libmp3lame/configure ${COMMON_ARGS} --enable-nasm +) + +ExternalProject_Add(libogg + PREFIX ${CMAKE_CURRENT_SOURCE_DIR} + DOWNLOAD_DIR ${ARCHIVE_DIR} + URL https://ftp.osuosl.org/pub/xiph/releases/ogg/libogg-1.3.3.tar.gz + URL_HASH SHA256=c2e8a485110b97550f453226ec644ebac6cb29d1caef2902c007edab4308d985 + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/src/libogg/configure ${COMMON_ARGS} +) + +ExternalProject_Add(libflac + PREFIX ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS libogg + DOWNLOAD_DIR ${ARCHIVE_DIR} + URL https://ftp.osuosl.org/pub/xiph/releases/flac/flac-1.3.2.tar.xz + URL_HASH SHA256=91cfc3ed61dc40f47f050a109b08610667d73477af6ef36dcad31c31a4a8d53f + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build_codec_helper.sh ${CMAKE_CURRENT_SOURCE_DIR}/src/libflac/configure ${COMMON_ARGS} --with-ogg +) + +ExternalProject_Add(libvorbis + PREFIX ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS libogg + DOWNLOAD_DIR ${ARCHIVE_DIR} + URL https://ftp.osuosl.org/pub/xiph/releases/vorbis/libvorbis-1.3.6.tar.gz + URL_HASH SHA256=6ed40e0241089a42c48604dc00e362beee00036af2d8b3f46338031c9e0351cb + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build_codec_helper.sh ${CMAKE_CURRENT_SOURCE_DIR}/src/libvorbis/configure ${COMMON_ARGS} --with-ogg +) + +ExternalProject_Add(libopus + PREFIX ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS libogg + DOWNLOAD_DIR ${ARCHIVE_DIR} + URL https://ftp.osuosl.org/pub/xiph/releases/opus/opus-1.3.1.tar.gz + URL_HASH SHA256=65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build_codec_helper.sh ${CMAKE_CURRENT_SOURCE_DIR}/src/libopus/configure ${COMMON_ARGS} --with-ogg +) + +ExternalProject_Add(opusfile + PREFIX ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS libopus + DOWNLOAD_DIR ${ARCHIVE_DIR} + STAMP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/opusfile-stamp + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/opusfile + URL https://ftp.osuosl.org/pub/xiph/releases/opus/opusfile-0.12.tar.gz + URL_HASH SHA256=118d8601c12dd6a44f52423e68ca9083cc9f2bfe72da7a8c1acb22a80ae3550b + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build_codec_helper.sh ${CMAKE_CURRENT_SOURCE_DIR}/src/opusfile/configure ${COMMON_ARGS} --disable-http +) + +ExternalProject_Add(libsox + PREFIX ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS libogg libflac libvorbis opusfile libmp3lame libmad + 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 + CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build_codec_helper.sh ${CMAKE_CURRENT_SOURCE_DIR}/src/libsox/configure ${COMMON_ARGS} --with-lame --with-flac --with-mad --with-oggvorbis --without-alsa --without-coreaudio --without-png --without-oss --without-sndfile --with-opus +) diff --git a/third_party/build_codec_helper.sh b/third_party/build_codec_helper.sh new file mode 100755 index 0000000000..e7f2614781 --- /dev/null +++ b/third_party/build_codec_helper.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +# Helper script for building codecs depending on libogg, such as libopus and opus. +# It is difficult to set environment variable inside of ExternalProject_Add, +# so this script sets necessary environment variables before running the given command + +this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +install_dir="${this_dir}/install" + +export PKG_CONFIG_PATH="${install_dir}/lib/pkgconfig" +export LDFLAGS="-L${install_dir}/lib ${LDFLAGS}" +export CPPFLAGS="-I${install_dir}/include ${CPPFLAGS}" + +$@ diff --git a/third_party/patch/libmad.patch b/third_party/patch/libmad.patch new file mode 100644 index 0000000000..a805787831 --- /dev/null +++ b/third_party/patch/libmad.patch @@ -0,0 +1,86 @@ +See the followings for the origin of this patch +http://www.linuxfromscratch.org/blfs/view/svn/multimedia/libmad.html +http://www.linuxfromscratch.org/patches/blfs/svn/libmad-0.15.1b-fixes-1.patch +--- src/libmad/configure 2004-02-05 09:34:07.000000000 +0000 ++++ src/libmad/configure.new 2020-06-30 21:10:28.528018931 +0000 +@@ -19083,71 +19083,7 @@ + + if test "$GCC" = yes + then +- if test -z "$arch" +- then +- case "$host" in +- i386-*) ;; +- i?86-*) arch="-march=i486" ;; +- arm*-empeg-*) arch="-march=armv4 -mtune=strongarm1100" ;; +- armv4*-*) arch="-march=armv4 -mtune=strongarm" ;; +- powerpc-*) ;; +- mips*-agenda-*) arch="-mcpu=vr4100" ;; +- mips*-luxsonor-*) arch="-mips1 -mcpu=r3000 -Wa,-m4010" ;; +- esac +- fi +- +- case "$optimize" in +- -O|"-O "*) +- optimize="-O" +- optimize="$optimize -fforce-mem" +- optimize="$optimize -fforce-addr" +- : #x optimize="$optimize -finline-functions" +- : #- optimize="$optimize -fstrength-reduce" +- optimize="$optimize -fthread-jumps" +- optimize="$optimize -fcse-follow-jumps" +- optimize="$optimize -fcse-skip-blocks" +- : #x optimize="$optimize -frerun-cse-after-loop" +- : #x optimize="$optimize -frerun-loop-opt" +- : #x optimize="$optimize -fgcse" +- optimize="$optimize -fexpensive-optimizations" +- optimize="$optimize -fregmove" +- : #* optimize="$optimize -fdelayed-branch" +- : #x optimize="$optimize -fschedule-insns" +- optimize="$optimize -fschedule-insns2" +- : #? optimize="$optimize -ffunction-sections" +- : #? optimize="$optimize -fcaller-saves" +- : #> optimize="$optimize -funroll-loops" +- : #> optimize="$optimize -funroll-all-loops" +- : #x optimize="$optimize -fmove-all-movables" +- : #x optimize="$optimize -freduce-all-givs" +- : #? optimize="$optimize -fstrict-aliasing" +- : #* optimize="$optimize -fstructure-noalias" +- +- case "$host" in +- arm*-*) +- optimize="$optimize -fstrength-reduce" +- ;; +- mips*-*) +- optimize="$optimize -fstrength-reduce" +- optimize="$optimize -finline-functions" +- ;; +- i?86-*) +- optimize="$optimize -fstrength-reduce" +- ;; +- powerpc-apple-*) +- # this triggers an internal compiler error with gcc2 +- : #optimize="$optimize -fstrength-reduce" +- +- # this is really only beneficial with gcc3 +- : #optimize="$optimize -finline-functions" +- ;; +- *) +- # this sometimes provokes bugs in gcc 2.95.2 +- : #optimize="$optimize -fstrength-reduce" +- ;; +- esac +- ;; +- esac ++ optimize="-O2" + fi + + case "$host" in +@@ -21497,6 +21433,7 @@ + then + case "$host" in + i?86-*) FPM="INTEL" ;; ++ x86_64*) FPM="64BIT" ;; + arm*-*) FPM="ARM" ;; + mips*-*) FPM="MIPS" ;; + sparc*-*) FPM="SPARC" ;; diff --git a/torchaudio/backend/sox_io_backend.py b/torchaudio/backend/sox_io_backend.py new file mode 100644 index 0000000000..4664f733c6 --- /dev/null +++ b/torchaudio/backend/sox_io_backend.py @@ -0,0 +1,134 @@ +from typing import Tuple, Optional + +import torch +from torchaudio._internal import ( + module_utils as _mod_utils, +) + + +class AudioMetaData: + def __init__(self, sample_rate: int, num_frames: int, num_channels: int): + self.sample_rate = sample_rate + self.num_frames = num_frames + self.num_channels = num_channels + + +@_mod_utils.requires_module('torchaudio._torchaudio') +def info(filepath: str) -> AudioMetaData: + """Get signal information of an audio file.""" + sinfo = torch.ops.torchaudio.sox_io_get_info(filepath) + return AudioMetaData(sinfo.get_sample_rate(), sinfo.get_num_frames(), sinfo.get_num_channels()) + + +@_mod_utils.requires_module('torchaudio._torchaudio') +def load( + filepath: str, + frame_offset: int = 0, + num_frames: int = -1, + normalize: bool = True, + channels_first: bool = True, +) -> Tuple[torch.Tensor, int]: + """Load audio data from file. + + This function can handle all the codecs that underlying libsox can handle, however note the + followings. + + Note: + This function is tested on the following formats; + - WAV + - 32-bit floating-point + - 32-bit signed integer + - 16-bit signed integer + - 8-bit unsigned integer + - MP3 + - FLAC + - OGG/VORBIS + + By default, this function returns Tensor with ``float32`` dtype and the shape of ``[channel, time]``. + The samples are normalized to fit in the range of ``[-1.0, 1.0]``. + + When the input format is WAV with integer type, such as 32-bit signed integer, 16-bit + signed integer and 8-bit unsigned integer (24-bit signed integer is not supported), + by providing ``normalize=False``, this function can return integer Tensor, where the samples + are expressed within the whole range of the corresponding dtype, that is, ``int32`` tensor + for 32-bit signed PCM, ``int16`` for 16-bit signed PCM and ``uint8`` for 8-bit unsigned PCM. + + ``normalize`` parameter has no effect on 32-bit floating-point WAV and other formats, such as + flac and mp3. For these formats, this function always returns ``float32`` Tensor with values + normalized to ``[-1.0, 1.0]``. + + Args: + filepath: Path to audio file + frame_offset: Number of frames to skip before start reading data. + num_frames: Maximum number of frames to read. -1 reads all the remaining samples, starting + from ``frame_offset``. This function may return the less number of frames if there is + not enough frames in the given file. + normalize: When ``True``, this function always return ``float32``, and sample values are + normalized to ``[-1.0, 1.0]``. If input file is integer WAV, giving ``False`` will change + the resulting Tensor type to integer type. This argument has no effect for formats other + than integer WAV type. + channels_first: When True, the returned Tensor has dimension ``[channel, time]``. + Otherwise, the returned Tensor's dimension is ``[time, channel]``. + + Returns: + torch.Tensor: If the input file has integer wav format and normalization is off, then it has + integer type, else ``float32`` type. If ``channels_first=True``, it has + ``[channel, time]`` else ``[time, channel]``. + """ + signal = torch.ops.torchaudio.sox_io_load_audio_file( + filepath, frame_offset, num_frames, normalize, channels_first) + return signal.get_tensor(), signal.get_sample_rate() + + +@_mod_utils.requires_module('torchaudio._torchaudio') +def save( + filepath: str, + tensor: torch.Tensor, + sample_rate: int, + channels_first: bool = True, + compression: Optional[float] = None, +): + """Save audio data to file. + + Supported formats are; + - WAV + - 32-bit floating-point + - 32-bit signed integer + - 16-bit signed integer + - 8-bit unsigned integer + - MP3 + - FLAC + - OGG/VORBIS + + Args: + filepath: Path to save file. + tensor: Audio data to save. must be 2D tensor. + sample_rate: sampling rate + channels_first: If True, the given tensor is interpreted as ``[channel, time]``. + compression: Used for formats other than WAV. This corresponds to ``-C`` option + of ``sox`` command. + See the detail at http://sox.sourceforge.net/soxformat.html. + - MP3: Either bitrate [kbps] with quality factor, such as ``128.2`` or + VBR encoding with quality factor such as ``-4.2``. Default: ``-4.5`` + - FLAC: compression level. Whole number from ``0`` to ``8``. + ``8`` is default and highest compression. + - OGG/VORBIS: number from -1 to 10; -1 is the highest compression and lowest + quality. Default: ``3``. + """ + if compression is None: + ext = str(filepath)[-3:].lower() + if ext == 'wav': + compression = 0. + elif ext == 'mp3': + compression = -4.5 + elif ext == 'flac': + compression = 8. + elif ext in ['ogg', 'vorbis']: + compression = 3. + else: + raise RuntimeError(f'Unsupported file type: "{ext}"') + signal = torch.classes.torchaudio.TensorSignal(tensor, sample_rate, channels_first) + torch.ops.torchaudio.sox_io_save_audio_file(filepath, signal, compression) + + +load_wav = load diff --git a/torchaudio/backend/utils.py b/torchaudio/backend/utils.py index d537f01daf..cb53b3e02f 100644 --- a/torchaudio/backend/utils.py +++ b/torchaudio/backend/utils.py @@ -7,6 +7,7 @@ from . import ( no_backend, sox_backend, + sox_io_backend, soundfile_backend, ) @@ -24,6 +25,7 @@ def list_audio_backends() -> List[str]: backends.append('soundfile') if is_module_available('torchaudio._torchaudio'): backends.append('sox') + backends.append('sox_io') return backends @@ -43,6 +45,8 @@ def set_audio_backend(backend: Optional[str]) -> None: module = no_backend elif backend == 'sox': module = sox_backend + elif backend == 'sox_io': + module = sox_io_backend elif backend == 'soundfile': module = soundfile_backend else: @@ -69,6 +73,8 @@ def get_audio_backend() -> Optional[str]: return None if torchaudio.load == sox_backend.load: return 'sox' + if torchaudio.load == sox_io_backend.load: + return 'sox_io' if torchaudio.load == soundfile_backend.load: return 'soundfile' raise ValueError('Unknown backend.') diff --git a/torchaudio/csrc/register.cpp b/torchaudio/csrc/register.cpp index 81b1a84c96..3c03232941 100644 --- a/torchaudio/csrc/register.cpp +++ b/torchaudio/csrc/register.cpp @@ -1,17 +1,64 @@ #ifndef TORCHAUDIO_REGISTER_H #define TORCHAUDIO_REGISTER_H -#include +#include +#include +#include namespace torchaudio { namespace { +//////////////////////////////////////////////////////////////////////////////// +// sox_utils.h +//////////////////////////////////////////////////////////////////////////////// +static auto registerTensorSignal = + torch::class_("torchaudio", "TensorSignal") + .def(torch::init()) + .def("get_tensor", &sox_utils::TensorSignal::getTensor) + .def("get_sample_rate", &sox_utils::TensorSignal::getSampleRate) + .def("get_channels_first", &sox_utils::TensorSignal::getChannelsFirst); + +//////////////////////////////////////////////////////////////////////////////// +// sox_io.h +//////////////////////////////////////////////////////////////////////////////// static auto registerSignalInfo = - torch::class_("torchaudio", "SignalInfo") - .def(torch::init()) - .def("get_sample_rate", &SignalInfo::getSampleRate) - .def("get_num_channels", &SignalInfo::getNumChannels) - .def("get_num_samples", &SignalInfo::getNumSamples); + torch::class_("torchaudio", "SignalInfo") + .def("get_sample_rate", &sox_io::SignalInfo::getSampleRate) + .def("get_num_channels", &sox_io::SignalInfo::getNumChannels) + .def("get_num_frames", &sox_io::SignalInfo::getNumFrames); + +static auto registerGetInfo = torch::RegisterOperators().op( + torch::RegisterOperators::options() + .schema( + "torchaudio::sox_io_get_info(str path) -> __torch__.torch.classes.torchaudio.SignalInfo info") + .catchAllKernel()); + +static auto registerLoadAudioFile = torch::RegisterOperators().op( + torch::RegisterOperators::options() + .schema( + "torchaudio::sox_io_load_audio_file(str path, int frame_offset, int num_frames, bool normalize, bool channels_first) -> __torch__.torch.classes.torchaudio.TensorSignal signal") + .catchAllKernel< + decltype(sox_io::load_audio_file), + &sox_io::load_audio_file>()); + +static auto registerSaveAudioFile = torch::RegisterOperators().op( + torch::RegisterOperators::options() + .schema( + "torchaudio::sox_io_save_audio_file(str path, __torch__.torch.classes.torchaudio.TensorSignal signal, float compression) -> ()") + .catchAllKernel< + decltype(sox_io::save_audio_file), + &sox_io::save_audio_file>()); + +//////////////////////////////////////////////////////////////////////////////// +// sox_effects.h +//////////////////////////////////////////////////////////////////////////////// +static auto registerSoxEffects = + torch::RegisterOperators( + "torchaudio::sox_effects_initialize_sox_effects", + &sox_effects::initialize_sox_effects) + .op("torchaudio::sox_effects_shutdown_sox_effects", + &sox_effects::shutdown_sox_effects) + .op("torchaudio::sox_effects_list_effects", &sox_effects::list_effects); } // namespace } // namespace torchaudio diff --git a/torchaudio/csrc/sox.cpp b/torchaudio/csrc/sox.cpp index 3ae81bef19..0f099946fd 100644 --- a/torchaudio/csrc/sox.cpp +++ b/torchaudio/csrc/sox.cpp @@ -82,17 +82,6 @@ std::tuple get_info( return std::make_tuple(fd->signal, fd->encoding); } -std::vector get_effect_names() { - sox_effect_fn_t const * fns = sox_get_effect_fns(); - std::vector sv; - for(int i = 0; fns[i]; ++i) { - const sox_effect_handler_t *eh = fns[i] (); - if(eh && eh->name) - sv.push_back(eh->name); - } - return sv; -} - int read_audio_file( const std::string& file_name, at::Tensor output, @@ -186,16 +175,6 @@ void write_audio_file( } } -int initialize_sox() { - /* Initialization for sox effects. Only initialize once */ - return sox_init(); -} - -int shutdown_sox() { - /* Shutdown for sox effects. Do not shutdown between multiple calls */ - return sox_quit(); -} - int build_flow_effects(const std::string& file_name, at::Tensor otensor, bool ch_first, @@ -489,20 +468,8 @@ PYBIND11_MODULE(_torchaudio, m) { "get_info", &torch::audio::get_info, "Gets information about an audio file"); - m.def( - "get_effect_names", - &torch::audio::get_effect_names, - "Gets the names of all available effects"); m.def( "build_flow_effects", &torch::audio::build_flow_effects, "build effects and flow chain into tensors"); - m.def( - "initialize_sox", - &torch::audio::initialize_sox, - "initialize sox for effects"); - m.def( - "shutdown_sox", - &torch::audio::shutdown_sox, - "shutdown sox for effects"); } diff --git a/torchaudio/csrc/sox.h b/torchaudio/csrc/sox.h index 8d851c9b21..8093f0732e 100644 --- a/torchaudio/csrc/sox.h +++ b/torchaudio/csrc/sox.h @@ -45,13 +45,6 @@ void write_audio_file( std::tuple get_info( const std::string& file_name); -// get names of all sox effects -std::vector get_effect_names(); - -// Initialize and Shutdown SoX effects chain. These functions should only be run once. -int initialize_sox(); -int shutdown_sox(); - // Struct for build_flow_effects function struct SoxEffect { SoxEffect() : ename(""), eopts({""}) { } diff --git a/torchaudio/csrc/sox_effects.cpp b/torchaudio/csrc/sox_effects.cpp new file mode 100644 index 0000000000..9a0c2ddc6f --- /dev/null +++ b/torchaudio/csrc/sox_effects.cpp @@ -0,0 +1,54 @@ +#include +#include + +using namespace torch::indexing; + +namespace torchaudio { +namespace sox_effects { + +namespace { + +enum SoxEffectsResourceState { NotInitialized, Initialized, ShutDown }; +SoxEffectsResourceState SOX_RESOURCE_STATE = NotInitialized; + +} // namespace + +void initialize_sox_effects() { + if (SOX_RESOURCE_STATE == ShutDown) { + throw std::runtime_error( + "SoX Effects has been shut down. Cannot initialize again."); + } + if (SOX_RESOURCE_STATE == NotInitialized) { + if (sox_init() != SOX_SUCCESS) { + throw std::runtime_error("Failed to initialize sox effects."); + }; + SOX_RESOURCE_STATE = Initialized; + } +}; + +void shutdown_sox_effects() { + if (SOX_RESOURCE_STATE == NotInitialized) { + throw std::runtime_error( + "SoX Effects is not initialized. Cannot shutdown."); + } + if (SOX_RESOURCE_STATE == Initialized) { + if (sox_quit() != SOX_SUCCESS) { + throw std::runtime_error("Failed to initialize sox effects."); + }; + SOX_RESOURCE_STATE = ShutDown; + } +} + +std::vector list_effects() { + std::vector names; + const sox_effect_fn_t* fns = sox_get_effect_fns(); + for (int i = 0; fns[i]; ++i) { + const sox_effect_handler_t* handler = fns[i](); + if (handler && handler->name) + names.push_back(handler->name); + } + return names; +} + +} // namespace sox_effects +} // namespace torchaudio diff --git a/torchaudio/csrc/sox_effects.h b/torchaudio/csrc/sox_effects.h new file mode 100644 index 0000000000..14bdbbfabc --- /dev/null +++ b/torchaudio/csrc/sox_effects.h @@ -0,0 +1,18 @@ +#ifndef TORCHAUDIO_SOX_EFFECTS_H +#define TORCHAUDIO_SOX_EFFECTS_H + +#include + +namespace torchaudio { +namespace sox_effects { + +void initialize_sox_effects(); + +void shutdown_sox_effects(); + +std::vector list_effects(); + +} // namespace sox_effects +} // namespace torchaudio + +#endif diff --git a/torchaudio/csrc/sox_io.cpp b/torchaudio/csrc/sox_io.cpp new file mode 100644 index 0000000000..5d308027bb --- /dev/null +++ b/torchaudio/csrc/sox_io.cpp @@ -0,0 +1,170 @@ +#include +#include +#include + +using namespace torch::indexing; +using namespace torchaudio::sox_utils; + +namespace torchaudio { +namespace sox_io { + +SignalInfo::SignalInfo( + const int64_t sample_rate_, + const int64_t num_channels_, + const int64_t num_frames_) + : sample_rate(sample_rate_), + num_channels(num_channels_), + num_frames(num_frames_){}; + +int64_t SignalInfo::getSampleRate() const { + return sample_rate; +} + +int64_t SignalInfo::getNumChannels() const { + return num_channels; +} + +int64_t SignalInfo::getNumFrames() const { + return num_frames; +} + +c10::intrusive_ptr get_info(const std::string& path) { + SoxFormat sf(sox_open_read( + path.c_str(), + /*signal=*/nullptr, + /*encoding=*/nullptr, + /*filetype=*/nullptr)); + + if (static_cast(sf) == nullptr) { + throw std::runtime_error("Error opening audio file"); + } + + return c10::make_intrusive( + static_cast(sf->signal.rate), + static_cast(sf->signal.channels), + static_cast(sf->signal.length / sf->signal.channels)); +} + +c10::intrusive_ptr load_audio_file( + const std::string& path, + const int64_t frame_offset, + const int64_t num_frames, + const bool normalize, + const bool channels_first) { + if (frame_offset < 0) { + throw std::runtime_error( + "Invalid argument: frame_offset must be non-negative."); + } + if (num_frames == 0 || num_frames < -1) { + throw std::runtime_error( + "Invalid argument: num_frames must be -1 or greater than 0."); + } + + SoxFormat sf(sox_open_read( + path.c_str(), + /*signal=*/nullptr, + /*encoding=*/nullptr, + /*filetype=*/nullptr)); + + validate_input_file(sf); + + const int64_t num_channels = sf->signal.channels; + const int64_t num_total_samples = sf->signal.length; + const int64_t sample_start = sf->signal.channels * frame_offset; + + if (sox_seek(sf, sample_start, 0) == SOX_EOF) { + throw std::runtime_error("Error reading audio file: offset past EOF."); + } + + const int64_t sample_end = [&]() { + if (num_frames == -1) + return num_total_samples; + const int64_t sample_end_ = num_channels * num_frames + sample_start; + if (num_total_samples < sample_end_) { + // For lossy encoding, it is difficult to predict exact size of buffer for + // reading the number of samples required. + // So we allocate buffer size of given `num_frames` and ask sox to read as + // much as possible. For lossless format, sox reads exact number of + // samples, but for lossy encoding, sox can end up reading less. (i.e. + // mp3) For the consistent behavior specification between lossy/lossless + // format, we allow users to provide `num_frames` value that exceeds #of + // available samples, and we adjust it here. + return num_total_samples; + } + return sample_end_; + }(); + + const int64_t max_samples = sample_end - sample_start; + + // Read samples into buffer + std::vector buffer; + buffer.reserve(max_samples); + const int64_t num_samples = sox_read(sf, buffer.data(), max_samples); + if (num_samples == 0) { + throw std::runtime_error( + "Error reading audio file: empty file or read operation failed."); + } + // NOTE: num_samples may be smaller than max_samples if the input + // format is compressed (i.e. mp3). + + // Convert to Tensor + auto tensor = convert_to_tensor( + buffer.data(), + num_samples, + num_channels, + get_dtype(sf->encoding.encoding, sf->signal.precision), + normalize, + channels_first); + + return c10::make_intrusive( + tensor, static_cast(sf->signal.rate), channels_first); +} + +void save_audio_file( + const std::string& file_name, + const c10::intrusive_ptr& signal, + const double compression) { + const auto tensor = signal->getTensor(); + const auto sample_rate = signal->getSampleRate(); + const auto channels_first = signal->getChannelsFirst(); + + validate_input_tensor(tensor); + + const auto filetype = get_filetype(file_name); + const auto signal_info = + get_signalinfo(tensor, sample_rate, channels_first, filetype); + const auto encoding_info = + get_encodinginfo(filetype, tensor.dtype(), compression); + + SoxFormat sf(sox_open_write( + file_name.c_str(), + &signal_info, + &encoding_info, + /*filetype=*/filetype.c_str(), + /*oob=*/nullptr, + /*overwrite_permitted=*/nullptr)); + + if (static_cast(sf) == nullptr) { + throw std::runtime_error("Error saving audio file: failed to open file."); + } + + auto tensor_ = tensor; + if (channels_first) { + tensor_ = tensor_.t(); + } + + const int64_t frames_per_chunk = 65536; + for (int64_t i = 0; i < tensor_.size(0); i += frames_per_chunk) { + auto chunk = tensor_.index({Slice(i, i + frames_per_chunk), Slice()}); + chunk = unnormalize_wav(chunk).contiguous(); + + const size_t numel = chunk.numel(); + if (sox_write(sf, chunk.data_ptr(), numel) != numel) { + throw std::runtime_error( + "Error saving audio file: failed to write the entier buffer."); + } + } +} + +} // namespace sox_io +} // namespace torchaudio diff --git a/torchaudio/csrc/sox_io.h b/torchaudio/csrc/sox_io.h new file mode 100644 index 0000000000..5288e911e8 --- /dev/null +++ b/torchaudio/csrc/sox_io.h @@ -0,0 +1,41 @@ +#ifndef TORCHAUDIO_SOX_IO_H +#define TORCHAUDIO_SOX_IO_H + +#include +#include + +namespace torchaudio { +namespace sox_io { + +struct SignalInfo : torch::CustomClassHolder { + int64_t sample_rate; + int64_t num_channels; + int64_t num_frames; + + SignalInfo( + const int64_t sample_rate_, + const int64_t num_channels_, + const int64_t num_frames_); + int64_t getSampleRate() const; + int64_t getNumChannels() const; + int64_t getNumFrames() const; +}; + +c10::intrusive_ptr get_info(const std::string& path); + +c10::intrusive_ptr load_audio_file( + const std::string& path, + const int64_t frame_offset = 0, + const int64_t num_frames = -1, + const bool normalize = true, + const bool channels_first = true); + +void save_audio_file( + const std::string& file_name, + const c10::intrusive_ptr& signal, + const double compression = 0.); + +} // namespace sox_io +} // namespace torchaudio + +#endif diff --git a/torchaudio/csrc/sox_utils.cpp b/torchaudio/csrc/sox_utils.cpp new file mode 100644 index 0000000000..c1fd8383a8 --- /dev/null +++ b/torchaudio/csrc/sox_utils.cpp @@ -0,0 +1,245 @@ +#include +#include +#include + +namespace torchaudio { +namespace sox_utils { + +TensorSignal::TensorSignal( + torch::Tensor tensor_, + int64_t sample_rate_, + bool channels_first_) + : tensor(tensor_), + sample_rate(sample_rate_), + channels_first(channels_first_){}; + +torch::Tensor TensorSignal::getTensor() const { + return tensor; +} +int64_t TensorSignal::getSampleRate() const { + return sample_rate; +} +bool TensorSignal::getChannelsFirst() const { + return channels_first; +} + +SoxFormat::SoxFormat(sox_format_t* fd) noexcept : fd_(fd) {} +SoxFormat::~SoxFormat() { + if (fd_ != nullptr) { + sox_close(fd_); + } +} +sox_format_t* SoxFormat::operator->() const noexcept { + return fd_; +} +SoxFormat::operator sox_format_t*() const noexcept { + return fd_; +} + +void validate_input_file(const SoxFormat& sf) { + if (static_cast(sf) == nullptr) { + throw std::runtime_error("Error loading audio file: failed to open file."); + } + if (sf->encoding.encoding == SOX_ENCODING_UNKNOWN) { + throw std::runtime_error("Error loading audio file: unknown encoding."); + } + if (sf->signal.length == 0) { + throw std::runtime_error("Error reading audio file: unkown length."); + } +} + +void validate_input_tensor(const torch::Tensor tensor) { + if (!tensor.device().is_cpu()) { + throw std::runtime_error("Input tensor has to be on CPU."); + } + + if (tensor.ndimension() != 2) { + throw std::runtime_error("Input tensor has to be 2D."); + } + + const auto dtype = tensor.dtype(); + if (!(dtype == torch::kFloat32 || dtype == torch::kInt32 || + dtype == torch::kInt16 || dtype == torch::kUInt8)) { + throw std::runtime_error( + "Input tensor has to be one of float32, int32, int16 or uint8 type."); + } +} + +caffe2::TypeMeta get_dtype( + const sox_encoding_t encoding, + const unsigned precision) { + const auto dtype = [&]() { + switch (encoding) { + case SOX_ENCODING_UNSIGNED: // 8-bit PCM WAV + return torch::kUInt8; + case SOX_ENCODING_SIGN2: // 16-bit or 32-bit PCM WAV + switch (precision) { + case 16: + return torch::kInt16; + case 32: + return torch::kInt32; + default: + throw std::runtime_error( + "Only 16 and 32 bits are supported for signed PCM."); + } + default: + // default to float32 for the other formats, including + // 32-bit flaoting-point WAV, + // MP3, + // FLAC, + // VORBIS etc... + return torch::kFloat32; + } + }(); + return c10::scalarTypeToTypeMeta(dtype); +} + +torch::Tensor convert_to_tensor( + sox_sample_t* buffer, + const int32_t num_samples, + const int32_t num_channels, + const caffe2::TypeMeta dtype, + const bool normalize, + const bool channels_first) { + auto t = torch::from_blob( + buffer, {num_samples / num_channels, num_channels}, torch::kInt32); + // Note: Tensor created from_blob does not own data but borrwos + // So make sure to create a new copy after processing samples. + if (normalize || dtype == torch::kFloat32) { + t = t.to(torch::kFloat32); + t *= (t > 0) / 2147483647. + (t < 0) / 2147483648.; + } else if (dtype == torch::kInt32) { + t = t.clone(); + } else if (dtype == torch::kInt16) { + t.floor_divide_(1 << 16); + t = t.to(torch::kInt16); + } else if (dtype == torch::kUInt8) { + t.floor_divide_(1 << 24); + t += 128; + t = t.to(torch::kUInt8); + } else { + throw std::runtime_error("Unsupported dtype."); + } + if (channels_first) { + t = t.transpose(1, 0); + } + return t.contiguous(); +} + +torch::Tensor unnormalize_wav(const torch::Tensor input_tensor) { + const auto dtype = input_tensor.dtype(); + auto tensor = input_tensor; + if (dtype == torch::kFloat32) { + double multi_pos = 2147483647.; + double multi_neg = -2147483648.; + auto mult = (tensor > 0) * multi_pos - (tensor < 0) * multi_neg; + tensor = tensor.to(torch::dtype(torch::kFloat64)); + tensor *= mult; + tensor.clamp_(multi_neg, multi_pos); + tensor = tensor.to(torch::dtype(torch::kInt32)); + } else if (dtype == torch::kInt32) { + // already denormalized + } else if (dtype == torch::kInt16) { + tensor = tensor.to(torch::dtype(torch::kInt32)); + tensor *= ((tensor != 0) * 65536); + } else if (dtype == torch::kUInt8) { + tensor = tensor.to(torch::dtype(torch::kInt32)); + tensor -= 128; + tensor *= 16777216; + } else { + throw std::runtime_error("Unexpected dtype."); + } + return tensor; +} + +const std::string get_filetype(const std::string path) { + std::string ext = path.substr(path.find_last_of(".") + 1); + std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); + return ext; +} + +sox_encoding_t get_encoding( + const std::string filetype, + const caffe2::TypeMeta dtype) { + if (filetype == "mp3") + return SOX_ENCODING_MP3; + if (filetype == "flac") + return SOX_ENCODING_FLAC; + if (filetype == "ogg" || filetype == "vorbis") + return SOX_ENCODING_VORBIS; + if (filetype == "wav") { + if (dtype == torch::kUInt8) + return SOX_ENCODING_UNSIGNED; + if (dtype == torch::kInt16) + return SOX_ENCODING_SIGN2; + if (dtype == torch::kInt32) + return SOX_ENCODING_SIGN2; + if (dtype == torch::kFloat32) + return SOX_ENCODING_FLOAT; + throw std::runtime_error("Unsupported dtype."); + } + throw std::runtime_error("Unsupported file type."); +} + +unsigned get_precision( + const std::string filetype, + const caffe2::TypeMeta dtype) { + if (filetype == "mp3") + return SOX_UNSPEC; + if (filetype == "flac") + return 24; + if (filetype == "ogg" || filetype == "vorbis") + return SOX_UNSPEC; + if (filetype == "wav") { + if (dtype == torch::kUInt8) + return 8; + if (dtype == torch::kInt16) + return 16; + if (dtype == torch::kInt32) + return 32; + if (dtype == torch::kFloat32) + return 32; + throw std::runtime_error("Unsupported dtype."); + } + throw std::runtime_error("Unsupported file type."); +} + +sox_signalinfo_t get_signalinfo( + const torch::Tensor& tensor, + const int64_t sample_rate, + const bool channels_first, + const std::string filetype) { + return sox_signalinfo_t{ + /*rate=*/static_cast(sample_rate), + /*channels=*/static_cast(tensor.size(channels_first ? 0 : 1)), + /*precision=*/get_precision(filetype, tensor.dtype()), + /*length=*/static_cast(tensor.numel())}; +} + +sox_encodinginfo_t get_encodinginfo( + const std::string filetype, + const caffe2::TypeMeta dtype, + const double compression) { + const double compression_ = [&]() { + if (filetype == "mp3") + return compression; + if (filetype == "flac") + return compression; + if (filetype == "ogg" || filetype == "vorbis") + return compression; + if (filetype == "wav") + return 0.; + throw std::runtime_error("Unsupported file type."); + }(); + + return sox_encodinginfo_t{/*encoding=*/get_encoding(filetype, dtype), + /*bits_per_sample=*/get_precision(filetype, dtype), + /*compression=*/compression_, + /*reverse_bytes=*/sox_option_default, + /*reverse_nibbles=*/sox_option_default, + /*reverse_bits=*/sox_option_default, + /*opposite_endian=*/sox_false}; +} + +} // namespace sox_utils +} // namespace torchaudio diff --git a/torchaudio/csrc/sox_utils.h b/torchaudio/csrc/sox_utils.h new file mode 100644 index 0000000000..665187c840 --- /dev/null +++ b/torchaudio/csrc/sox_utils.h @@ -0,0 +1,100 @@ +#ifndef TORCHAUDIO_SOX_UTILS_H +#define TORCHAUDIO_SOX_UTILS_H + +#include +#include + +namespace torchaudio { +namespace sox_utils { + +struct TensorSignal : torch::CustomClassHolder { + torch::Tensor tensor; + int64_t sample_rate; + bool channels_first; + + TensorSignal( + torch::Tensor tensor_, + int64_t sample_rate_, + bool channels_first_); + + torch::Tensor getTensor() const; + int64_t getSampleRate() const; + bool getChannelsFirst() const; +}; + +/// helper class to automatically close sox_format_t* +struct SoxFormat { + explicit SoxFormat(sox_format_t* fd) noexcept; + SoxFormat(const SoxFormat& other) = delete; + SoxFormat(SoxFormat&& other) = delete; + SoxFormat& operator=(const SoxFormat& other) = delete; + SoxFormat& operator=(SoxFormat&& other) = delete; + ~SoxFormat(); + sox_format_t* operator->() const noexcept; + operator sox_format_t*() const noexcept; + + private: + sox_format_t* fd_; +}; + +/// +/// Verify that input file is found, has known encoding, and not empty +void validate_input_file(const SoxFormat& sf); + +/// +/// Verify that input Tensor is 2D, CPU and either uin8, int16, int32 or float32 +void validate_input_tensor(const torch::Tensor); + +/// +/// Get target dtype for the given encoding and precision. +caffe2::TypeMeta get_dtype( + const sox_encoding_t encoding, + const unsigned precision); + +/// +/// Convert sox_sample_t buffer to uint8/int16/int32/float32 Tensor +/// NOTE: This function might modify the values in the input buffer to +/// reduce the number of memory copy. +/// @param buffer Pointer to buffer that contains audio data. +/// @param num_samples The number of samples to read. +/// @param num_channels The number of channels. Used to reshape the resulting +/// Tensor. +/// @param dtype Target dtype. Determines the output dtype and value range in +/// conjunction with normalization. +/// @param noramlize Perform normalization. Only effective when dtype is not +/// kFloat32. When effective, the output tensor is kFloat32 type and value range +/// is [-1.0, 1.0] +/// @param channels_first When True, output Tensor has shape of [num_channels, +/// num_frames]. +torch::Tensor convert_to_tensor( + sox_sample_t* buffer, + const int32_t num_samples, + const int32_t num_channels, + const caffe2::TypeMeta dtype, + const bool normalize, + const bool channels_first); + +/// +/// Convert float32/int32/int16/uint8 Tensor to int32 for Torch -> Sox +/// conversion. +torch::Tensor unnormalize_wav(const torch::Tensor); + +/// Extract extension from file path +const std::string get_filetype(const std::string path); + +/// Get sox_signalinfo_t for passing a torch::Tensor object. +sox_signalinfo_t get_signalinfo( + const torch::Tensor& tensor, + const int64_t sample_rate, + const bool channels_first, + const std::string filetype); + +/// Get sox_encofinginfo_t for saving audoi file +sox_encodinginfo_t get_encodinginfo( + const std::string filetype, + const caffe2::TypeMeta dtype, + const double compression); + +} // namespace sox_utils +} // namespace torchaudio +#endif diff --git a/torchaudio/csrc/typedefs.cpp b/torchaudio/csrc/typedefs.cpp deleted file mode 100644 index 7b81d665dc..0000000000 --- a/torchaudio/csrc/typedefs.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include - -namespace torchaudio { -SignalInfo::SignalInfo( - const int64_t sample_rate_, - const int64_t num_channels_, - const int64_t num_samples_) - : sample_rate(sample_rate_), - num_channels(num_channels_), - num_samples(num_samples_){}; - -int64_t SignalInfo::getSampleRate() const { - return sample_rate; -} - -int64_t SignalInfo::getNumChannels() const { - return num_channels; -} - -int64_t SignalInfo::getNumSamples() const { - return num_samples; -} -} // namespace torchaudio diff --git a/torchaudio/csrc/typedefs.h b/torchaudio/csrc/typedefs.h deleted file mode 100644 index 646ed09f3d..0000000000 --- a/torchaudio/csrc/typedefs.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef TORCHAUDIO_TYPDEFS_H -#define TORCHAUDIO_TYPDEFS_H - -#include - -namespace torchaudio { -struct SignalInfo : torch::CustomClassHolder { - int64_t sample_rate; - int64_t num_channels; - int64_t num_samples; - - SignalInfo( - const int64_t sample_rate_, - const int64_t num_channels_, - const int64_t num_samples_); - int64_t getSampleRate() const; - int64_t getNumChannels() const; - int64_t getNumSamples() const; -}; - -} // namespace torchaudio - -#endif diff --git a/torchaudio/extension/extension.py b/torchaudio/extension/extension.py index 4a2ab82124..b01ba13e39 100644 --- a/torchaudio/extension/extension.py +++ b/torchaudio/extension/extension.py @@ -12,38 +12,9 @@ def _init_extension(): _init_script_module(ext) else: warnings.warn('torchaudio C++ extension is not available.') - _init_dummy_module() def _init_script_module(module): path = importlib.util.find_spec(module).origin torch.classes.load_library(path) torch.ops.load_library(path) - - -def _init_dummy_module(): - class SignalInfo: - """Data class for audio format information - - Used when torchaudio C++ extension is not available for annotating - sox_io backend functions so that torchaudio is still importable - without extension. - This class has to implement the same interface as C++ equivalent. - """ - def __init__(self, sample_rate: int, num_channels: int, num_samples: int): - self.sample_rate = sample_rate - self.num_channels = num_channels - self.num_samples = num_samples - - def get_sample_rate(self): - return self.sample_rate - - def get_num_channels(self): - return self.num_channels - - def get_num_samples(self): - return self.num_samples - - DummyModule = namedtuple('torchaudio', ['SignalInfo']) - module = DummyModule(SignalInfo) - setattr(torch.classes, 'torchaudio', module) diff --git a/torchaudio/functional.py b/torchaudio/functional.py index 28cb6a3fa2..78c8c594c9 100644 --- a/torchaudio/functional.py +++ b/torchaudio/functional.py @@ -485,9 +485,10 @@ def complex_norm( Returns: Tensor: Power of the normed input tensor. Shape of `(..., )` """ - if power == 1.0: - return torch.norm(complex_tensor, 2, -1) - return torch.norm(complex_tensor, 2, -1).pow(power) + + # Replace by torch.norm once issue is fixed + # https://github.com/pytorch/pytorch/issues/34279 + return complex_tensor.pow(2.).sum(-1).pow(0.5 * power) def angle( diff --git a/torchaudio/models/_wavernn.py b/torchaudio/models/_wavernn.py index 04155fb87c..cd2e89a10c 100644 --- a/torchaudio/models/_wavernn.py +++ b/torchaudio/models/_wavernn.py @@ -1,105 +1,331 @@ +from typing import List + +import torch from torch import Tensor from torch import nn -__all__ = ["_ResBlock", "_MelResNet"] +__all__ = ["_ResBlock", "_MelResNet", "_Stretch2d", "_UpsampleNetwork", "_WaveRNN"] class _ResBlock(nn.Module): - r"""This is a ResNet block layer. This layer is based on the paper "Deep Residual Learning - for Image Recognition". Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun. CVPR, 2016. - It is a block used in WaveRNN. WaveRNN is based on the paper "Efficient Neural Audio Synthesis". - Nal Kalchbrenner, Erich Elsen, Karen Simonyan, Seb Noury, Norman Casagrande, Edward Lockhart, - Florian Stimberg, Aaron van den Oord, Sander Dieleman, Koray Kavukcuoglu. arXiv:1802.08435, 2018. + r"""ResNet block based on "Deep Residual Learning for Image Recognition" + + The paper link is https://arxiv.org/pdf/1512.03385.pdf. Args: - num_dims: the number of compute dimensions in the input (default=128). + n_freq: the number of bins in a spectrogram (default=128) - Examples:: - >>> resblock = _ResBlock(num_dims=128) - >>> input = torch.rand(10, 128, 512) - >>> output = resblock(input) + Examples + >>> resblock = _ResBlock() + >>> input = torch.rand(10, 128, 512) # a random spectrogram + >>> output = resblock(input) # shape: (10, 128, 512) """ - def __init__(self, num_dims: int = 128) -> None: + def __init__(self, n_freq: int = 128) -> None: super().__init__() self.resblock_model = nn.Sequential( - nn.Conv1d(in_channels=num_dims, out_channels=num_dims, kernel_size=1, bias=False), - nn.BatchNorm1d(num_dims), + nn.Conv1d(in_channels=n_freq, out_channels=n_freq, kernel_size=1, bias=False), + nn.BatchNorm1d(n_freq), nn.ReLU(inplace=True), - nn.Conv1d(in_channels=num_dims, out_channels=num_dims, kernel_size=1, bias=False), - nn.BatchNorm1d(num_dims) + nn.Conv1d(in_channels=n_freq, out_channels=n_freq, kernel_size=1, bias=False), + nn.BatchNorm1d(n_freq) ) - def forward(self, x: Tensor) -> Tensor: + def forward(self, specgram: Tensor) -> Tensor: r"""Pass the input through the _ResBlock layer. - Args: - x: the input sequence to the _ResBlock layer (required). + specgram (Tensor): the input sequence to the _ResBlock layer (n_batch, n_freq, n_time). - Shape: - - x: :math:`(N, S, T)`. - - output: :math:`(N, S, T)`. - where N is the batch size, S is the number of input sequence, - T is the length of input sequence. + Return: + Tensor shape: (n_batch, n_freq, n_time) """ - residual = x - return self.resblock_model(x) + residual + return self.resblock_model(specgram) + specgram class _MelResNet(nn.Module): - r"""This is a MelResNet layer based on a stack of ResBlocks. It is a block used in WaveRNN. - WaveRNN is based on the paper "Efficient Neural Audio Synthesis". Nal Kalchbrenner, Erich Elsen, - Karen Simonyan, Seb Noury, Norman Casagrande, Edward Lockhart, Florian Stimberg, Aaron van den Oord, - Sander Dieleman, Koray Kavukcuoglu. arXiv:1802.08435, 2018. + r"""MelResNet layer uses a stack of ResBlocks on spectrogram. Args: - res_blocks: the number of ResBlock in stack (default=10). - input_dims: the number of input sequence (default=100). - hidden_dims: the number of compute dimensions (default=128). - output_dims: the number of output sequence (default=128). - pad: the number of kernal size (pad * 2 + 1) in the first Conv1d layer (default=2). - - Examples:: - >>> melresnet = _MelResNet(res_blocks=10, input_dims=100, - hidden_dims=128, output_dims=128, pad=2) - >>> input = torch.rand(10, 100, 512) - >>> output = melresnet(input) + n_res_block: the number of ResBlock in stack (default=10) + n_freq: the number of bins in a spectrogram (default=128) + n_hidden: the number of hidden dimensions (default=128) + n_output: the number of output dimensions (default=128) + kernel_size: the number of kernel size in the first Conv1d layer (default=5) + + Examples + >>> melresnet = _MelResNet() + >>> input = torch.rand(10, 128, 512) # a random spectrogram + >>> output = melresnet(input) # shape: (10, 128, 508) """ - def __init__(self, res_blocks: int = 10, - input_dims: int = 100, - hidden_dims: int = 128, - output_dims: int = 128, - pad: int = 2) -> None: + def __init__(self, + n_res_block: int = 10, + n_freq: int = 128, + n_hidden: int = 128, + n_output: int = 128, + kernel_size: int = 5) -> None: super().__init__() - kernel_size = pad * 2 + 1 - ResBlocks = [] - - for i in range(res_blocks): - ResBlocks.append(_ResBlock(hidden_dims)) + ResBlocks = [_ResBlock(n_hidden) for _ in range(n_res_block)] self.melresnet_model = nn.Sequential( - nn.Conv1d(in_channels=input_dims, out_channels=hidden_dims, kernel_size=kernel_size, bias=False), - nn.BatchNorm1d(hidden_dims), + nn.Conv1d(in_channels=n_freq, out_channels=n_hidden, kernel_size=kernel_size, bias=False), + nn.BatchNorm1d(n_hidden), nn.ReLU(inplace=True), *ResBlocks, - nn.Conv1d(in_channels=hidden_dims, out_channels=output_dims, kernel_size=1) + nn.Conv1d(in_channels=n_hidden, out_channels=n_output, kernel_size=1) ) - def forward(self, x: Tensor) -> Tensor: + def forward(self, specgram: Tensor) -> Tensor: r"""Pass the input through the _MelResNet layer. + Args: + specgram (Tensor): the input sequence to the _MelResNet layer (n_batch, n_freq, n_time). + + Return: + Tensor shape: (n_batch, n_output, n_time - kernel_size + 1) + """ + + return self.melresnet_model(specgram) + + +class _Stretch2d(nn.Module): + r"""Upscale the frequency and time dimensions of a spectrogram. + + Args: + time_scale: the scale factor in time dimension + freq_scale: the scale factor in frequency dimension + + Examples + >>> stretch2d = _Stretch2d(time_scale=10, freq_scale=5) + + >>> input = torch.rand(10, 100, 512) # a random spectrogram + >>> output = stretch2d(input) # shape: (10, 500, 5120) + """ + + def __init__(self, + time_scale: int, + freq_scale: int) -> None: + super().__init__() + + self.freq_scale = freq_scale + self.time_scale = time_scale + + def forward(self, specgram: Tensor) -> Tensor: + r"""Pass the input through the _Stretch2d layer. Args: - x: the input sequence to the _MelResNet layer (required). + specgram (Tensor): the input sequence to the _Stretch2d layer (..., n_freq, n_time). - Shape: - - x: :math:`(N, S, T)`. - - output: :math:`(N, P, T - 2 * pad)`. - where N is the batch size, S is the number of input sequence, - P is the number of output sequence, T is the length of input sequence. + Return: + Tensor shape: (..., n_freq * freq_scale, n_time * time_scale) """ - return self.melresnet_model(x) + return specgram.repeat_interleave(self.freq_scale, -2).repeat_interleave(self.time_scale, -1) + + +class _UpsampleNetwork(nn.Module): + r"""Upscale the dimensions of a spectrogram. + + Args: + upsample_scales: the list of upsample scales + n_res_block: the number of ResBlock in stack (default=10) + n_freq: the number of bins in a spectrogram (default=128) + n_hidden: the number of hidden dimensions (default=128) + n_output: the number of output dimensions (default=128) + kernel_size: the number of kernel size in the first Conv1d layer (default=5) + + Examples + >>> upsamplenetwork = _UpsampleNetwork(upsample_scales=[4, 4, 16]) + >>> input = torch.rand(10, 128, 10) # a random spectrogram + >>> output = upsamplenetwork(input) # shape: (10, 1536, 128), (10, 1536, 128) + """ + + def __init__(self, + upsample_scales: List[int], + n_res_block: int = 10, + n_freq: int = 128, + n_hidden: int = 128, + n_output: int = 128, + kernel_size: int = 5) -> None: + super().__init__() + + total_scale = 1 + for upsample_scale in upsample_scales: + total_scale *= upsample_scale + + self.indent = (kernel_size - 1) // 2 * total_scale + self.resnet = _MelResNet(n_res_block, n_freq, n_hidden, n_output, kernel_size) + self.resnet_stretch = _Stretch2d(total_scale, 1) + + up_layers = [] + for scale in upsample_scales: + stretch = _Stretch2d(scale, 1) + conv = nn.Conv2d(in_channels=1, + out_channels=1, + kernel_size=(1, scale * 2 + 1), + padding=(0, scale), + bias=False) + conv.weight.data.fill_(1. / (scale * 2 + 1)) + up_layers.append(stretch) + up_layers.append(conv) + self.upsample_layers = nn.Sequential(*up_layers) + + def forward(self, specgram: Tensor) -> Tensor: + r"""Pass the input through the _UpsampleNetwork layer. + + Args: + specgram (Tensor): the input sequence to the _UpsampleNetwork layer (n_batch, n_freq, n_time) + + Return: + Tensor shape: (n_batch, n_freq, (n_time - kernel_size + 1) * total_scale), + (n_batch, n_output, (n_time - kernel_size + 1) * total_scale) + where total_scale is the product of all elements in upsample_scales. + """ + + resnet_output = self.resnet(specgram).unsqueeze(1) + resnet_output = self.resnet_stretch(resnet_output) + resnet_output = resnet_output.squeeze(1) + + specgram = specgram.unsqueeze(1) + upsampling_output = self.upsample_layers(specgram) + upsampling_output = upsampling_output.squeeze(1)[:, :, self.indent:-self.indent] + + return upsampling_output, resnet_output + + +class _WaveRNN(nn.Module): + r"""WaveRNN model based on the implementation from `fatchord `_. + + The original implementation was introduced in + `"Efficient Neural Audio Synthesis" `_. + The input channels of waveform and spectrogram have to be 1. The product of + `upsample_scales` must equal `hop_length`. + + Args: + upsample_scales: the list of upsample scales + n_bits: the bits of output waveform + sample_rate: the rate of audio dimensions (samples per second) + hop_length: the number of samples between the starts of consecutive frames + n_res_block: the number of ResBlock in stack (default=10) + n_rnn: the dimension of RNN layer (default=512) + n_fc: the dimension of fully connected layer (default=512) + kernel_size: the number of kernel size in the first Conv1d layer (default=5) + n_freq: the number of bins in a spectrogram (default=128) + n_hidden: the number of hidden dimensions (default=128) + n_output: the number of output dimensions (default=128) + mode: the mode of waveform in ['waveform', 'mol'] (default='waveform') + + Example + >>> wavernn = _waveRNN(upsample_scales=[5,5,8], n_bits=9, sample_rate=24000, hop_length=200) + >>> waveform, sample_rate = torchaudio.load(file) + >>> # waveform shape: (n_batch, n_channel, (n_time - kernel_size + 1) * hop_length) + >>> specgram = MelSpectrogram(sample_rate)(waveform) # shape: (n_batch, n_channel, n_freq, n_time) + >>> output = wavernn(waveform, specgram) + >>> # output shape: (n_batch, n_channel, (n_time - kernel_size + 1) * hop_length, 2 ** n_bits) + """ + + def __init__(self, + upsample_scales: List[int], + n_bits: int, + sample_rate: int, + hop_length: int, + n_res_block: int = 10, + n_rnn: int = 512, + n_fc: int = 512, + kernel_size: int = 5, + n_freq: int = 128, + n_hidden: int = 128, + n_output: int = 128, + mode: str = 'waveform') -> None: + super().__init__() + + self.mode = mode + self.kernel_size = kernel_size + + if self.mode == 'waveform': + self.n_classes = 2 ** n_bits + elif self.mode == 'mol': + self.n_classes = 30 + else: + raise ValueError(f"Expected mode: `waveform` or `mol`, but found {self.mode}") + + self.n_rnn = n_rnn + self.n_aux = n_output // 4 + self.hop_length = hop_length + self.sample_rate = sample_rate + + total_scale = 1 + for upsample_scale in upsample_scales: + total_scale *= upsample_scale + if total_scale != self.hop_length: + raise ValueError(f"Expected: total_scale == hop_length, but found {total_scale} != {hop_length}") + + self.upsample = _UpsampleNetwork(upsample_scales, n_res_block, n_freq, n_hidden, n_output, kernel_size) + self.fc = nn.Linear(n_freq + self.n_aux + 1, n_rnn) + + self.rnn1 = nn.GRU(n_rnn, n_rnn, batch_first=True) + self.rnn2 = nn.GRU(n_rnn + self.n_aux, n_rnn, batch_first=True) + + self.relu1 = nn.ReLU(inplace=True) + self.relu2 = nn.ReLU(inplace=True) + + self.fc1 = nn.Linear(n_rnn + self.n_aux, n_fc) + self.fc2 = nn.Linear(n_fc + self.n_aux, n_fc) + self.fc3 = nn.Linear(n_fc, self.n_classes) + + def forward(self, waveform: Tensor, specgram: Tensor) -> Tensor: + r"""Pass the input through the _WaveRNN model. + + Args: + waveform: the input waveform to the _WaveRNN layer (n_batch, 1, (n_time - kernel_size + 1) * hop_length) + specgram: the input spectrogram to the _WaveRNN layer (n_batch, 1, n_freq, n_time) + + Return: + Tensor shape: (n_batch, 1, (n_time - kernel_size + 1) * hop_length, 2 ** n_bits) + """ + + assert waveform.size(1) == 1, 'Require the input channel of waveform is 1' + assert specgram.size(1) == 1, 'Require the input channel of specgram is 1' + # remove channel dimension until the end + waveform, specgram = waveform.squeeze(1), specgram.squeeze(1) + + batch_size = waveform.size(0) + h1 = torch.zeros(1, batch_size, self.n_rnn, dtype=waveform.dtype, device=waveform.device) + h2 = torch.zeros(1, batch_size, self.n_rnn, dtype=waveform.dtype, device=waveform.device) + # output of upsample: + # specgram: (n_batch, n_freq, (n_time - kernel_size + 1) * total_scale) + # aux: (n_batch, n_output, (n_time - kernel_size + 1) * total_scale) + specgram, aux = self.upsample(specgram) + specgram = specgram.transpose(1, 2) + aux = aux.transpose(1, 2) + + aux_idx = [self.n_aux * i for i in range(5)] + a1 = aux[:, :, aux_idx[0]:aux_idx[1]] + a2 = aux[:, :, aux_idx[1]:aux_idx[2]] + a3 = aux[:, :, aux_idx[2]:aux_idx[3]] + a4 = aux[:, :, aux_idx[3]:aux_idx[4]] + + x = torch.cat([waveform.unsqueeze(-1), specgram, a1], dim=-1) + x = self.fc(x) + res = x + x, _ = self.rnn1(x, h1) + + x = x + res + res = x + x = torch.cat([x, a2], dim=-1) + x, _ = self.rnn2(x, h2) + + x = x + res + x = torch.cat([x, a3], dim=-1) + x = self.fc1(x) + x = self.relu1(x) + + x = torch.cat([x, a4], dim=-1) + x = self.fc2(x) + x = self.relu2(x) + x = self.fc3(x) + + # bring back channel dimension + return x.unsqueeze(1) diff --git a/torchaudio/sox_effects/__init__.py b/torchaudio/sox_effects/__init__.py index 115b70c895..507dc5c3af 100644 --- a/torchaudio/sox_effects/__init__.py +++ b/torchaudio/sox_effects/__init__.py @@ -9,4 +9,6 @@ if _mod_utils.is_module_available('torchaudio._torchaudio'): + import atexit init_sox_effects() + atexit.register(shutdown_sox_effects) diff --git a/torchaudio/sox_effects/sox_effects.py b/torchaudio/sox_effects/sox_effects.py index 6a6b5be0a5..0aee312126 100644 --- a/torchaudio/sox_effects/sox_effects.py +++ b/torchaudio/sox_effects/sox_effects.py @@ -1,4 +1,3 @@ -import atexit from typing import Any, Callable, List, Optional, Tuple, Union import torch @@ -13,19 +12,8 @@ from torchaudio import _torchaudio -_SOX_INITIALIZED: Optional[bool] = False -# This variable has a micro lifecycle. (False -> True -> None) -# False: Not initialized -# True: Initialized -# None: Already shut down (should not be initialized again.) - -_SOX_SUCCESS_CODE = 0 -# defined at -# https://fossies.org/dox/sox-14.4.2/sox_8h.html#a8e07e80cebeff3339265d89c387cea93a9ef2b87ec303edfe40751d9a85fadeeb - - @_mod_utils.requires_module('torchaudio._torchaudio') -def init_sox_effects() -> int: +def init_sox_effects() -> None: """Initialize resources required to use ``SoxEffectsChain`` You do not need to call this function manually. It is called automatically. @@ -33,50 +21,26 @@ def init_sox_effects() -> int: Once initialized, you do not need to call this function again across the multiple call of ``SoxEffectsChain.sox_build_flow_effects``, though it is safe to do so as long as ``shutdown_sox_effects`` is not called yet. - Once ``shutdown_sox_effects`` is called, you can no longer use SoX effects and calling - this function results in `RuntimeError`. + Once ``shutdown_sox_effects`` is called, you can no longer use SoX effects and + initializing again will result in error. Note: This function is not required for simple loading. - - Returns: - int: Code corresponding to sox_error_t enum. See - https://fossies.org/dox/sox-14.4.2/sox_8h.html#a8e07e80cebeff3339265d89c387cea93 """ - global _SOX_INITIALIZED - if _SOX_INITIALIZED is None: - raise RuntimeError('SoX effects chain has been already shut down. Can not initialize again.') - if not _SOX_INITIALIZED: - code = _torchaudio.initialize_sox() - if code == _SOX_SUCCESS_CODE: - _SOX_INITIALIZED = True - atexit.register(shutdown_sox_effects) - return code - return _SOX_SUCCESS_CODE + torch.ops.torchaudio.sox_effects_initialize_sox_effects() @_mod_utils.requires_module("torchaudio._torchaudio") -def shutdown_sox_effects() -> int: +def shutdown_sox_effects() -> None: """Clean up resources required to use ``SoxEffectsChain`` You do not need to call this function manually. It is called automatically. It is safe to call this function multiple times. - Once ``shutdown_sox_effects`` is called, you can no longer use SoX effects and calling - this function results in `RuntimeError`. - - - Returns: - int: Code corresponding to sox_error_t enum. See - https://fossies.org/dox/sox-14.4.2/sox_8h.html#a8e07e80cebeff3339265d89c387cea93 + Once ``shutdown_sox_effects`` is called, you can no longer use SoX effects and + initializing again will result in error. """ - global _SOX_INITIALIZED - if _SOX_INITIALIZED: - code = _torchaudio.shutdown_sox() - if code == _SOX_INITIALIZED: - _SOX_INITIALIZED = None - return code - return _SOX_SUCCESS_CODE + torch.ops.torchaudio.sox_effects_shutdown_sox_effects() @_mod_utils.requires_module('torchaudio._torchaudio') @@ -88,7 +52,7 @@ def effect_names() -> List[str]: Example >>> EFFECT_NAMES = torchaudio.sox_effects.effect_names() """ - return _torchaudio.get_effect_names() + return torch.ops.torchaudio.sox_effects_list_effects() @_mod_utils.requires_module('torchaudio._torchaudio')