From f1c3dc7979ef369e22bd6d36a90dd0a73988c480 Mon Sep 17 00:00:00 2001 From: moto <855818+mthrok@users.noreply.github.com> Date: Wed, 24 Jun 2020 20:50:24 +0000 Subject: [PATCH] Replace sox_effects init/list/shutdown with TS binding --- torchaudio/csrc/register.cpp | 12 ++++++ torchaudio/csrc/sox.cpp | 33 ---------------- torchaudio/csrc/sox.h | 7 ---- torchaudio/csrc/sox_effects.cpp | 54 +++++++++++++++++++++++++++ torchaudio/csrc/sox_effects.h | 19 ++++++++++ torchaudio/sox_effects/__init__.py | 2 + torchaudio/sox_effects/sox_effects.py | 54 +++++---------------------- 7 files changed, 96 insertions(+), 85 deletions(-) create mode 100644 torchaudio/csrc/sox_effects.cpp create mode 100644 torchaudio/csrc/sox_effects.h diff --git a/torchaudio/csrc/register.cpp b/torchaudio/csrc/register.cpp index 4ab3fde639..baa13c031f 100644 --- a/torchaudio/csrc/register.cpp +++ b/torchaudio/csrc/register.cpp @@ -1,6 +1,7 @@ #ifndef TORCHAUDIO_REGISTER_H #define TORCHAUDIO_REGISTER_H +#include #include #include @@ -20,6 +21,17 @@ static auto registerGetInfo = torch::RegisterOperators().op( "torchaudio::sox_io_get_info(str path) -> __torch__.torch.classes.torchaudio.SignalInfo info") .catchAllKernel()); +//////////////////////////////////////////////////////////////////////////////// +// 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 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..6e4a26628f --- /dev/null +++ b/torchaudio/csrc/sox_effects.h @@ -0,0 +1,19 @@ +#ifndef TORCHAUDIO_SOX_EFFECTS_H +#define TORCHAUDIO_SOX_EFFECTS_H + +#include +#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/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')