speex库音频降噪(含代码)

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;
}

 

posted @ 2017-06-07 22:21  一度逍遥  阅读(12076)  评论(0编辑  收藏  举报