videosdk-plugins-rnnoise 0.0.47__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ myenv/
2
+ venv/
3
+ env/
4
+ __pycache__/
5
+ .venv/
6
+ .env
7
+ .env.local
8
+ test_env/
9
+ dist/
10
+ .DS_Store
11
+ node_modules/
12
+ credentials.json
13
+ .Python
14
+ build/
15
+ eggs/
16
+ sdist/
17
+ wheels/
18
+ docs/
19
+ agent-sdk-reference/
@@ -0,0 +1,35 @@
1
+ Metadata-Version: 2.4
2
+ Name: videosdk-plugins-rnnoise
3
+ Version: 0.0.47
4
+ Summary: VideoSDK Agent Framework plugin for RNNoise.
5
+ Author: videosdk
6
+ License-Expression: Apache-2.0
7
+ Keywords: ai,audio,lmnt,rime,tts,video,videosdk
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Topic :: Communications :: Conferencing
11
+ Classifier: Topic :: Multimedia :: Sound/Audio
12
+ Classifier: Topic :: Multimedia :: Video
13
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
14
+ Requires-Python: >=3.11
15
+ Requires-Dist: numpy>=1.27
16
+ Requires-Dist: resampy
17
+ Requires-Dist: videosdk-agents>=0.0.47
18
+ Description-Content-Type: text/markdown
19
+
20
+ # VideoSDK RNNoise Plugin
21
+
22
+ Agent Framework plugin for de-noising with RNNoise.
23
+
24
+ ## Installation
25
+
26
+ ```bash
27
+ pip install videosdk-plugins-rnnoise
28
+ ```
29
+
30
+ ## Building RNNoise for your OS
31
+
32
+ To avoid OS security issues with prebuilt libraries, build RNNoise locally:
33
+ 1. Ensure you have git and build tools (autoconf/make on Mac/Linux, Visual Studio with nmake on Windows).
34
+ 2. Run `python build_rnnoise.py` in the project root.
35
+ 3. This clones RNNoise, builds the library for your OS, and places it in videosdk/plugins/rnnoise/files/.
@@ -0,0 +1,16 @@
1
+ # VideoSDK RNNoise Plugin
2
+
3
+ Agent Framework plugin for de-noising with RNNoise.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install videosdk-plugins-rnnoise
9
+ ```
10
+
11
+ ## Building RNNoise for your OS
12
+
13
+ To avoid OS security issues with prebuilt libraries, build RNNoise locally:
14
+ 1. Ensure you have git and build tools (autoconf/make on Mac/Linux, Visual Studio with nmake on Windows).
15
+ 2. Run `python build_rnnoise.py` in the project root.
16
+ 3. This clones RNNoise, builds the library for your OS, and places it in videosdk/plugins/rnnoise/files/.
@@ -0,0 +1,32 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "videosdk-plugins-rnnoise"
7
+ dynamic = ["version"]
8
+ description = "VideoSDK Agent Framework plugin for RNNoise."
9
+ readme = "README.md"
10
+ license = "Apache-2.0"
11
+ requires-python = ">=3.11"
12
+ authors = [{ name = "videosdk" }]
13
+ keywords = ["video", "audio", "ai", "lmnt", "tts", "videosdk", "rime"]
14
+ classifiers = [
15
+ "Intended Audience :: Developers",
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Topic :: Communications :: Conferencing",
19
+ "Topic :: Multimedia :: Sound/Audio",
20
+ "Topic :: Multimedia :: Video",
21
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
22
+ ]
23
+ dependencies = ["videosdk-agents>=0.0.47", "resampy", "numpy>=1.27"]
24
+
25
+ [tool.hatch.version]
26
+ path = "videosdk/plugins/rnnoise/version.py"
27
+
28
+ [tool.hatch.build.targets.wheel]
29
+ packages = ["videosdk"]
30
+
31
+ [tool.hatch.build.targets.sdist]
32
+ include = ["/videosdk"]
@@ -0,0 +1,3 @@
1
+ from .denoise import RNNoise
2
+
3
+ __all__ = ["RNNoise"]
@@ -0,0 +1,76 @@
1
+ import os
2
+ import platform
3
+ import subprocess
4
+ import shutil
5
+ import tempfile
6
+
7
+ import sys
8
+ from shutil import which
9
+
10
+ def check_command(cmd, install_tip):
11
+ if not which(cmd):
12
+ raise EnvironmentError(f"{cmd} not found. Install it: {install_tip}")
13
+
14
+ def run_subprocess(cmd, cwd=None):
15
+ print(f"Running: {' '.join(cmd)}")
16
+ try:
17
+ result = subprocess.run(cmd, cwd=cwd, check=True, capture_output=True, text=True)
18
+ print(result.stdout)
19
+ if result.stderr:
20
+ print(f"Warnings/Errors: {result.stderr}")
21
+ return result
22
+ except subprocess.CalledProcessError as e:
23
+ print(f"Command failed with code {e.returncode}: {e.stderr}")
24
+ raise
25
+
26
+ def build_rnnoise():
27
+ os_sys = platform.system()
28
+ repo_url = "https://github.com/xiph/rnnoise.git"
29
+
30
+ git_tip = "Install git (e.g., apt install git on Debian/Ubuntu, brew install git on macOS, or Chocolatey on Windows)."
31
+ check_command("git", git_tip)
32
+
33
+ with tempfile.TemporaryDirectory() as tmpdir:
34
+ run_subprocess(["git", "clone", repo_url, tmpdir])
35
+ os.chdir(tmpdir)
36
+ if os_sys == "Darwin" or os_sys == "Linux":
37
+ # Check required Unix build tools
38
+ unix_tip = "Install build tools (e.g., apt install build-essential autoconf automake libtool on Debian/Ubuntu; brew install autoconf automake libtool on macOS)."
39
+ for tool in ["autoconf", "automake", "libtool", "make"]:
40
+ check_command(tool, unix_tip)
41
+
42
+ # Generate build files and compile
43
+ run_subprocess(["./autogen.sh"])
44
+ run_subprocess(["./configure"])
45
+ run_subprocess(["make"])
46
+ lib_dir = ".libs"
47
+ lib_file = "librnnoise.dylib" if os_sys == "Darwin" else "librnnoise.so"
48
+ built_lib = os.path.join(lib_dir, lib_file)
49
+ elif os_sys == "Windows":
50
+ # Check nmake for Visual Studio-based build
51
+ nmake_tip = "Install Visual Studio (community edition) and run this script from Developer Command Prompt. Alternatively, use MSYS2 (install via https://www.msys2.org/) and run make in the repo."
52
+ check_command("nmake", nmake_tip)
53
+
54
+ os.chdir("msvc")
55
+ # Assumes Visual Studio is installed; run from Developer Command Prompt if needed
56
+ run_subprocess(["nmake", "/f", "Makefile.ms"])
57
+ built_lib = "rnnoise.dll" # Adjust if name differs after build
58
+ else:
59
+ raise ValueError(f"Unsupported OS: {os_sys}. Manual build required (clone repo and follow README).")
60
+
61
+ if not os.path.exists(built_lib):
62
+ raise FileNotFoundError(f"Build failed: {built_lib} not found. Ensure build tools are installed and environment is set up (e.g., in containers, add tools via Dockerfile/package manager).")
63
+
64
+ script_dir = os.path.dirname(os.path.abspath(__file__))
65
+ target_dir = os.path.join(script_dir, "files")
66
+ os.makedirs(target_dir, exist_ok=True)
67
+ shutil.copy(built_lib, os.path.join(target_dir, os.path.basename(built_lib)))
68
+
69
+ if __name__ == "__main__":
70
+ try:
71
+ build_rnnoise()
72
+ print("RNNoise library built successfully for your OS.")
73
+ except Exception as e:
74
+ print(f"Build failed: {e}")
75
+ print("If in a container/cloud/terminal, ensure tools are installed (e.g., via apt/brew/Chocolatey) or build manually per RNNoise README: https://github.com/xiph/rnnoise")
76
+ sys.exit(1)
@@ -0,0 +1,72 @@
1
+ from typing import Any
2
+ from videosdk.agents.denoise import Denoise
3
+ from .rnnoise import RNN
4
+ import numpy as np
5
+ import resampy
6
+
7
+
8
+ class RNNoise(Denoise):
9
+ def __init__(self):
10
+ """Initialize the RNNoise denoise plugin.
11
+ """
12
+ super().__init__()
13
+ self.rnnoise = RNN()
14
+ self._target_sample_rate = 48000
15
+ self._frame_duration_ms = 20
16
+ self._rnnoise_frame_size = 480
17
+
18
+ async def denoise(self, audio_frames: bytes, **kwargs: Any) -> bytes:
19
+ if not audio_frames:
20
+ return b""
21
+
22
+ audio_np = np.frombuffer(audio_frames, dtype=np.int16)
23
+ num_samples = len(audio_np)
24
+ original_sample_rate = int(
25
+ num_samples * 1000 / self._frame_duration_ms)
26
+
27
+ if original_sample_rate != self._target_sample_rate:
28
+ audio_float = audio_np.astype(np.float32) / 32767.0
29
+ resampled_audio_float = resampy.resample(
30
+ audio_float, sr_orig=original_sample_rate, sr_new=self._target_sample_rate)
31
+ resampled_audio_np = (resampled_audio_float *
32
+ 32767.0).astype(np.int16)
33
+ else:
34
+ resampled_audio_np = audio_np
35
+
36
+ num_rnnoise_frames = len(
37
+ resampled_audio_np) // self._rnnoise_frame_size
38
+ denoised_chunks = []
39
+
40
+ for i in range(num_rnnoise_frames):
41
+ start = i * self._rnnoise_frame_size
42
+ end = start + self._rnnoise_frame_size
43
+ chunk = resampled_audio_np[start:end]
44
+
45
+ if len(chunk) != self._rnnoise_frame_size:
46
+ continue
47
+
48
+ chunk_bytes = chunk.tobytes()
49
+ _vod_prob, denoised_chunk_bytes = self.rnnoise.process_frame(
50
+ chunk_bytes)
51
+ denoised_chunk_np = np.frombuffer(
52
+ denoised_chunk_bytes, dtype=np.int16)
53
+ denoised_chunks.append(denoised_chunk_np)
54
+
55
+ if not denoised_chunks:
56
+ return b""
57
+
58
+ denoised_audio_np = np.concatenate(denoised_chunks)
59
+
60
+ if original_sample_rate != self._target_sample_rate:
61
+ denoised_float = denoised_audio_np.astype(np.float32) / 32767.0
62
+ original_format_float = resampy.resample(
63
+ denoised_float, sr_orig=self._target_sample_rate, sr_new=original_sample_rate)
64
+ final_audio_np = (original_format_float * 32767.0).astype(np.int16)
65
+ else:
66
+ final_audio_np = denoised_audio_np
67
+
68
+ return final_audio_np.tobytes()
69
+
70
+ async def aclose(self) -> None:
71
+ self.rnnoise.destroy()
72
+ await super().aclose()
@@ -0,0 +1,43 @@
1
+ import ctypes,numpy,os
2
+ import platform
3
+
4
+ script_dir = os.path.dirname(os.path.abspath(__file__))
5
+
6
+
7
+ sys_name = platform.system()
8
+ if sys_name == "Darwin":
9
+ lib_name = "librnnoise.dylib"
10
+ elif sys_name == "Linux":
11
+ lib_name = "librnnoise.so"
12
+ elif sys_name == "Windows":
13
+ lib_name = "rnnoise.dll"
14
+ else:
15
+ raise OSError(f"Unsupported OS: {sys_name}")
16
+
17
+ lib_path = os.path.join(script_dir, "files", lib_name)
18
+
19
+ try:
20
+ lib = ctypes.cdll.LoadLibrary(lib_path)
21
+ except OSError as e:
22
+ raise OSError(
23
+ f"Error loading rnnoise library at {lib_path}. "
24
+ f"It may be corrupted or incompatible with your platform. "
25
+ f"Original error: {e}"
26
+ ) from e
27
+
28
+ lib.rnnoise_process_frame.argtypes = [ctypes.c_void_p,ctypes.POINTER(ctypes.c_float),ctypes.POINTER(ctypes.c_float)]
29
+ lib.rnnoise_process_frame.restype = ctypes.c_float
30
+ lib.rnnoise_create.restype = ctypes.c_void_p
31
+ lib.rnnoise_destroy.argtypes = [ctypes.c_void_p]
32
+
33
+ class RNN(object):
34
+ def __init__(self):
35
+ self.obj = lib.rnnoise_create()
36
+ def process_frame(self,inbuf):
37
+ outbuf = numpy.ndarray((480,), 'h', inbuf).astype(ctypes.c_float)
38
+ outbuf_ptr = outbuf.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
39
+ VodProb = lib.rnnoise_process_frame(self.obj,outbuf_ptr,outbuf_ptr)
40
+ return (VodProb,outbuf.astype(ctypes.c_short).tobytes())
41
+
42
+ def destroy(self):
43
+ lib.rnnoise_destroy(self.obj)
@@ -0,0 +1 @@
1
+ __version__ = "0.0.47"