videosdk-plugins-rnnoise-dev 0.0.63.dev0__tar.gz → 0.0.63.dev2__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.
- {videosdk_plugins_rnnoise_dev-0.0.63.dev0 → videosdk_plugins_rnnoise_dev-0.0.63.dev2}/PKG-INFO +3 -3
- {videosdk_plugins_rnnoise_dev-0.0.63.dev0 → videosdk_plugins_rnnoise_dev-0.0.63.dev2}/pyproject.toml +3 -10
- videosdk_plugins_rnnoise_dev-0.0.63.dev2/videosdk/plugins/rnnoise/build_rnnoise.py +71 -0
- {videosdk_plugins_rnnoise_dev-0.0.63.dev0 → videosdk_plugins_rnnoise_dev-0.0.63.dev2}/videosdk/plugins/rnnoise/denoise.py +20 -10
- videosdk_plugins_rnnoise_dev-0.0.63.dev2/videosdk/plugins/rnnoise/files/librnnoise.0.dylib +0 -0
- videosdk_plugins_rnnoise_dev-0.0.63.dev2/videosdk/plugins/rnnoise/files/librnnoise.dylib +1 -0
- videosdk_plugins_rnnoise_dev-0.0.63.dev2/videosdk/plugins/rnnoise/rnnoise.py +43 -0
- videosdk_plugins_rnnoise_dev-0.0.63.dev2/videosdk/plugins/rnnoise/version.py +1 -0
- videosdk_plugins_rnnoise_dev-0.0.63.dev0/videosdk/plugins/rnnoise/build_rnnoise.py +0 -126
- videosdk_plugins_rnnoise_dev-0.0.63.dev0/videosdk/plugins/rnnoise/files/librnnoise.0.dylib +0 -0
- videosdk_plugins_rnnoise_dev-0.0.63.dev0/videosdk/plugins/rnnoise/files/librnnoise.dylib +0 -0
- videosdk_plugins_rnnoise_dev-0.0.63.dev0/videosdk/plugins/rnnoise/rnnoise.py +0 -77
- videosdk_plugins_rnnoise_dev-0.0.63.dev0/videosdk/plugins/rnnoise/version.py +0 -1
- {videosdk_plugins_rnnoise_dev-0.0.63.dev0 → videosdk_plugins_rnnoise_dev-0.0.63.dev2}/README.md +0 -0
- {videosdk_plugins_rnnoise_dev-0.0.63.dev0 → videosdk_plugins_rnnoise_dev-0.0.63.dev2}/videosdk/plugins/rnnoise/__init__.py +0 -0
- {videosdk_plugins_rnnoise_dev-0.0.63.dev0 → videosdk_plugins_rnnoise_dev-0.0.63.dev2}/videosdk/plugins/rnnoise/files/librnnoise.so +0 -0
{videosdk_plugins_rnnoise_dev-0.0.63.dev0 → videosdk_plugins_rnnoise_dev-0.0.63.dev2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: videosdk-plugins-rnnoise-dev
|
|
3
|
-
Version: 0.0.63.
|
|
3
|
+
Version: 0.0.63.dev2
|
|
4
4
|
Summary: VideoSDK Agent Framework plugin for RNNoise.
|
|
5
5
|
Author: videosdk
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -12,9 +12,9 @@ Classifier: Topic :: Multimedia :: Sound/Audio
|
|
|
12
12
|
Classifier: Topic :: Multimedia :: Video
|
|
13
13
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
14
|
Requires-Python: >=3.11
|
|
15
|
-
Requires-Dist: numpy>=1.
|
|
15
|
+
Requires-Dist: numpy>=1.27
|
|
16
16
|
Requires-Dist: resampy
|
|
17
|
-
Requires-Dist: videosdk-agents>=0.0.
|
|
17
|
+
Requires-Dist: videosdk-agents>=0.0.62
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
|
|
20
20
|
# VideoSDK RNNoise Plugin
|
{videosdk_plugins_rnnoise_dev-0.0.63.dev0 → videosdk_plugins_rnnoise_dev-0.0.63.dev2}/pyproject.toml
RENAMED
|
@@ -9,7 +9,7 @@ description = "VideoSDK Agent Framework plugin for RNNoise."
|
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
11
11
|
requires-python = ">=3.11"
|
|
12
|
-
authors = [{ name = "videosdk"}]
|
|
12
|
+
authors = [{ name = "videosdk" }]
|
|
13
13
|
keywords = ["video", "audio", "ai", "lmnt", "tts", "videosdk", "rime"]
|
|
14
14
|
classifiers = [
|
|
15
15
|
"Intended Audience :: Developers",
|
|
@@ -20,20 +20,13 @@ classifiers = [
|
|
|
20
20
|
"Topic :: Multimedia :: Video",
|
|
21
21
|
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
22
22
|
]
|
|
23
|
-
dependencies = [
|
|
24
|
-
"videosdk-agents>=0.0.22",
|
|
25
|
-
"resampy",
|
|
26
|
-
"numpy>=1.26"
|
|
27
|
-
]
|
|
23
|
+
dependencies = ["videosdk-agents>=0.0.62", "resampy", "numpy>=1.27"]
|
|
28
24
|
|
|
29
25
|
[tool.hatch.version]
|
|
30
26
|
path = "videosdk/plugins/rnnoise/version.py"
|
|
31
27
|
|
|
32
28
|
[tool.hatch.build.targets.wheel]
|
|
33
29
|
packages = ["videosdk"]
|
|
34
|
-
include = [
|
|
35
|
-
"videosdk/plugins/rnnoise/files/*"
|
|
36
|
-
]
|
|
37
30
|
|
|
38
31
|
[tool.hatch.build.targets.sdist]
|
|
39
|
-
include = ["/videosdk"]
|
|
32
|
+
include = ["/videosdk"]
|
|
@@ -0,0 +1,71 @@
|
|
|
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
|
+
unix_tip = "Install build tools (e.g., apt install build-essential autoconf automake libtool on Debian/Ubuntu; brew install autoconf automake libtool on macOS)."
|
|
38
|
+
for tool in ["autoconf", "automake", "libtool", "make"]:
|
|
39
|
+
check_command(tool, unix_tip)
|
|
40
|
+
|
|
41
|
+
run_subprocess(["./autogen.sh"])
|
|
42
|
+
run_subprocess(["./configure"])
|
|
43
|
+
run_subprocess(["make"])
|
|
44
|
+
lib_dir = ".libs"
|
|
45
|
+
lib_file = "librnnoise.dylib" if os_sys == "Darwin" else "librnnoise.so"
|
|
46
|
+
built_lib = os.path.join(lib_dir, lib_file)
|
|
47
|
+
elif os_sys == "Windows":
|
|
48
|
+
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."
|
|
49
|
+
check_command("nmake", nmake_tip)
|
|
50
|
+
os.chdir("msvc")
|
|
51
|
+
run_subprocess(["nmake", "/f", "Makefile.ms"])
|
|
52
|
+
built_lib = "rnnoise.dll"
|
|
53
|
+
else:
|
|
54
|
+
raise ValueError(f"Unsupported OS: {os_sys}. Manual build required (clone repo and follow README).")
|
|
55
|
+
|
|
56
|
+
if not os.path.exists(built_lib):
|
|
57
|
+
raise FileNotFoundError(f"Build failed: {built_lib} not found. Ensure build tools are installed and environment is set up.")
|
|
58
|
+
|
|
59
|
+
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
60
|
+
target_dir = os.path.join(script_dir, "files")
|
|
61
|
+
os.makedirs(target_dir, exist_ok=True)
|
|
62
|
+
shutil.copy(built_lib, os.path.join(target_dir, os.path.basename(built_lib)))
|
|
63
|
+
|
|
64
|
+
if __name__ == "__main__":
|
|
65
|
+
try:
|
|
66
|
+
build_rnnoise()
|
|
67
|
+
print("RNNoise library built successfully for your OS.")
|
|
68
|
+
except Exception as e:
|
|
69
|
+
print(f"Build failed: {e}")
|
|
70
|
+
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")
|
|
71
|
+
sys.exit(1)
|
|
@@ -4,12 +4,15 @@ from .rnnoise import RNN
|
|
|
4
4
|
import numpy as np
|
|
5
5
|
import resampy
|
|
6
6
|
|
|
7
|
+
|
|
7
8
|
class RNNoise(Denoise):
|
|
8
9
|
def __init__(self):
|
|
10
|
+
"""Initialize the RNNoise denoise plugin.
|
|
11
|
+
"""
|
|
9
12
|
super().__init__()
|
|
10
13
|
self.rnnoise = RNN()
|
|
11
14
|
self._target_sample_rate = 48000
|
|
12
|
-
self._frame_duration_ms = 20
|
|
15
|
+
self._frame_duration_ms = 20
|
|
13
16
|
self._rnnoise_frame_size = 480
|
|
14
17
|
|
|
15
18
|
async def denoise(self, audio_frames: bytes, **kwargs: Any) -> bytes:
|
|
@@ -18,29 +21,35 @@ class RNNoise(Denoise):
|
|
|
18
21
|
|
|
19
22
|
audio_np = np.frombuffer(audio_frames, dtype=np.int16)
|
|
20
23
|
num_samples = len(audio_np)
|
|
21
|
-
original_sample_rate = int(
|
|
24
|
+
original_sample_rate = int(
|
|
25
|
+
num_samples * 1000 / self._frame_duration_ms)
|
|
22
26
|
|
|
23
27
|
if original_sample_rate != self._target_sample_rate:
|
|
24
28
|
audio_float = audio_np.astype(np.float32) / 32767.0
|
|
25
|
-
resampled_audio_float = resampy.resample(
|
|
26
|
-
|
|
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)
|
|
27
33
|
else:
|
|
28
34
|
resampled_audio_np = audio_np
|
|
29
35
|
|
|
30
|
-
num_rnnoise_frames = len(
|
|
36
|
+
num_rnnoise_frames = len(
|
|
37
|
+
resampled_audio_np) // self._rnnoise_frame_size
|
|
31
38
|
denoised_chunks = []
|
|
32
39
|
|
|
33
40
|
for i in range(num_rnnoise_frames):
|
|
34
41
|
start = i * self._rnnoise_frame_size
|
|
35
42
|
end = start + self._rnnoise_frame_size
|
|
36
43
|
chunk = resampled_audio_np[start:end]
|
|
37
|
-
|
|
44
|
+
|
|
38
45
|
if len(chunk) != self._rnnoise_frame_size:
|
|
39
46
|
continue
|
|
40
47
|
|
|
41
48
|
chunk_bytes = chunk.tobytes()
|
|
42
|
-
_vod_prob, denoised_chunk_bytes = self.rnnoise.process_frame(
|
|
43
|
-
|
|
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)
|
|
44
53
|
denoised_chunks.append(denoised_chunk_np)
|
|
45
54
|
|
|
46
55
|
if not denoised_chunks:
|
|
@@ -50,7 +59,8 @@ class RNNoise(Denoise):
|
|
|
50
59
|
|
|
51
60
|
if original_sample_rate != self._target_sample_rate:
|
|
52
61
|
denoised_float = denoised_audio_np.astype(np.float32) / 32767.0
|
|
53
|
-
original_format_float = resampy.resample(
|
|
62
|
+
original_format_float = resampy.resample(
|
|
63
|
+
denoised_float, sr_orig=self._target_sample_rate, sr_new=original_sample_rate)
|
|
54
64
|
final_audio_np = (original_format_float * 32767.0).astype(np.int16)
|
|
55
65
|
else:
|
|
56
66
|
final_audio_np = denoised_audio_np
|
|
@@ -59,4 +69,4 @@ class RNNoise(Denoise):
|
|
|
59
69
|
|
|
60
70
|
async def aclose(self) -> None:
|
|
61
71
|
self.rnnoise.destroy()
|
|
62
|
-
await super().aclose()
|
|
72
|
+
await super().aclose()
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
librnnoise.0.dylib
|
|
@@ -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.63.dev2"
|
|
@@ -1,126 +0,0 @@
|
|
|
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
|
-
# Force Linux detection when running in Docker
|
|
28
|
-
if os.path.exists("/.dockerenv") or os.environ.get("DOCKER_CONTAINER"):
|
|
29
|
-
os_sys = "Linux"
|
|
30
|
-
else:
|
|
31
|
-
os_sys = platform.system()
|
|
32
|
-
repo_url = "https://github.com/xiph/rnnoise.git"
|
|
33
|
-
|
|
34
|
-
git_tip = "Install git (e.g., apt install git on Debian/Ubuntu, brew install git on macOS, or Chocolatey on Windows)."
|
|
35
|
-
check_command("git", git_tip)
|
|
36
|
-
|
|
37
|
-
with tempfile.TemporaryDirectory() as tmpdir:
|
|
38
|
-
run_subprocess(["git", "clone", repo_url, tmpdir])
|
|
39
|
-
os.chdir(tmpdir)
|
|
40
|
-
if os_sys == "Darwin" or os_sys == "Linux":
|
|
41
|
-
# Check required Unix build tools
|
|
42
|
-
unix_tip = "Install build tools (e.g., apt install build-essential autoconf automake libtool on Debian/Ubuntu; brew install autoconf automake libtool on macOS)."
|
|
43
|
-
for tool in ["autoconf", "automake", "libtool", "make"]:
|
|
44
|
-
check_command(tool, unix_tip)
|
|
45
|
-
|
|
46
|
-
# Generate build files and compile
|
|
47
|
-
run_subprocess(["./autogen.sh"])
|
|
48
|
-
run_subprocess(["./configure"])
|
|
49
|
-
run_subprocess(["make"])
|
|
50
|
-
lib_dir = ".libs"
|
|
51
|
-
|
|
52
|
-
# Force Linux .so file when running in Docker container
|
|
53
|
-
if os.path.exists("/.dockerenv") or os.environ.get("DOCKER_CONTAINER"):
|
|
54
|
-
lib_file = "librnnoise.so"
|
|
55
|
-
print(f"🔧 Docker detected, forcing .so file: {lib_file}")
|
|
56
|
-
else:
|
|
57
|
-
lib_file = "librnnoise.dylib" if os_sys == "Darwin" else "librnnoise.so"
|
|
58
|
-
print(f"🔧 Host system detected: {os_sys}, using: {lib_file}")
|
|
59
|
-
|
|
60
|
-
built_lib = os.path.join(lib_dir, lib_file)
|
|
61
|
-
elif os_sys == "Windows":
|
|
62
|
-
# Check nmake for Visual Studio-based build
|
|
63
|
-
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."
|
|
64
|
-
check_command("nmake", nmake_tip)
|
|
65
|
-
|
|
66
|
-
os.chdir("msvc")
|
|
67
|
-
# Assumes Visual Studio is installed; run from Developer Command Prompt if needed
|
|
68
|
-
run_subprocess(["nmake", "/f", "Makefile.ms"])
|
|
69
|
-
built_lib = "rnnoise.dll" # Adjust if name differs after build
|
|
70
|
-
else:
|
|
71
|
-
raise ValueError(f"Unsupported OS: {os_sys}. Manual build required (clone repo and follow README).")
|
|
72
|
-
|
|
73
|
-
if not os.path.exists(built_lib):
|
|
74
|
-
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).")
|
|
75
|
-
|
|
76
|
-
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
77
|
-
target_dir = os.path.join(script_dir, "files")
|
|
78
|
-
os.makedirs(target_dir, exist_ok=True)
|
|
79
|
-
|
|
80
|
-
# Force .so files when running in Docker
|
|
81
|
-
if os.path.exists("/.dockerenv") or os.environ.get("DOCKER_CONTAINER"):
|
|
82
|
-
# Look for shared library specifically
|
|
83
|
-
shared_lib = os.path.join(lib_dir, "librnnoise.so")
|
|
84
|
-
static_lib = os.path.join(lib_dir, "librnnoise.a")
|
|
85
|
-
|
|
86
|
-
if os.path.exists(shared_lib):
|
|
87
|
-
source_lib = shared_lib
|
|
88
|
-
print(f"🔧 Found shared library: {source_lib}")
|
|
89
|
-
elif os.path.exists(static_lib):
|
|
90
|
-
# If no shared library, create one from static library
|
|
91
|
-
print(f"🔧 Creating shared library from static library")
|
|
92
|
-
# Extract object files from static library
|
|
93
|
-
run_subprocess(["ar", "-x", static_lib])
|
|
94
|
-
# Create shared library from object files
|
|
95
|
-
obj_files = [f for f in os.listdir(".") if f.endswith(".o")]
|
|
96
|
-
run_subprocess(["gcc", "-shared", "-o", shared_lib] + obj_files + ["-lm"])
|
|
97
|
-
source_lib = shared_lib
|
|
98
|
-
else:
|
|
99
|
-
raise FileNotFoundError(f"No librnnoise library found in {lib_dir}")
|
|
100
|
-
|
|
101
|
-
target_lib = os.path.join(target_dir, "librnnoise.so")
|
|
102
|
-
shutil.copy(source_lib, target_lib)
|
|
103
|
-
print(f"🔧 Copied {source_lib} to {target_lib}")
|
|
104
|
-
|
|
105
|
-
# Also create a symlink for compatibility
|
|
106
|
-
symlink_path = os.path.join(target_dir, "librnnoise.dylib")
|
|
107
|
-
if os.path.exists(symlink_path):
|
|
108
|
-
os.remove(symlink_path)
|
|
109
|
-
os.symlink("librnnoise.so", symlink_path)
|
|
110
|
-
print(f"🔧 Created symlink: librnnoise.dylib -> librnnoise.so")
|
|
111
|
-
|
|
112
|
-
# Copy to the mounted volume location
|
|
113
|
-
mounted_target = "/output/librnnoise.so"
|
|
114
|
-
shutil.copy(source_lib, mounted_target)
|
|
115
|
-
print(f"🔧 Copied to mounted volume: {mounted_target}")
|
|
116
|
-
else:
|
|
117
|
-
shutil.copy(built_lib, os.path.join(target_dir, os.path.basename(built_lib)))
|
|
118
|
-
|
|
119
|
-
if __name__ == "__main__":
|
|
120
|
-
try:
|
|
121
|
-
build_rnnoise()
|
|
122
|
-
print("RNNoise library built successfully for your OS.")
|
|
123
|
-
except Exception as e:
|
|
124
|
-
print(f"Build failed: {e}")
|
|
125
|
-
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")
|
|
126
|
-
sys.exit(1)
|
|
Binary file
|
|
Binary file
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import ctypes
|
|
2
|
-
import numpy as np
|
|
3
|
-
import os
|
|
4
|
-
import platform
|
|
5
|
-
|
|
6
|
-
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
sys_name = platform.system()
|
|
10
|
-
if sys_name == "Darwin":
|
|
11
|
-
lib_name = "librnnoise.dylib"
|
|
12
|
-
elif sys_name == "Linux":
|
|
13
|
-
lib_name = "librnnoise.so"
|
|
14
|
-
elif sys_name == "Windows":
|
|
15
|
-
lib_name = "rnnoise.dll"
|
|
16
|
-
else:
|
|
17
|
-
raise OSError(f"Unsupported OS: {sys_name}")
|
|
18
|
-
|
|
19
|
-
lib_path = os.path.join(script_dir, "files", lib_name)
|
|
20
|
-
|
|
21
|
-
try:
|
|
22
|
-
lib = ctypes.cdll.LoadLibrary(lib_path)
|
|
23
|
-
except OSError as e:
|
|
24
|
-
raise OSError(
|
|
25
|
-
f"Error loading rnnoise library at {lib_path}. "
|
|
26
|
-
f"It may be corrupted or incompatible with your platform. "
|
|
27
|
-
f"Original error: {e}"
|
|
28
|
-
) from e
|
|
29
|
-
|
|
30
|
-
# Define the correct function signatures
|
|
31
|
-
lib.rnnoise_create.argtypes = [ctypes.c_void_p] # RNNModel *model (can be NULL)
|
|
32
|
-
lib.rnnoise_create.restype = ctypes.c_void_p
|
|
33
|
-
lib.rnnoise_destroy.argtypes = [ctypes.c_void_p]
|
|
34
|
-
lib.rnnoise_process_frame.argtypes = [ctypes.c_void_p, ctypes.POINTER(ctypes.c_float), ctypes.POINTER(ctypes.c_float)]
|
|
35
|
-
lib.rnnoise_process_frame.restype = ctypes.c_float
|
|
36
|
-
|
|
37
|
-
class RNN(object):
|
|
38
|
-
def __init__(self):
|
|
39
|
-
# Pass NULL (None) for the model parameter to use the default model
|
|
40
|
-
self.obj = lib.rnnoise_create(None)
|
|
41
|
-
if self.obj is None:
|
|
42
|
-
raise RuntimeError("Failed to create RNNoise instance")
|
|
43
|
-
|
|
44
|
-
def process_frame(self, inbuf):
|
|
45
|
-
# Create a copy of the input buffer to avoid modifying the original
|
|
46
|
-
if isinstance(inbuf, bytes):
|
|
47
|
-
# Convert bytes to numpy array
|
|
48
|
-
audio_data = np.frombuffer(inbuf, dtype=np.int16)
|
|
49
|
-
else:
|
|
50
|
-
audio_data = np.array(inbuf, dtype=np.int16)
|
|
51
|
-
|
|
52
|
-
# Ensure we have exactly 480 samples
|
|
53
|
-
if len(audio_data) != 480:
|
|
54
|
-
raise ValueError(f"Expected 480 samples, got {len(audio_data)}")
|
|
55
|
-
|
|
56
|
-
# Convert to float32 and normalize
|
|
57
|
-
audio_float = audio_data.astype(np.float32) / 32767.0
|
|
58
|
-
|
|
59
|
-
# Create output buffer
|
|
60
|
-
outbuf = np.zeros(480, dtype=np.float32)
|
|
61
|
-
|
|
62
|
-
# Get pointers
|
|
63
|
-
in_ptr = audio_float.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
|
|
64
|
-
out_ptr = outbuf.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
|
|
65
|
-
|
|
66
|
-
# Process the frame
|
|
67
|
-
VodProb = lib.rnnoise_process_frame(self.obj, out_ptr, in_ptr)
|
|
68
|
-
|
|
69
|
-
# Convert back to int16
|
|
70
|
-
outbuf_int16 = (outbuf * 32767.0).astype(np.int16)
|
|
71
|
-
|
|
72
|
-
return (VodProb, outbuf_int16.tobytes())
|
|
73
|
-
|
|
74
|
-
def destroy(self):
|
|
75
|
-
if self.obj is not None:
|
|
76
|
-
lib.rnnoise_destroy(self.obj)
|
|
77
|
-
self.obj = None
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.63.dev0"
|
{videosdk_plugins_rnnoise_dev-0.0.63.dev0 → videosdk_plugins_rnnoise_dev-0.0.63.dev2}/README.md
RENAMED
|
File without changes
|
|
File without changes
|