Unverified Commit 3ab521fa authored by moto's avatar moto Committed by GitHub
Browse files

Refactor libtorchaudio example (#1486)

parent 7fd5fce4
......@@ -14,7 +14,4 @@ message("libtorchaudio CMakeLists: ${TORCH_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_subdirectory(../.. libtorchaudio)
add_executable(main main.cpp)
target_link_libraries(main "${TORCH_LIBRARIES}" "${TORCHAUDIO_LIBRARY}")
set_property(TARGET main PROPERTY CXX_STANDARD 14)
add_subdirectory(augmentation)
# Example usage: libtorchaudio
# Libtorchaudio Examples
This example demonstrates how you can use torchaudio's I/O features in C++ application, in addition to PyTorch's operations.
* [Augmentation](./augmentation)
To try this example, simply run `./run.sh`. This script will
## Build
1. Create an audio preprocessing pipeline with TorchScript and dump it to a file.
2. Build the application using `libtorch` and `libtorchaudio`.
3. Execute the preprocessing pipeline on an example audio.
The example applications in this directory depend on `libtorch` and `libtorchaudio`.
If you have a working `PyTorch`, you already have `libtorch`.
Please refer to [this tutorial](https://pytorch.org/tutorials/advanced/torch_script_custom_classes.html) for the use of `libtorch` and TorchScript.
The detail of the preprocessing pipeline can be found in [`create_jittable_pipeline.py`](./create_jittable_pipeline.py).
`libtorchaudio` is the library of torchaudio's C++ components without Python component.
It is currently not distributed, and it will be built alongside with the applications.
The following commands will build `libtorchaudio` and applications.
```bash
mkdir build
cd build
cmake -GNinja \
-DCMAKE_PREFIX_PATH="$(python -c 'import torch;print(torch.utils.cmake_prefix_path)')" \
-DBUILD_SOX=ON \
-DBUILD_KALDI=OFF \
..
cmake --build .
```
For the usages of each application, refer to the corresponding application directory.
add_executable(augment main.cpp)
target_link_libraries(augment "${TORCH_LIBRARIES}" "${TORCHAUDIO_LIBRARY}")
set_property(TARGET augment PROPERTY CXX_STANDARD 14)
# Augmentation
This example demonstrates how you can use torchaudio's I/O features and augmentations in C++ application.
**NOTE**
This example uses `"sox_io"` backend, thus does not work on Windows.
## Steps
### 1. Create augmentation pipeline TorchScript file.
First, we implement our data process pipeline as a regular Python, and save it as a TorchScript object.
We will load and execute it in our C++ application. The C++ code is found in [`main.cpp`](./main.cpp).
```python
python create_jittable_pipeline.py \
--rir-path "../data/rir.wav" \
--output-path "./pipeline.zip"
```
### 2. Build the application
Please refer to [the top level README.md](../README.md)
### 3. Run the application
Now we run the C++ application `augment`, with the TorchScript object we created in Step.1 and an input audio file.
In [the top level directory](../)
```bash
input_audio_file="./data/input.wav"
./build/augmentation/augment ./augmentation/pipeline.zip "${input_audio_file}" "output.wav"
```
When you give a clean speech file, the output audio sounds like it's a phone conversation.
......@@ -14,9 +14,9 @@ class Pipeline(torch.nn.Module):
This example load waveform from a file then apply effects and save it to a file.
"""
def __init__(self):
def __init__(self, rir_path: str):
super().__init__()
rir, sample_rate = _load_rir()
rir, sample_rate = torchaudio.load(rir_path)
self.register_buffer('rir', rir)
self.rir_sample_rate: int = sample_rate
......@@ -44,8 +44,8 @@ class Pipeline(torch.nn.Module):
torchaudio.save(output_path, waveform, sample_rate)
def _create_jit_pipeline(output_path):
module = torch.jit.script(Pipeline())
def _create_jit_pipeline(rir_path, output_path):
module = torch.jit.script(Pipeline(rir_path))
print("*" * 40)
print("* Pipeline code")
print("*" * 40)
......@@ -59,16 +59,16 @@ def _get_path(*paths):
return os.path.join(os.path.dirname(__file__), *paths)
def _load_rir():
path = _get_path("data", "rir.wav")
return torchaudio.load(path)
def _parse_args():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--rir-path",
default=_get_path("..", "data", "rir.wav"),
help="Audio dara for room impulse response."
)
parser.add_argument(
"--output-path",
default=_get_path("data", "pipeline.zip"),
default=_get_path("pipeline.zip"),
help="Output JIT file."
)
return parser.parse_args()
......@@ -76,7 +76,7 @@ def _parse_args():
def _main():
args = _parse_args()
_create_jit_pipeline(args.output_path)
_create_jit_pipeline(args.rir_path, args.output_path)
if __name__ == '__main__':
......
......@@ -7,7 +7,7 @@ int main(int argc, char* argv[]) {
}
torch::jit::script::Module module;
std::cout << "Loading module from: " << argv[0] << std::endl;
std::cout << "Loading module from: " << argv[1] << std::endl;
try {
module = torch::jit::load(argv[1]);
} catch (const c10::Error &error) {
......
......@@ -3,22 +3,14 @@
set -eux
this_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
build_dir="${this_dir}/build"
data_dir="${this_dir}/data"
jit_file="${data_dir}/pipeline.zip"
input_file="${data_dir}/input.wav"
output_file="${data_dir}/output.wav"
cd "${this_dir}"
python create_jittable_pipeline.py
mkdir -p "${build_dir}"
cd "${build_dir}"
cmake -GNinja \
-DCMAKE_PREFIX_PATH="$(python -c 'import torch;print(torch.utils.cmake_prefix_path)')" \
-DBUILD_SOX=ON \
-DBUILD_KALDI=OFF \
..
cmake --build . --target main
./main "${jit_file}" "${input_file}" "${output_file}"
cmake --build .
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment