本文有部分是借鉴网上部分作者的,尽量注明来源,如有问题,请告知本人,及时删帖
文章只为能够吸引并且与更多人一起学习,若文章有任何问题,请告知本人,本人尽快改正
1、创建实体:NsHandle *pNS_inst = NULL;
2、创建webrtc降噪处理句柄:int WebRtcNs_Create(NsHandle** NS_inst);(定点数运算)
WebRtcNsx_Create();(利用浮点数运算)
返回值: 0 正常
-1 错误
3、初始化频率的降噪结构体参数:int WebRtcNs_Init(NsHandle* NS_inst, uint32_t fs);
WebRtcNsx_Init();(利用浮点数运算)
fs:采集数据的频率
返回值: 0 正常
-1 错误
4、设置降噪的策略(程度):int WebRtcNs_set_policy(NsHandle* NS_inst, int mode);
WebRtcNsx_set_policy();(利用浮点数运算)
mode:4种模式分别对应:0/1/2/3,数值越高,效果越明显
返回值: 0 正常
-1 错误
5、降噪处理:
降噪处理过程中每次取一帧的长度为10ms的数据,如果采样率为8K,则对应80个采样点,16K对应160,32K对应320;假如每次缓存的数据是8K16位的,长度为160字节,缓存的固定长度为320字节,会循环读取两次;
32K的数据需要分为高频与低频两部分进行降噪,降噪后再讲两部分数据合并,8K和16K的直接做为低频数据输入,不用进行高低频分开处理。
5.1 分频处理32K:void WebRtcSpl_AnalysisQMF(const int16_t* in_data,int in_data_length,int16_t* low_band,int16_t* high_band,int32_t* filter_state1,int32_t* filter_state2);
WebRtcSpl_AnalysisQMF();(利用浮点数运算)
in_data:输入原始数据(32K对应640个字节,对应short型320)
in_data_length:输入数据长度(320)
low_band:低频数据存储空间(320个字节,160个short型)
high_band:高频数据存储空间(320个字节,160个short型)
filter_state1、filter_state2:滤波器(默认空间长度位6个int型)
无返回值
5.2 降噪处理:int WebRtcNs_Process(NsHandle* NS_inst,short* spframe,short* spframe_H,
short* outframe,short* outframe_H);
WebRtcNsx_Process();(利用浮点数运算)
spframe:输入的低频段数据
spframe_H:输入的高频段数据
outframe:输出的低频段数据
outframe_H:输出的高频段数据
返回值: 0 正常
-1 错误
对于8K/16K数据来说并没有高频数据,因而对应高频直接输入为NULL
5.3 32K高低频数据合成32K:void WebRtcSpl_SynthesisQMF(const int16_t* low_band,
const int16_t* high_band,int band_length,int16_t* out_data,
int32_t* filter_state1,int32_t* filter_state2);(定点与浮点算法一样)
low_band:最后处理完后输出低频数据
high_band:最后处理完后输出高频数据
band_length:数据长度,对应每段的长度,short型
out_data:合成后的输出数据
filter_state1、filter_state2:滤波器(默认空间长度位6个int型)
无返回值
6、 销毁释放实体:int WebRtcNs_Free(NsHandle* NS_inst);
返回值: 0 正常
-1 错误
附上源码:
#include
#include
#include
#include "../WebRtcMoudle/signal_processing_library.h"
#include "../WebRtcMoudle/noise_suppression.h"
void NoiseSuppression32(char *szFileIn,char *szFileOut,int nSample,int nMode)
{
int nRet = 0;
NsHandle *pNS_inst = NULL;
FILE *fpIn = NULL;
FILE *fpOut = NULL;
char *pInBuffer =NULL;
char *pOutBuffer = NULL;
do
{
int i = 0;
int nFileSize = 0;
int nTime = 0;
if (0 != WebRtcNs_Create(&pNS_inst))
{
printf("Noise_Suppression WebRtcNs_Create err! \n");
break;
}
if (0 != WebRtcNs_Init(pNS_inst,nSample))
{
printf("Noise_Suppression WebRtcNs_Init err! \n");
break;
}
if (0 != WebRtcNs_set_policy(pNS_inst,nMode))
{
printf("Noise_Suppression WebRtcNs_set_policy err! \n");
break;
}
fpIn = fopen(szFileIn, "rb");
if (NULL == fpIn)
{
printf("open src file err \n");
break;
}
fseek(fpIn,0,SEEK_END);
nFileSize = ftell(fpIn);
fseek(fpIn,0,SEEK_SET);
pInBuffer = (char*)malloc(nFileSize);
memset(pInBuffer,0,nFileSize);
fread(pInBuffer, sizeof(char), nFileSize, fpIn);
pOutBuffer = (char*)malloc(nFileSize);
memset(pOutBuffer,0,nFileSize);
int filter_state1[6],filter_state12[6];
int Synthesis_state1[6],Synthesis_state12[6];
memset(filter_state1,0,sizeof(filter_state1));
memset(filter_state12,0,sizeof(filter_state12));
memset(Synthesis_state1,0,sizeof(Synthesis_state1));
memset(Synthesis_state12,0,sizeof(Synthesis_state12));
nTime = GetTickCount();
for (i = 0;i < nFileSize;i+=640)
{
if (nFileSize - i >= 640)
{
short shBufferIn[320] = {0};
short shInL[160],shInH[160];
short shOutL[160] = {0},shOutH[160] = {0};
memcpy(shBufferIn,(char*)(pInBuffer+i),320*sizeof(short));
//首先需要使用滤波函数将音频数据分高低频,以高频和低频的方式传入降噪函数内部
WebRtcSpl_AnalysisQMF(shBufferIn,320,shInL,shInH,filter_state1,filter_state12);
//将需要降噪的数据以高频和低频传入对应接口,同时需要注意返回数据也是分高频和低频
if (0 == WebRtcNs_Process(pNS_inst ,shInL ,shInH ,shOutL , shOutH))
{
short shBufferOut[320];
//如果降噪成功,则根据降噪后高频和低频数据传入滤波接口,然后用将返回的数据写入文件
WebRtcSpl_SynthesisQMF(shOutL,shOutH,160,shBufferOut,Synthesis_state1,Synthesis_state12);
memcpy(pOutBuffer+i,shBufferOut,320*sizeof(short));
}
}
}
nTime = GetTickCount() - nTime;
printf("n_s user time=%dms\n",nTime);
fpOut = fopen(szFileOut, "wb");
if (NULL == fpOut)
{
printf("open out file err! \n");
break;
}
fwrite(pOutBuffer, sizeof(char), nFileSize, fpOut);
} while (0);
WebRtcNs_Free(pNS_inst);
fclose(fpIn);
fclose(fpOut);
free(pInBuffer);
free(pOutBuffer);
}
int main(int argc, char* argv[])
{
NoiseSuppression32("lhydd_1C_16bit_32K.PCM","lhydd_1C_16bit_32K_ns.pcm",32000,0);
getchar();
return 0;
}
结果分析:
从上到下分别为原含噪声音频信号、降噪强度分别为0/1/2/3的处理后音频信号
原含噪声音频信号含有比较明显的噪声
降噪强度为0的处理音频信号:噪声有一定幅度的降低,但是明显听到噪声
降噪强度为1:噪声进一步减少,但是还有稀疏的噪声存在
降噪强度为2:噪声抑制到人耳基本没有办法听到
降噪强度为3:噪声抑制跟2一样有明显抑制,但是感觉没什么太大区别
下图为分别为定点运算0/浮点运算0/定点运算1/浮点运算1的波形图或波形db图,两者差别通过耳朵基本无法判断准确两者的差距,但是浮点运算需要耗费的资源比较多。