博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用speex对pcm,wav进行降噪处理
阅读量:2715 次
发布时间:2019-05-13

本文共 5413 字,大约阅读时间需要 18 分钟。

1. speex的降噪模块的简介

speex的语音处理模块要使用独立于 speex codec库的libspeexdsp 库。

这个分离的库是在1.2版本后实现;

它这库包括了: 预处理,回声消除,jitter buffer 和重采样模块;

在Unix/Linux环境下,使用 -lspeexdsp -lm 来编译和链接。

 

和libspeex一样,库libspeexdsp的库函数都是可重入函数。

但它不是线程安全的,所以在多个线程中使用同一个实例时,必须加个线程安全锁。

 

NOTE:

所谓就是允许被的函数。

函数的递归调用是 指当一个函数正被调用尚未返回时,又直接或间接调用函数本身。

一般的函数不能做到这样,只有重入函数才允许递归调用.

 

2. 下载与编译

$ tar -zxvf

$ cd speexdsp-1.2rc3

$./configure --prefix=/data/speexdsp-1.2rc3-install/ --enable-static --disable-shared --with-pic

$ make && make install

 

3. API简介

预处理模块需要添加头文件:

#include <speex/speex_preprocess.h>

 

创建实例:

SpeexPreprocessState *preprocess_state = speex_preprocess_state_init(frame_size,sampling_rate);

参数: frame_size , 建议设置成编码器相同的值。

 

对于每一个输入帧,调用处理的函数:

speex_preprocess_run(preprocess_state, audio_frame);

参数: audio_frame , 即是输入,也是输出。

 

 

在某些场景下,有些降噪的数据并不想输出,可以下面的API:

它会更新处理器内部的状态,但不会将降噪后的数据输出,这样可以节省一些计算量:

speex_preprocess_estimate_update(preprocess_state, audio_frame);

 

 

使用下面API来改变进行预处理器的状态设置,更多的参数见下面的一节:

speex_preprocess_ctl(preprocess_state, request, ptr);

 

实例销毁 :

speex_preprocess_state_destroy(preprocess_state);

 

3.1 Preprocessor options

As with the codec, the preprocessor also has options that can be controlled using an ioctl()-like call. The available options are:

SPEEX_PREPROCESS_SET_DENOISE Turns denoising on(1) or off(2) (spx_int32_t)

SPEEX_PREPROCESS_GET_DENOISE Get denoising status (spx_int32_t)

SPEEX_PREPROCESS_SET_AGC Turns automatic gain control (AGC) on(1) or off(2) (spx_int32_t)

SPEEX_PREPROCESS_GET_AGC Get AGC status (spx_int32_t)

SPEEX_PREPROCESS_SET_VAD Turns voice activity detector (VAD) on(1) or off(2) (spx_int32_t)

SPEEX_PREPROCESS_GET_VAD Get VAD status (spx_int32_t)

SPEEX_PREPROCESS_SET_AGC_LEVEL

SPEEX_PREPROCESS_GET_AGC_LEVEL

SPEEX_PREPROCESS_SET_DEREVERB Turns reverberation removal on(1) or off(2) (spx_int32_t)

SPEEX_PREPROCESS_GET_DEREVERB Get reverberation removal status (spx_int32_t)

SPEEX_PREPROCESS_SET_DEREVERB_LEVEL Not working yet, do not use

SPEEX_PREPROCESS_GET_DEREVERB_LEVEL Not working yet, do not use

SPEEX_PREPROCESS_SET_DEREVERB_DECAY Not working yet, do not use

SPEEX_PREPROCESS_GET_DEREVERB_DECAY Not working yet, do not use

SPEEX_PREPROCESS_SET_PROB_START

SPEEX_PREPROCESS_GET_PROB_START

SPEEX_PREPROCESS_SET_PROB_CONTINUE

SPEEX_PREPROCESS_GET_PROB_CONTINUE

SPEEX_PREPROCESS_SET_NOISE_SUPPRESS Setmaximumattenuation of the noise in dB (negativespx_int32_t)

SPEEX_PREPROCESS_GET_NOISE_SUPPRESS Getmaximumattenuation of the noise in dB (negativespx_int32_t)

SPEEX_PREPROCESS_SET_ECHO_SUPPRESS Setmaximumattenuation of the residual echo in dB (negative spx_int32_t)

SPEEX_PREPROCESS_GET_ECHO_SUPPRESS Setmaximumattenuation of the residual echo in dB (negativespx_int32_t)

SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE Set maximum attenuation of the echo in dB when near

end is active (negative spx_int32_t)

SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE Set maximum attenuation of the echo in dB when near

end is active (negative spx_int32_t)

SPEEX_PREPROCESS_SET_ECHO_STATE Set the associated echo canceller for residual echo suppression (pointer

or NULL for no residual echo suppression)

SPEEX_PREPROCESS_GET_ECHO_STATE Get the associated echo canceller (pointer)

 

4. 应用实例

C语言实现的音频降噪代码如下。

代码中采样率、音频帧大小需要根据实际情况设置,

HEADLEN是WAV格式的文件头,占44个字节,这44个字节是不需要处理的,不然文件头会损坏,

导致得到的结果无法播放。

如果是PCM数据,则没有这个头,直接输入指定长度的数据就行;

 

noiseSuppress的值可以控制减除的噪声强度,负值越小,噪声去除的强度越大,

同时会造成原声的失真,需要作出权衡。

#include 
#include
#include
#include
#include
#include
#define HEADLEN 44#define SAMPLE_RATE (48000) #define SAMPLES_PER_FRAME (1024)#define FRAME_SIZE (SAMPLES_PER_FRAME * 1000/ SAMPLE_RATE)#define FRAME_BYTES (SAMPLES_PER_FRAME)int main(){ size_t n = 0; FILE *inFile, *outFile; fopen_s(&inFile, "./audio/input01L.wav", "rb"); fopen_s(&outFile, "./audio/output01L.wav", "wb"); char *headBuf = (char*)malloc(HEADLEN); char *dataBuf = (char*)malloc(FRAME_BYTES * 2 ); memset(headBuf, 0, HEADLEN); memset(dataBuf, 0, FRAME_BYTES); assert(headBuf != NULL); assert(dataBuf != NULL); SpeexPreprocessState *state = speex_preprocess_state_init(1024, SAMPLE_RATE); int denoise = 1; int noiseSuppress = -25; speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_DENOISE, &denoise); speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress); int i; i = 0; speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_AGC, &i); i = 80000; speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i); i = 0; speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_DEREVERB, &i); float f = 0; speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f); f = 0; speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f); //静音检测,效果一般 /* int vad = 1; int vadProbStart = 80; int vadProbContinue = 65; speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_VAD, &vad); speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_PROB_START, &vadProbStart); speex_preprocess_ctl(state, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &vadProbContinue); */ bool flag = true; while (1) { if (flag == true) { flag = false; n = fread(headBuf, 1, HEADLEN, inFile); if (n == 0) break; fwrite(headBuf, 1, HEADLEN, outFile); } else { n = fread(dataBuf, 1, SAMPLES_PER_FRAME, inFile); if (n == 0) break; speex_preprocess_run(state, (spx_int16_t*)(dataBuf)); fwrite(dataBuf, 1, SAMPLES_PER_FRAME, outFile); } } free(headBuf); free(dataBuf); fclose(inFile); fclose(outFile); speex_preprocess_state_destroy(state); return 0;}

转载地址:http://rjctd.baihongyu.com/

你可能感兴趣的文章
framebuffer驱动全篇
查看>>
高手进阶 Linux系统下MTD/CFI驱动介绍
查看>>
FAT32文件系统详细介绍
查看>>
开启Samba服务
查看>>
Linux2.6内核的新特性
查看>>
Linux操作系统内核启动参数详细解析
查看>>
对.lds连接脚本文件的分析
查看>>
linux系统2.6内核编译全过程
查看>>
Linux中阅读源代码工具Vim
查看>>
Linux 2.6 内核的嵌入式系统应用
查看>>
Makefile 常用函数表
查看>>
关于Linux Grep命令使用的详细介绍
查看>>
linux内核启动流程
查看>>
start_kernel分析
查看>>
Linux下ARM汇编教程
查看>>
busybox的init
查看>>
Linux中find常见用法示例
查看>>
ARM linux启动的流程
查看>>
bootloader技术内幕
查看>>
Linux 嵌入式启动以及优化
查看>>