RNNoise 是一个基于循环神经网络的噪声抑制库。 该算法的描述可参见以下论文:
J.-M. Valin,《一种实时全频带语音增强的混合DSP/深度学习方法》,IEEE多媒体信号处理研讨会(MMSP)论文集,arXiv:1709.08243,2018年。 https://arxiv.org/pdf/1709.08243.pdf
交互式演示可在以下网址获得:https://jmvalin.ca/demo/rnnoise/
编译只需输入: % ./autogen.sh % ./configure % make
可选: % make install
建议在 CFLAGS 中设置 -march= 为支持 AVX2 的架构,或在配置脚本中添加 --enable-x86-rtcd,以便至少可以将 AVX2(或 SSE4.1)作为一个选项使用。 请注意,autogen.sh 脚本会自动从 Xiph.Org 服务器下载模型文件,因为这些文件太大,无法放入 Git 中。
虽然它主要用作库,但也提供了一个简单的命令行工具作为示例。它处理采样率为 48 kHz 的 RAW 16 位(机器字节序)单声道 PCM 文件。使用方法如下:
% ./examples/rnnoise_demo <带噪语音> <输出去噪后>
输出也是 16 位原始 PCM 文件。 再次注意,输入和输出都是原始格式,而非 WAV 格式。
最新版本的源代码可从 https://gitlab.xiph.org/xiph/rnnoise 获取。GitHub 仓库是一个便利副本。
== 训练 ==
RNNoise 随附的模型现在仅使用下面列出的公开可用数据集进行训练,并采用此处描述的训练程序。确切结果仍将取决于所使用的数据精确混合、训练持续时间以及涉及的各种随机种子。
要训练 RNNoise 模型,你需要清晰的语音数据和噪声数据。两者都需要以 48 kHz 采样率、16 位 PCM 格式(机器字节序)。清晰的语音数据可以从 datasets.txt 文件中列出的数据集获得,或通过下载这些文件的已连接版本: https://media.xiph.org/rnnoise/data/tts_speech_48k.sw 对于噪声数据,我们建议将 DEMAND 中的 48 kHz 噪声数据(https://zenodo.org/records/1227121)与以下网址中的 contrib_noise.sw 和 synthetic_noise.sw 噪声文件连接起来: https://media.xiph.org/rnnoise/data/ 为了平衡数据,我们建议使用 contrib_noise.sw 和 synthetic_noise.sw 噪声文件的多个副本(例如 5 个)。
第一步是将语音和噪声以各种方式混合,以模拟真实生活条件(包括暂停、过滤等)。假设文件名为 speech.pcm 和 noise.pcm,首先通过以下命令生成训练特征数据:
% ./dump_features speech.pcm noise.pcm features.f32 <数量> 其中 <数量> 是要处理的序列数。序列数应至少为 10000,但越多越好(建议 200000 或更多)。
可选地,训练也可以模拟混响,这种情况下还需要房间冲激响应(RIR)。有限的 RIR 数据可在以下网址获取: https://media.xiph.org/rnnoise/data/measured_rirs-v2.tar.gz 这些文件的格式为原始 32 位浮点数(文件为小端字节序)。假设所有 RIR 文件的列表包含在 rir_list.txt 文件中,可以使用以下命令生成训练特征数据:
% ./dump_features -rir_list rir_list.txt speech.pcm noise.pcm features.f32 <数量>
要加快特征生成速度,可以使用 script/dump_features_parallel.sh 中提供的脚本(如果要添加 RIR 增强,需要修改脚本)。
使用方法: % script/dump_features_parallel.sh ./dump_features speech.pcm noise.pcm features.f32 <数量> <进程数> 这将运行 <进程数> 个进程,每个进程处理 <数量> 个序列,并将输出连接到单个文件中。
计算特征文件后,可以使用以下命令开始训练: % python3 train_rnnoise.py features.f32 输出目录
选择一个导致约 75000 次权重更新的 epoch 数(使用 --epochs)。训练将生成 .pth 文件,例如 rnnoise_50.pth。 下一步是使用以下命令将模型转换为 C 文件:
% python3 dump_rnnoise_weights.py --quantize rnnoise_50.pth rnnoise_c
这将在 rnnoise_c 目录中生成 rnnoise_data.c 和 rnnoise_data.h 文件。
将这些文件复制到 src/ 目录,然后按照上述说明构建 RNNoise。
为获得稍好的结果,可以使用训练好的模型去除"清晰"训练语音中的任何噪声,然后再次重新开始去噪过程(无需多次进行)。
== 可加载模型 ==
自 v0.1.1 以来,模型格式已更改。现在模型使用二进制"机器字节序"格式。要输出该格式的模型,请使用该模型构建 RNNoise,并使用 dump_weights_blob 可执行文件输出 weights_blob.bin 二进制文件。然后可以使用 rnnoise_model_from_file() API 调用该文件。请注意,当 RNNoise 状态处于活动状态时,不得删除模型对象,且不得关闭文件。
要避免在构建中包含默认模型(例如,减少下载大小)并仅依赖模型加载,请将 -DUSE_WEIGHTS_FILE 添加到 CFLAGS 中。 为了能够加载不同的模型,模型大小(和头文件)需要与构建时使用的大小匹配。否则,模型将无法加载。 我们提供了一个"小型"模型作为替代方案,其大小为原来的一半。要使用较小的模型,请将 rnnoise_data_little.c 重命名为 rnnoise_data.c。可以同时构建常规和小型二进制权重,并在运行时加载其中任何一个,因为小型模型的大小与常规模型相同(除了增加的稀疏性)。