From cc277d091e27fc8676f8e6c3dc22a198a4f659c8 Mon Sep 17 00:00:00 2001 From: Hui Zhang Date: Fri, 1 Jul 2022 11:00:51 +0000 Subject: [PATCH] add backends --- paddlespeech/audio/backends/no_backend.py | 27 ++++++ paddlespeech/audio/backends/sox_io_backend.py | 28 ++++++ paddlespeech/audio/backends/utils.py | 89 +++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 paddlespeech/audio/backends/no_backend.py create mode 100644 paddlespeech/audio/backends/sox_io_backend.py create mode 100644 paddlespeech/audio/backends/utils.py diff --git a/paddlespeech/audio/backends/no_backend.py b/paddlespeech/audio/backends/no_backend.py new file mode 100644 index 000000000..78094b157 --- /dev/null +++ b/paddlespeech/audio/backends/no_backend.py @@ -0,0 +1,27 @@ +from pathlib import Path +from typing import Callable +from typing import Optional +from typing import Tuple +from typing import Union + +from paddle import Tensor + + +def load( + filepath: Union[str, Path], + out: Optional[Tensor] = None, + normalization: Union[bool, float, Callable] = True, + channels_first: bool = True, + num_frames: int = 0, + offset: int = 0, + filetype: Optional[str] = None, +) -> Tuple[Tensor, int]: + raise RuntimeError("No audio I/O backend is available.") + + +def save(filepath: str, src: Tensor, sample_rate: int, precision: int = 16, channels_first: bool = True) -> None: + raise RuntimeError("No audio I/O backend is available.") + + +def info(filepath: str) -> None: + raise RuntimeError("No audio I/O backend is available.") \ No newline at end of file diff --git a/paddlespeech/audio/backends/sox_io_backend.py b/paddlespeech/audio/backends/sox_io_backend.py new file mode 100644 index 000000000..5a2595b3b --- /dev/null +++ b/paddlespeech/audio/backends/sox_io_backend.py @@ -0,0 +1,28 @@ + +from pathlib import Path +from typing import Callable +from typing import Optional +from typing import Tuple +from typing import Union + +from paddle import Tensor + + +def load( + filepath: Union[str, Path], + out: Optional[Tensor] = None, + normalization: Union[bool, float, Callable] = True, + channels_first: bool = True, + num_frames: int = 0, + offset: int = 0, + filetype: Optional[str] = None, +) -> Tuple[Tensor, int]: + raise RuntimeError("No audio I/O backend is available.") + + +def save(filepath: str, src: Tensor, sample_rate: int, precision: int = 16, channels_first: bool = True) -> None: + raise RuntimeError("No audio I/O backend is available.") + + +def info(filepath: str) -> None: + raise RuntimeError("No audio I/O backend is available.") \ No newline at end of file diff --git a/paddlespeech/audio/backends/utils.py b/paddlespeech/audio/backends/utils.py new file mode 100644 index 000000000..ce21e0203 --- /dev/null +++ b/paddlespeech/audio/backends/utils.py @@ -0,0 +1,89 @@ +"""Defines utilities for switching audio backends""" +import warnings +from typing import List +from typing import Optional + +import paddlespeech.audio +from paddlespeech.audio._internal import module_utils as _mod_utils + +from . import no_backend, soundfile_backend, sox_io_backend + +__all__ = [ + "list_audio_backends", + "get_audio_backend", + "set_audio_backend", +] + + +def list_audio_backends() -> List[str]: + """List available backends + + Returns: + List[str]: The list of available backends. + """ + backends = [] + if _mod_utils.is_module_available("soundfile"): + backends.append("soundfile") + if _mod_utils.is_sox_available(): + backends.append("sox_io") + return backends + + +def set_audio_backend(backend: Optional[str]): + """Set the backend for I/O operation + + Args: + backend (str or None): Name of the backend. + One of ``"sox_io"`` or ``"soundfile"`` based on availability + of the system. If ``None`` is provided the current backend is unassigned. + """ + if backend is not None and backend not in list_audio_backends(): + raise RuntimeError(f'Backend "{backend}" is not one of ' f"available backends: {list_audio_backends()}.") + + if backend is None: + module = no_backend + elif backend == "sox_io": + module = sox_io_backend + elif backend == "soundfile": + module = soundfile_backend + else: + raise NotImplementedError(f'Unexpected backend "{backend}"') + + for func in ["save", "load", "info"]: + setattr(paddlespeech.audio, func, getattr(module, func)) + + +# def _init_audio_backend(): +# backends = list_audio_backends() +# if "sox_io" in backends: +# set_audio_backend("sox_io") +# elif "soundfile" in backends: +# set_audio_backend("soundfile") +# else: +# warnings.warn("No audio backend is available.") +# set_audio_backend(None) + + +def _init_audio_backend(): + backends = list_audio_backends() + if "soundfile" in backends: + set_audio_backend("soundfile") + elif "sox_io" in backends: + set_audio_backend("sox_io") + else: + warnings.warn("No audio backend is available.") + set_audio_backend(None) + +def get_audio_backend() -> Optional[str]: + """Get the name of the current backend + + Returns: + Optional[str]: The name of the current backend or ``None`` if no backend is assigned. + """ + if paddlespeech.audio.load == no_backend.load: + return None + if paddlespeech.audio.load == sox_io_backend.load: + return "sox_io" + if paddlespeech.audio.load == soundfile_backend.load: + return "soundfile" + raise ValueError("Unknown backend.") \ No newline at end of file