RK3576 实现sox降噪和rnnoise降噪
概述
音频降噪技术的发展,经历了从对抗物理噪声到智能识别分离的演变。
模拟时代(20世纪中期)
- 杜比A型(1965年):开创性的动态降噪技术,采用“压缩-扩张”原理降低磁带本底噪声。
- 杜比B型(1968年):A型的消费简化版,让卡式磁带走入千家万户。
- dbx(1971年):更激进的压缩-扩张系统,动态范围更大。
- 后续发展:Dolby C、SR等更先进的模拟系统相继问世。
数字时代早期(1980-1990年代)
- 数字信号处理芯片的出现,让实时数字滤波和谱减法成为可能
- 算法开始从时域转向频域处理
- 自适应滤波理论成熟并应用于通信领域
数字算法普及期(1990-2010年代)
- 个人电脑性能提升,专业音频软件(如Audition、iZotope RX)普及了数字降噪工具
- 心理声学模型的应用提升了降噪音质
- 主动降噪耳机开始商业化(Bose等厂商推动)
人工智能时代(2010年代至今)
- 深度学习彻底改变了降噪方式,能够处理复杂的非平稳噪声
- 技术广泛应用于视频会议、语音助手、音乐流媒体等领域
- 研究方向从单纯降噪扩展到语音分离、人声提取等精细化任务
主要降噪方法
基于频谱的降噪 核心思路是在频域上区分噪声和信号:
- 谱减法:从音频中减去噪声频谱
- 维纳滤波:更优的统计降噪方法
- 掩蔽效应法:利用人耳特性保留音质
机器学习降噪
- 使用深度学习模型(RNN、CNN、Transformer等)从数据中学习降噪
- 能够有效处理复杂场景和非平稳噪声
- 支持端到端的波形或频谱处理
滤波降噪
- 自适应滤波:需要参考噪声信号,用于电话和主动降噪耳机
- 固定滤波:去除特定频率噪声,如50Hz工频干扰
多麦克风技术
- 通过麦克风阵列形成指向性波束
- 增强目标方向声音,抑制环境噪声
- 常见于手机、会议设备和智能音箱
传统处理方法
- 噪声门:通过阈值静音低电平信号
- 简单有效,常用于音乐制作和直播场景
下面使用两种方法来进行音频降噪的处理:sox降噪和rnnoise降噪。
sox降噪
sox的 noisered 是一个经典的、基于噪声采样和谱减法的非AI降噪工具,原理直观,实现相对简单,对稳态噪声(如风扇声、空调声、恒定电流声)效果显著,noisered 效果器是其降噪的核心,核心原理步骤如下:
- 分析/训练阶段:核心是建立噪声指纹。SoX需要先“学习”噪声是什么样的。可以提供一段纯噪声片段(例如录音前的环境底噪),或者让它自动检测音频中能量较低的“静音”部分。它会分析这些片段,计算出一个平均噪声频谱,并保存为一个
.prof文件。这个文件就是后续降噪的参考基准。 - 降噪处理阶段:核心是频谱减法。
- 分帧与变换:将连续的音频信号切成短时重叠的帧,并通过FFT转换到频域。在频域,信号表现为不同频率的能量(幅度)和相位。
- 关键操作 - 谱减法:这是最核心的一步。算法会比较当前帧的频谱和之前学到的噪声样本频谱。基本思想非常简单:
干净信号频谱 ≈ 带噪信号频谱 - 噪声频谱。- 能量相减:主要操作是在能量/幅度谱上进行减法。当前帧某个频率的能量如果低于或接近噪声样本在该频率的能量,就会被大幅抑制;如果远高于,则会被保留。
- 相位保留:相位信息对于重建声音波形至关重要。谱减法通常不改变原始信号的相位,直接用降噪后的幅度谱和原始相位谱合成新信号。
- 抑制因子:SoX的
amount参数(0.0 到 1.0)控制减法力度。0.5意味着只减去一半的噪声能量,更为保守,能减少失真。
- 合成与输出:处理后的频域数据通过IFFT变回时域波形,再通过重叠相加方法将短时帧合成连续的音频信号,最终得到降噪后的音频。
看起来很复杂,但操作起来很简单,现在使用sox命令操纵一下就明白了。
sox命令降噪
#noise.wav是背景噪声,在安静状态下录制的一段10s的音频
ls
noise.wav speech.wav
#生成噪声profile(手动截取纯噪声5-10秒)
sox noise.wav -n noiseprof noise.prof
#降噪,0.21是经验值,绝大部分素材不会出现水声
sox speech.wav noisered_speech.wav noisered noise.prof 0.21
#对比播放,可以看出效果明显
aplay noise.wav
Playing WAVE 'noise.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Stereo
aplay speech.wav
Playing WAVE 'speech.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Stereo
aplay noisered_speech.wav
Playing WAVE 'noisered_speech.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Stereo
只是使用sox命令降噪,无法集成到嵌入式系统中,下面采用C语言,使用sox的库和API来进行音频降噪。
使用sox的库和API来进行音频降噪
代码结构如下:
(base) ubuntu@ubuntu-2204:~/baiwen/sox_noise_reduction$ tree -L 2
.
├── CMakeLists.txt
├── deps
│ ├── include
│ └── lib
├── include
│ ├── custom_effects.h
│ └── sox_noise_reduction.h
├── Makefile
└── src
├── custom_effects.c
├── main.c
└── sox_noise_reduction.c
5 directories, 7 files
编译
要编译这个demo,需要设置cmakelist.txt中得工具链
# 指定交叉编译器
set(CMAKE_C_COMPILER /home/ubuntu/rk3576_AI/buildroot/output/rockchip_rk3576/host/bin/aarch64-buildroot-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /home/ubuntu/rk3576_AI/buildroot/output/rockchip_rk3576/host/bin/aarch64-buildroot-linux-gnu-g++)
# 设置sysroot
set(CMAKE_SYSROOT /home/ubuntu/rk3576_AI/buildroot/output/rockchip_rk3576/staging)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
# 添加链接库
target_link_libraries(sox_noise_reduction
sox
)
#ubuntu22.04编译
(base) ubuntu@ubuntu-2204:~/baiwen/sox_noise_reduction$ make
Configuring CMake...
-- The C compiler identification is GNU 11.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ubuntu/baiwen/sox_noise_reduction/build
Building with 16 jobs...
make[1]: Entering directory '/home/ubuntu/baiwen/sox_noise_reduction/build'
make[2]: Entering directory '/home/ubuntu/baiwen/sox_noise_reduction/build'
make[3]: Entering directory '/home/ubuntu/baiwen/sox_noise_reduction/build'
make[3]: Leaving directory '/home/ubuntu/baiwen/sox_noise_reduction/build'
make[3]: Entering directory '/home/ubuntu/baiwen/sox_noise_reduction/build'
[ 75%] Building C object CMakeFiles/sox_noise_reduction.dir/src/sox_noise_reduction.c.o
[ 75%] Building C object CMakeFiles/sox_noise_reduction.dir/src/custom_effects.c.o
[ 75%] Building C object CMakeFiles/sox_noise_reduction.dir/src/main.c.o
[100%] Linking C executable sox_noise_reduction
make[3]: Leaving directory '/home/ubuntu/baiwen/sox_noise_reduction/build'
[100%] Built target sox_noise_reduction
make[2]: Leaving directory '/home/ubuntu/baiwen/sox_noise_reduction/build'
make[1]: Leaving directory '/home/ubuntu/baiwen/sox_noise_reduction/build'
#make push会通过adb 将sox_noise_reduction可执行文件推送到buildroot的/develo
(base) ubuntu@ubuntu-2204:~/baiwen/sox_noise_reduction$ make push
Running build/sox_noise_reduction...
build/sox_noise_reduction: 1 file pushed. 10.6 MB/s (23840 bytes in 0.002s)
运行
在rk3576上
root@rk3576-buildroot:/develop# ls
live_life.mp3 noise.wav sox_noise_reduction speech.wav
先在安静环境下录制一段 noise.wav的背景噪声,再对着麦克风说一段话speech.wav
root@rk3576-buildroot:/develop# ./sox_noise_reduction
SoX音频噪声降低处理开始
=======================
噪声文件: noise.wav
输入文件: speech.wav
输出文件: noisered_output.wav
降噪敏感度: 0.21
-----------------------
Processing...
[1/2] Creating noise profile...
Creating noise profile from: noise.wav
Processing noise profile...
Noise profile created: /tmp/noise_profile_NFk1uN.prof
[2/2] Applying noise reduction...
Applying noise reduction to: speech.wav
Processing audio with noise reduction...
Noise reduction applied. Output: noisered_output.wav
Done!
处理成功! 输出文件: noisered_output.wav
#使用aplay播放可以对比
aplay noise.wav
aplay speech.wav
aplay noisered_output.wav
可以听到 noisered_output.wav明显改善,但还有一些微弱的**“音乐噪声”,这是采用sox谱减法降噪固有的副作用,要完全去除,需要再设计一个维纳滤波**效果插件,进一步去除。
sox_noise_reduction的使用可以看-h的帮助信息
root@rk3576-buildroot:/develop# ./sox_noise_reduction -h
SoX音频噪声降低工具
====================
使用方法: ./sox_noise_reduction [选项]
选项:
-n 文件 噪声样本文件 (默认: noise.wav)
-i 文件 输入语音文件 (默认: speech.wav)
-o 文件 输出文件 (默认: noisered_output.wav)
-s 数值 降噪敏感度 0.0-1.0 (默认: 0.21)
-h 显示此帮助信息
参数说明:
敏感度: 0.0表示最强降噪(可能损伤语音),1.0表示最弱降噪
推荐值: 0.21 (经验值,适用于大多数音频素材)
使用示例:
./sox_noise_reduction # 使用所有默认设置
./sox_noise_reduction -n mynoise.wav # 指定噪声文件
./sox_noise_reduction -i myspeech.wav # 指定输入文件
./sox_noise_reduction -s 0.3 # 调整降噪强度
./sox_noise_reduction -o clean.wav # 指定输出文件
rnnoise降噪
RNNoise 是一个优秀的开源音频降噪工具,非常适合入门学习、快速集成和中等性能需求的场景。
- 技术原理:
- 结合传统信号处理(谱分析)与深度学习(RNN神经网络)。
- 输入音频分帧→提取特征(如频带能量、基音)→RNN预测每个频带的增益掩码(VAD也集成在其中)→输出降噪后的频谱→重建波形。
- 轻量化设计:
- 模型仅约86KB,适合嵌入式或实时处理。
- 单核CPU即可实时处理。
优点:
- 开源且易用:代码清晰,提供C语言API,易于集成到各类项目。
- 低延迟:帧处理延迟约10ms(默认帧长20ms),适合实时通信。
- 兼容性强:无第三方深度学习框架依赖,纯C实现。
- 语音保护较好:在抑制稳态噪声(如风扇声)的同时,对语音损伤较小。
局限性:
- 非通用降噪:主要针对语音通信优化,对音乐、突发噪声(如键盘声)效果有限。
- 参数固定:模型为通用场景训练,难以针对特定噪声定制。
- 残留“音乐噪声”:某些场景下可能引入类似水波的残留噪声。
- 不支持高采样率:默认仅支持48kHz/16kHz单声道,音乐降噪需调整。
编译
## 设置交叉编译工具链路径
export TOOLCHAIN_DIR="/home/ubuntu/rk3576_AI/buildroot/output/rockchip_rk3576/host/bin"
export CC="${TOOLCHAIN_DIR}/aarch64-buildroot-linux-gnu-gcc"
export CXX="${TOOLCHAIN_DIR}/aarch64-buildroot-linux-gnu-g++"
export AR="${TOOLCHAIN_DIR}/aarch64-buildroot-linux-gnu-ar"
export LD="${TOOLCHAIN_DIR}/aarch64-buildroot-linux-gnu-ld"
export RANLIB="${TOOLCHAIN_DIR}/aarch64-buildroot-linux-gnu-ranlib"
export STRIP="${TOOLCHAIN_DIR}/aarch64-buildroot-linux-gnu-strip"
# 设置目标架构
export ARCH="aarch64"
export CROSS_COMPILE="aarch64-buildroot-linux-gnu-"
# 设置sysroot(重要!)
export SYSROOT="/home/ubuntu/rk3576_AI/buildroot/output/rockchip_rk3576/staging"
export CFLAGS="--sysroot=${SYSROOT} -O2"
export LDFLAGS="--sysroot=${SYSROOT}"
echo "工具链设置完成"
echo "CC = $CC"
# 克隆项目并编译
git clone https://github.com/xiph/rnnoise.git
cd rnnoise
./autogen.sh
./configure \
--host=aarch64-buildroot-linux-gnu \
--build=x86_64-pc-linux-gnu \
--prefix=$(pwd)/tmp \
--enable-static \
--enable-shared \
CFLAGS="--sysroot=${SYSROOT} -O2" \
LDFLAGS="--sysroot=${SYSROOT}" \
CC="${CC}" \
CXX="${CXX}" \
AR="${AR}" \
LD="${LD}"
#编译
make
#安装到./tmp
make install
(base) ubuntu@ubuntu-2204:~/rnnoise$ tree -L 2 tmp
tmp
├── include
│ └── rnnoise.h
├── lib
│ ├── librnnoise.a
│ ├── librnnoise.la
│ ├── librnnoise.so -> librnnoise.so.0.4.1
│ ├── librnnoise.so.0 -> librnnoise.so.0.4.1
│ ├── librnnoise.so.0.4.1
│ └── pkgconfig
└── share
└── doc
(base) ubuntu@ubuntu-2204:~/rnnoise$ ls examples/
rnnoise_demo rnnoise_demo.c rnnoise_demo.o
./tmp目录下的文件就是需要使用的编译出来的rnnoise的头文件和库,用来做集成,examples下的rnnoise_demo就是参考实现,还有.c文件可以参考
adb push examples/.libs/rnnoise_demo /usr/bin/rnnoise_demo
adb push tmp/lib/librnnoise.so* /usr/lib/
现在可以到开发板进行简单的测试了
测试
# 先检查原始WAV文件信息
soxi speech.wav
# 如果采样率不是48000,先转换到48000
sox speech.wav -r 48000 speech_48k.wav
# 调整输入音量到合适范围(-3dB到-6dB)
# RNNoise要求:48000Hz,单声道,16位有符号整数PCM
sox speech_48k.wav -r 48000 -c 1 -e signed-integer -b 16 -t raw speech.pcm gain -n -3
# 运行RNNoise降噪
rnnoise_demo speech.pcm rnnoise.pcm
#转换回WAV格式
sox -r 48000 -c 1 -e signed-integer -b 16 -t raw rnnoise.pcm rnnoise.wav
使用rnnoise的库和API来进行音频降噪
代码结构
(base) ubuntu@ubuntu-2204:~/baiwen/rnnoise_reduction$ tree -L 3
.
├── CMakeLists.txt
├── deps
│ ├── include
│ │ └── rnnoise.h
│ └── lib
│ └── librnnoise.so
├── include
├── Makefile
└── src
└── main.c
5 directories, 5 files
其中 rnnnoise.h librnnoise.s0来自rnnoise的编译产物,直接复制就行,CMakeLists.txt需要更改工具链路径
# 指定交叉编译器
set(CMAKE_C_COMPILER /home/ubuntu/rk3576_AI/buildroot/output/rockchip_rk3576/host/bin/aarch64-buildroot-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER /home/ubuntu/rk3576_AI/buildroot/output/rockchip_rk3576/host/bin/aarch64-buildroot-linux-gnu-g++)
# 设置sysroot
set(CMAKE_SYSROOT /home/ubuntu/rk3576_AI/buildroot/output/rockchip_rk3576/staging)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
编译
make clean
make
#push adb到开发板的develop目录
make push
在开发板测试
root@rk3576-buildroot:/develop# ./rnnoise_reduction speech.wav rnnoise.wav -3
=== RNNoise音频降噪处理 ===
1. 读取WAV文件: speech.wav
采样率: 8000Hz, 声道: 2, 采样点数: 40000 (5.00秒)
2. 应用增益: -3.0dB
3. 重采样到48kHz
重采样后: 240000采样点 (5.00秒)
4. RNNoise降噪处理
处理帧数: 500, 每帧480个样本
第一帧前5个原始样本值: -34 -28 -23 -17 -11
处理后: 240000采样点 (5.00秒)
5. 保存为WAV文件: rnnoise.wav
=== 处理完成 ===
root@rk3576-buildroot:/develop# aplay speech.wav
Playing WAVE 'speech.wav' : Signed 16 bit Little Endian, Rate 8000 Hz, Stereo
root@rk3576-buildroot:/develop# aplay rnnoise.wav
Playing WAVE 'rnnoise.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Mono
可以听出明显的降噪效果