應用speex進行音頻去噪,speex功能很強大,因為opus的出現,用speex進行編碼/解碼的人幾乎沒有了,但是用speex來進行降噪,去除回聲,增益還是很多。
這里用speex進行音頻去噪,主要用如下幾個關鍵點:
1,准確設置pcm音頻的音頻采樣率,和幀長度,
st = speex_preprocess_state_init(FRAME_SIZE, FRAME_SAMPLERATE);//初始化
2,設置降噪參數,其中DENOISE_DB默認是-25,單位是dB(分貝);
int denoise = 1;
int noiseSuppress = DENOISE_DB;
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &denoise); //降噪
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress); //設置噪聲的dB
源代碼如下,main函數參數一是原始pcm文件名,參數二是去噪后的pcm文件名
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include "speex/speex_preprocess.h"
#include <stdio.h>
#define FRAME_SIZE 1152
#define FRAME_SAMPLERATE 32000
#define DENOISE_DB (-90)
int main(int argn, char* argv[]) {
char* szInFilename = NULL;
char* szOutFilename = NULL;
FILE* pInFileHandle = NULL;
FILE* pOutFileHandle = NULL;
short in[FRAME_SAMPLERATE];
int i;
SpeexPreprocessState *st;
int count=0;
float f;
printf("starting....\r\n");
if(argn != 3){
printf("please input 2 parameters\r\n");
return -1;
}
memset((void*)empty, 0, sizeof(empty));
szInFilename = argv[1];
szOutFilename = argv[2];
pInFileHandle = fopen(szInFilename, "rb");
if(!pInFileHandle){
printf("open file %s error\r\n", szInFilename);
return -2;
}
pOutFileHandle = fopen(szOutFilename, "wb");
if(!pOutFileHandle){
printf("open file %s error\r\n", szOutFilename);
fclose(pInFileHandle);
return -3;
}
st = speex_preprocess_state_init(FRAME_SIZE, FRAME_SAMPLERATE);
int denoise = 1;
int noiseSuppress = DENOISE_DB;
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &denoise); //降噪
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress); //設置噪聲的dB
i=0;
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);
i=8000;
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &i);
i=0;
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i);
f=.0;
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
f=.0;
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
int vad = 1;
int vadProbStart = 80;
int vadProbContinue = 65;
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_VAD, &vad); //靜音檢測
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_START , &vadProbStart); //Set probability required for the VAD to go from silence to voice
speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &vadProbContinue); //Set probability required for the VAD to stay in the voice state (integer percent)
while (1)
{
int vad;
int iLen = fread(in, sizeof(short), FRAME_SIZE, pInFileHandle);
if(iLen <= 0){
break;
}
if (feof(pInFileHandle))
break;
vad = speex_preprocess_run(st, in);
if(vad != 0){
printf("speech.\r\n");
fwrite(in, sizeof(short), FRAME_SIZE, pOutFileHandle);
}else{
printf("slience############################\r\n");
fwrite(in, sizeof(short), FRAME_SIZE, pOutFileHandle);
}
count++;
}
speex_preprocess_state_destroy(st);
fclose(pInFileHandle);
fclose(pOutFileHandle);
return 0;
}
編譯的Makefile如下:
OBJS = test.o
CC = gcc
CFLAGS = -Wall -O -g -D HAVE_CONFIG_H
LD = /usr/local/lib/libspeexdsp.a
INCLUDE_PATH = /usr/local/include/speex
test : $(OBJS)
$(CC) $(OBJS) $(LD) -lm -I$(INCLUDE_PATH) -o test
test.o : test.c
$(CC) $(CFLAGS) -I$(INCLUDE_PATH) -c test.c
clean:
rm -rf *.o test
而編譯speexdsp-1.2rc3庫文件的腳本如下:
./configure --prefix=/usr/local --enable-shared --enable-static --enable-sse
make
make install
去噪后的效果,感覺不是很理想,原因應該是speex的去噪功能比較簡單,基本上是以來聲音分貝來進行去噪,所以不是很准確。
接下來去研究一下Audacity的源碼,看看是否能提高降噪效果。
相關網址:
https://github.com/audacity/audacity
