前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >在腾讯云云服务器CVM上玩转rnnoise

在腾讯云云服务器CVM上玩转rnnoise

原创
作者头像
buzzfrog
修改于 2025-04-26 15:46:46
修改于 2025-04-26 15:46:46
18600
代码可运行
举报
文章被收录于专栏:云上修行云上修行
运行总次数:0
代码可运行

rnnoise介绍

RNNoise是一种用于语音信号降噪的开源库,它使用递归神经网络(RNN)来实现噪声抑制。由Jean-Marc Valin开发,RNNoise结合了传统数字信号处理(DSP)和深度学习技术,旨在实时去除语音通信中的背景噪声。

为什么推荐rnnoise

  1. 专业优化:
  2. 专为语音设计的RNN架构
  3. 包含预训练好的噪声模型
  4. 实时处理延迟仅5ms
  5. 性能优势:
  6. 计算量比自行实现低10倍以上
  7. 已针对CPU指令集优化(SSE/AVX)
  8. 内存占用小于2MB
  9. 实用特性:
  10. 自动处理采样率转换
  11. 支持帧处理模式(适合实时流)
  12. 内置语音活动检测(VAD)

购买腾讯云云服务器

依赖安装

通过本地ssh ubuntu@服务器IP地址 ,远程登录到腾讯云云服务器上。在服务器中,执行如下指令:

代码语言:bash
AI代码解释
复制
sudo apt update
sudo apt-get update
sudo apt-get install git
sudo apt-get install autoconf
sudo apt-get install libtool

安装rnnoise

代码语言:bash
AI代码解释
复制
git clone https://github.com/xiph/rnnoise
cd rnnoise
./autogen.sh
./configure
make
sudo make install
代码语言:txt
AI代码解释
复制
configure:
------------------------------------------------------------------------
  rnnoise 0.2-22-g70f1d25: Automatic configuration OK.

    Assertions ................... no

    Hidden visibility ............ yes

    API code examples ............ yes
    API documentation ............ yes
------------------------------------------------------------------------

make会有很多warning,这里仅演示流程,可以忽略。如果需要提升性能,可以使用:

代码语言:bash
AI代码解释
复制
make CFLAGS="-march=native"

python3 wrapper程序

由于rnnoise编译出来是.so库,这里给一个python3的wrapper程序供python工程师使用。

首先需要安装依赖库

代码语言:bash
AI代码解释
复制
pip3 install numpy
pip3 install scipy

下面是pydenoise.py的源代码。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
import numpy as np
import ctypes
from scipy.signal import resample


class RNNoiseWrapper:
    def __init__(self, lib_path):
        self.rnnoise_lib = ctypes.CDLL(lib_path)
        # RNNOISE_EXPORT DenoiseState *rnnoise_create(RNNModel *model);
        self.rnnoise_lib.rnnoise_create.argtypes = [ctypes.c_void_p]
        self.rnnoise_lib.rnnoise_create.restype = ctypes.c_void_p

        # RNNOISE_EXPORT float rnnoise_process_frame(DenoiseState *st, float *out, const float *in);
        self.rnnoise_lib.rnnoise_process_frame.argtypes = [
            ctypes.c_void_p,
            ctypes.POINTER(ctypes.c_float), 
            ctypes.POINTER(ctypes.c_float)
        ]
        self.rnnoise_lib.rnnoise_process_frame.restype = ctypes.c_float

        # RNNOISE_EXPORT void rnnoise_destroy(DenoiseState *st);
        self.rnnoise_lib.rnnoise_destroy.argtypes = [ctypes.c_void_p]

        self.state = self.rnnoise_lib.rnnoise_create(None)
    
    def detect_sample_rate_from_frame(self, frame):
        """Detect the sample rate based on the length of the frame."""
        frame_length = len(frame)
        if frame_length == 160:
            return 16000
        elif frame_length == 240:
            return 24000
        elif frame_length == 480:
            return 48000
        else:
            raise ValueError("Unsupported frame length. Expected 160, 240, or 480 for 10ms at 16000Hz, 24000Hz or 48000Hz.")

    def process_frame(self, input_frame):
        """ Process a frame of audio data with RNNoise, supporting multiple sample rates. """
        input_frame = np.asarray(input_frame, dtype=np.float32)
        
        # Detect the sample rate of the input frame
        input_sample_rate = self.detect_sample_rate_from_frame(input_frame)

        # Resample the input frame to 48000Hz if necessary
        original_length = len(input_frame)
        if input_sample_rate != 48000:
            input_frame = resample(input_frame, 480)
        
        # Allocate output buffer
        output_frame = np.zeros(480, dtype=np.float32)
        
        # Convert numpy array to ctypes pointers
        input_ptr = input_frame.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
        output_ptr = output_frame.ctypes.data_as(ctypes.POINTER(ctypes.c_float))

        # Process the frame
        self.rnnoise_lib.rnnoise_process_frame(self.state, output_ptr, input_ptr)

        if input_sample_rate != 48000:
            output_frame = resample(output_frame, original_length)
        return output_frame

    def __del__(self):
        if self.state:
            self.rnnoise_lib.rnnoise_destroy(self.state)

# Usage Example
if __name__ == "__main__":
    lib_path = "/usr/local/lib/librnnoise.so"

    # Create RNNoise wrapper instance
    rnnoise_wrapper = RNNoiseWrapper(lib_path)

    # Create example input frames for different sample rates
    frame_16000Hz = np.random.randn(160).astype(np.float32)
    frame_24000Hz = np.random.randn(240).astype(np.float32)
    frame_48000Hz = np.random.randn(480).astype(np.float32)

    # Process frames
    processed_frame_16000 = rnnoise_wrapper.process_frame(frame_16000Hz)
    processed_frame_24000 = rnnoise_wrapper.process_frame(frame_24000Hz)
    processed_frame_48000 = rnnoise_wrapper.process_frame(frame_48000Hz)

    # Output the processed frames size
    print(f"Processed frame (16000Hz frame) length: {len(processed_frame_16000)}")
    print(f"Processed frame (24000Hz frame) length: {len(processed_frame_24000)}")
    print(f"Processed frame (48000Hz frame) length: {len(processed_frame_48000)}")

运行上述代码,结果见下图。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验