speex库中音频降噪效果不错,应该是应用最广泛的吧,speex库下载地址https://www.speex.org/downloads/,可以直接下载二进制代码使用,像配置OpenCV一样配置speex库就可以了。speex库的API参考文档下载:http://download.csdn.net/detail/yizhaoyanbo/9856894。
贴出C语言实现的音频降噪代码如下。
代码中采样率、音频帧大小需要根据实际情况设置,HEADLEN是WAV格式的文件头,占44个字节,这44个字节是不需要处理的,不然文件头会损坏,导致得到的结果无法播放。
noiseSuppress的值可以控制减除的噪声强度,负值越小,噪声去除的强度越大,同时会造成原声的失真,需要作出权衡。
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <assert.h> #include <string.h> #include <speex/speex_preprocess.h> #include <speex/speex.h> #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; }