"...en/git@developer.sourcefind.cn:renzhc/diffusers_dcu.git" did not exist on "c6ae9b7df65bbeee93e49fc11e6044f9ce8b56e1"
Unverified Commit f4589714 authored by moto's avatar moto Committed by GitHub
Browse files

Add libtorchaudio cpp example (#1349)

parent fd4ee240
build
data/output.wav
data/pipeline.zip
cmake_minimum_required(VERSION 3.5)
project(libtorchaudio-cpp-example)
SET(BUILD_LIBTORCHAUDIO ON CACHE BOOL "Build libtorchaudio")
SET(BUILD_SOX ON CACHE BOOL "Build libsox into libtorchaudio")
SET(BUILD_KALDI OFF CACHE BOOL "Build Kaldi into libtorchaudio")
SET(BUILD_TRANSDUCER OFF CACHE BOOL "Build Python binding")
SET(BUILD_TORCHAUDIO_PYTHON_EXTENSION OFF CACHE BOOL "Build Python binding")
find_package(Torch REQUIRED)
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)
# Example usage: libtorchaudio
This example demonstrates how you can use torchaudio's I/O features in C++ application, in addition to PyTorch's operations.
To try this example, simply run `./run.sh`. This script will
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 detail of the preprocessing pipeline can be found in [`create_jittable_pipeline.py`](./create_jittable_pipeline.py).
#!/usr/bin/env python3
"""
Create a data preprocess pipeline that can be run with libtorchaudio
"""
import os
import argparse
import torch
import torchaudio
class Pipeline(torch.nn.Module):
"""Example audio process pipeline.
This example load waveform from a file then apply effects and save it to a file.
"""
def __init__(self):
super().__init__()
rir, sample_rate = _load_rir()
self.register_buffer('rir', rir)
self.rir_sample_rate: int = sample_rate
def forward(self, input_path: str, output_path: str):
torchaudio.sox_effects.init_sox_effects()
# 1. load audio
waveform, sample_rate = torchaudio.load(input_path)
# 2. Add background noise
alpha = 0.01
waveform = alpha * torch.randn_like(waveform) + (1 - alpha) * waveform
# 3. Reample the RIR filter to much the audio sample rate
rir, _ = torchaudio.sox_effects.apply_effects_tensor(
self.rir, self.rir_sample_rate, effects=[["rate", str(sample_rate)]])
rir = rir / torch.norm(rir, p=2)
rir = torch.flip(rir, [1])
# 4. Apply RIR filter
waveform = torch.nn.functional.pad(waveform, (rir.shape[1] - 1, 0))
waveform = torch.nn.functional.conv1d(waveform[None, ...], rir[None, ...])[0]
# Save
torchaudio.save(output_path, waveform, sample_rate)
def _create_jit_pipeline(output_path):
module = torch.jit.script(Pipeline())
print("*" * 40)
print("* Pipeline code")
print("*" * 40)
print()
print(module.code)
print("*" * 40)
module.save(output_path)
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(
"--output-path",
default=_get_path("data", "pipeline.zip"),
help="Output JIT file."
)
return parser.parse_args()
def _main():
args = _parse_args()
_create_jit_pipeline(args.output_path)
if __name__ == '__main__':
_main()
The files in this directory are originated from [VOiCES](https://iqtlabs.github.io/voices/) dataset, which is licensed under Creative Commos BY 4.0. They are modified to fit into the tutorial.
* `input.wav`: `VOiCES_devkit/source-16k/train/sp0307/Lab41-SRI-VOiCES-src-sp0307-ch127535-sg0042.wav`
* `rir.wav`: `VOiCES_devkit/distant-16k/room-response/rm1/impulse/Lab41-SRI-VOiCES-rm1-impulse-mc01-stu-clo.wav`
#include <torch/script.h>
int main(int argc, char* argv[]) {
if (argc !=4) {
std::cerr << "Usage: " << argv[0] << " <JIT_OBJECT> <INPUT_FILE> <OUTPUT_FILE>" << std::endl;
return -1;
}
torch::jit::script::Module module;
std::cout << "Loading module from: " << argv[0] << std::endl;
try {
module = torch::jit::load(argv[1]);
} catch (const c10::Error &error) {
std::cerr << "Failed to load the module:" << error.what() << std::endl;
return -1;
}
std::cout << "Performing the process ..." << std::endl;
module.forward({c10::IValue(argv[2]), c10::IValue(argv[3])});
std::cout << "Done." << std::endl;
}
#!/usr/bin/env bash
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}"
...@@ -49,6 +49,7 @@ if(BUILD_LIBTORCHAUDIO) ...@@ -49,6 +49,7 @@ if(BUILD_LIBTORCHAUDIO)
target_link_libraries( target_link_libraries(
libtorchaudio libtorchaudio
${TORCH_LIBRARIES}
${TORCHAUDIO_THIRD_PARTIES} ${TORCHAUDIO_THIRD_PARTIES}
) )
......
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