Unverified Commit 0f0d0af3 authored by moto's avatar moto Committed by GitHub
Browse files

Replace sox_effects init/list/shutdown with TS binding (#748)

parent 0c847aaa
#ifndef TORCHAUDIO_REGISTER_H
#define TORCHAUDIO_REGISTER_H
#include <torchaudio/csrc/sox_effects.h>
#include <torchaudio/csrc/sox_io.h>
#include <torchaudio/csrc/typedefs.h>
......@@ -20,6 +21,17 @@ static auto registerGetInfo = torch::RegisterOperators().op(
"torchaudio::sox_io_get_info(str path) -> __torch__.torch.classes.torchaudio.SignalInfo info")
.catchAllKernel<decltype(sox_io::get_info), &sox_io::get_info>());
////////////////////////////////////////////////////////////////////////////////
// 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
#endif
......@@ -82,17 +82,6 @@ std::tuple<sox_signalinfo_t, sox_encodinginfo_t> get_info(
return std::make_tuple(fd->signal, fd->encoding);
}
std::vector<std::string> get_effect_names() {
sox_effect_fn_t const * fns = sox_get_effect_fns();
std::vector<std::string> 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");
}
......@@ -45,13 +45,6 @@ void write_audio_file(
std::tuple<sox_signalinfo_t, sox_encodinginfo_t> get_info(
const std::string& file_name);
// get names of all sox effects
std::vector<std::string> 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({""}) { }
......
#include <sox.h>
#include <torchaudio/csrc/sox_effects.h>
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<std::string> list_effects() {
std::vector<std::string> 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
#ifndef TORCHAUDIO_SOX_EFFECTS_H
#define TORCHAUDIO_SOX_EFFECTS_H
#include <torch/script.h>
#include <torchaudio/csrc/typedefs.h>
namespace torchaudio {
namespace sox_effects {
void initialize_sox_effects();
void shutdown_sox_effects();
std::vector<std::string> list_effects();
} // namespace sox_effects
} // namespace torchaudio
#endif
......@@ -9,4 +9,6 @@ from .sox_effects import (
if _mod_utils.is_module_available('torchaudio._torchaudio'):
import atexit
init_sox_effects()
atexit.register(shutdown_sox_effects)
import atexit
from typing import Any, Callable, List, Optional, Tuple, Union
import torch
......@@ -13,19 +12,8 @@ if _mod_utils.is_module_available('torchaudio._torchaudio'):
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')
......
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