webrtc NS 函数调用 自我学习

本文有部分是借鉴网上部分作者的,尽量注明来源,如有问题,请告知本人,及时删帖

文章只为能够吸引并且与更多人一起学习,若文章有任何问题,请告知本人,本人尽快改正


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的数据需要分为高频与低频两部分进行降噪,降噪后再讲两部分数据合并,8K16K的直接做为低频数据输入,不用进行高低频分开处理。

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高低频数据合成32Kvoid 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_state1filter_state2:滤波器(默认空间长度位6int型)

无返回值


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的处理后音频信号

webrtc NS 函数调用 自我学习_第1张图片

原含噪声音频信号含有比较明显的噪声

降噪强度为0的处理音频信号:噪声有一定幅度的降低,但是明显听到噪声

降噪强度为1:噪声进一步减少,但是还有稀疏的噪声存在

降噪强度为2:噪声抑制到人耳基本没有办法听到

降噪强度为3:噪声抑制跟2一样有明显抑制,但是感觉没什么太大区别


下图为分别为定点运算0/浮点运算0/定点运算1/浮点运算1的波形图或波形db图,两者差别通过耳朵基本无法判断准确两者的差距,但是浮点运算需要耗费的资源比较多。

webrtc NS 函数调用 自我学习_第2张图片


你可能感兴趣的:(webrtc NS 函数调用 自我学习)