1.Speex音频降噪模块
相关文章链接:开源库Speex编解码,speex开源库分析(前置处理)
Speex是很强大的编解码库,也包含一些降噪,自动增益,回音消除等模块功能,Speex是开源的,Opus是Speex的更优替代方案,但是Opus没有降噪去噪模块,就具体我所在公司,我们公司使用的是Speex编码,没有使用更新的Opus,经过实际实验,Speex的去噪效果有限,话不多说,上过程:
部分代码:
#define USE_SPEEX_DENOISE 0
class CHHAudioEncoderG711ADenoise:public IHHAudioEncoder
{
public:
CHHAudioEncoderG711ADenoise(int samplerate,int bitsize):m_RetainCount(1)
{
m_encoder = new CHHAudioEncoderG711A;
#if USE_SPEEX_DENOISE
//帧长度,以20ms为例,帧长度=20*采样率/1000=(20ms内的采样点数量)
int framesize = 20*samplerate/1000;
m_context = speex_preprocess_state_init(framesize, samplerate);
int i=1;//1表示开启,0表示关闭
//SPEEX_PREPROCESS_SET_DENOISE表示降噪
speex_preprocess_ctl(m_context, SPEEX_PREPROCESS_SET_DENOISE, &i);//降噪
int noiseSuppress = -25;//噪音分贝数,是一个负值
//Speex的降噪是通过简单的设置音频数据的阀值,过滤掉低分贝的声音来实现的
//优点是简单,使用Speex编解码库时可以直接使用
//缺点是会把声音细节抹掉
speex_preprocess_ctl(m_context, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &noiseSuppress);
#endif
}
virtual ~CHHAudioEncoderG711ADenoise(void)
{
if (m_encoder){
m_encoder->Release();
m_encoder = NULL;
}
#if USE_SPEEX_DENOISE
if (m_context){
speex_preprocess_state_destroy(m_context);
m_context = NULL;
}
#endif
}
protected:
virtual void Retain()
{
++m_RetainCount;
}
virtual void Release()
{
if (--m_RetainCount==0) {
delete this;
}
}
virtual bool Encode(unsigned char *pInData,int nInLen,onAudioEncodeResultCallback func,void* param)
{
//去噪声
#if USE_SPEEX_DENOISE
//pInData是采集到的音频数据,因为上层的原因,采集到的缓存长度是320个字节
speex_preprocess_run(m_context, (short*)pInData);
#endif
//编码
m_encoder->Encode(pInData,nInLen,func,param);
return true ;
}
private:
unsigned long m_RetainCount;
IHHAudioEncoder* m_encoder;
#if USE_SPEEX_DENOISE
SpeexPreprocessState* m_context;//Speex预处理器指针
#endif
};
使用过程很简单,依次顺序为:
1.创建Speex预处理器指针:speex_preprocess_state_init
支持的采样率有3种:8K,16K,44K,采样送进去降噪的数据需要控制在20ms,也就是(20采样率/1000)*个采样点。
2.设置预处理器的参数:speex_preprocess_ctl
包括SPEEX_PREPROCESS_SET_DENOISE和SPEEX_PREPROCESS_SET_NOISE_SUPPRESS
3.处理一帧音频数据