webrtc_noise_suppression
原因:由于APM中涉及到去噪模块,故在此进行简单调用和原理分析
概况:通过对信号的初始噪声估计得出一个语音/噪声概率函数,然后通过该函数估计出每帧数据的噪声,然后使用维纳滤波器将噪声进行抑制。故重点为噪声估计的准确性。而噪声估计依赖于语音/噪声概率函数,而语音/噪声概率函数是通过使用映射函数将每帧的信号分类特征映射到一个概率值而得出。每帧的分类特征包括:频谱平坦度,频谱差异,LRT均值特征。

伪代码实现如下:
首先设置提取特征的参数信息
// Initialize state.
int WebRtcNs_InitCore(NoiseSuppressionC* self, uint32_t fs) {
set_feature_extraction_parameters(self);
}
针对每帧进行特征值的提取并映射得出语音/噪声概率函数.
void WebRtcNs_AnalyzeCore(NoiseSuppressionC* self, const float* speechFrame) {
// Quantile noise estimate.
NoiseEstimation(self, magn, noise);噪声估计
// Post and prior SNR needed for SpeechNoiseProb.
ComputeSnr(self, magn, noise, snrLocPrior, snrLocPost);计算信噪比
FeatureUpdate(self, magn, updateParsFlag);更新特征值
SpeechNoiseProb(self, self->speechProb, snrLocPrior, snrLocPost);计算语音/噪声概率
UpdateNoiseEstimate(self, magn, snrLocPrior, snrLocPost, noise);更新噪声估计
}
static void FeatureUpdate(NoiseSuppressionC* self,
const float* magn,
int updateParsFlag) {
// Compute spectral flatness on input spectrum.
ComputeSpectralFlatness(self, magn);计算谱平坦度
// Compute difference of input spectrum with learned/estimated noise spectrum.
ComputeSpectralDifference(self, magn);计算谱差异
}
根据估计出的语音/噪声概率函数估计当前帧噪声,并进行维纳滤波进行抑制
void WebRtcNs_ProcessCore(NoiseSuppressionC* self,
const float* const* speechFrame,
size_t num_bands,
float* const* outFrame) {
ComputeDdBasedWienerFilter(self, magn, theFilter);
}
测试伪代码如下
NsHandle *phandle = WebRtcNs_Create();
int ir = WebRtcNs_Init(phandle, iSampleRate);
ir = WebRtcNs_set_policy(phandle, 0);
while (iR)
{
WebRtcNs_Analyze(phandle, pbuff);
WebRtcNs_Process(phandle, &pbuff, 1, &pbout);
}
波形对比:明显看出降噪后能量值也被衰减.


测试工程地址:https://github.com/quanwstone/WebRTC
总结:通过测试流程和源码可以得知noise_suppression的实现原理.具体实现细节算法未完待续。
智能推荐
Worley Noise(二)
根据前文所述,Worley噪声代码实现比较简单,我们着重讲解一下2D噪声的算法,3D、4D实现基本一致,不作详细描述。 一、Worley Noise 2D实现 还是与以前一样,我们分步来实现Worley噪声,根据前文步骤,Worley噪声实现共分六步: 第一步、确定输入点所在的晶胞 这与Perlin噪声确定输入点所在晶格是一样...
Value Noise(二)
一、Value Noise 1D 根据之前学习的Value 噪声原理,我们分步来实现之。但在这之前,我们还有一些准备工作要做,如之前所说的,Value噪声是将随机值赋于晶格点,然后根据输入点所处晶格,对随机值进行线性插值而得到噪声值,所以,我们首先初始化一个晶格顶点值数组,并将各顶点的随机值保存在顶点上,在实施中,我们初始化了一个长度512的float数组保存我们的晶格顶点...
Perlin noise(一)
Perlin noise(一) 一、分形噪声 分形几何学的基本思想是:客观事物具有自相似的层次结构,局部与整体在形态、功能、信息、时间、空间等方面具有统计意义上的相似性,称为自相似性。客观自然界中许多事物,具有自相似的“层次”结构,在理想情况下,甚至分形分形至具有无穷层次。适当的放大或缩小事物的几何尺寸,整个结构并不改变。不少复杂的物理现象,背后就是...
Perlin noise(二)
Perlin noise(二) 通过前面两篇文章,我们现在对噪声已经有了初步的了解,对Perlin噪声生成原理也进行了阐述,现在是时候开始学习噪声生成了,即将进入程序纹理这个神秘而又让人觊觎的国度了。 (一)、1D Perlin Noise 前面我们是以2D Perlin 噪声来讲解Perlin噪声的原理的,对于1D Perlin噪声,我们首先要明白...
Perlin noise(三)
Perlin noise(三) 前文学习了1D、2D Perlin噪声的生成算法,本文将更进一步,学习3D、4D Perlin噪声的生成。我们不仅需要2D的噪声面纹理,也需要3D的体纹理(后面将进一步学习),同时,我们可以利用3D体纹理来生成2D动态面纹理,也可以利用4D的超纹理来生成3D的动态体纹理,这就是我们为什么要学习4D Perlin噪声的原因。4D Perlin噪...
猜你喜欢
OSPF prefix-suppression Test
OSPF prefix-suppression Test From: fuhrer 当前C9500的OSPF进程中配置了通告所有前缀的命令,导致本次新增的1段用于打通VRF互联的subnet也进入了OSPF路由表。 示例: Router ospf 100 Network 0.0.0.0 255.255.255.255 area 0 现不希望将这条直连网段的prefix存在于OSPF路由表中,以免日...
Linux信号及工作原理
什么是信号 信号可以理解为软件中断,是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是差不多的。信号是异步的,一个进程不必通过任何操作来等待信号的到达。信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统事件。 谁来产生信号 信号事件的发生有两个...
手机端图片放大,双指放大,元素的双指缩放
在做webapp时候,遇到一个需要做双指放大的功能,需求是:一张带有坐标的图片上有固定的点,需要点击这些坐标上的点进入相应的商品,并且需要对这一块进行双指可以缩放,双击缩放; 一开始是自己写监听touch事件进行处理,但是再缩放的时候,偶尔出现卡顿闪烁,用户体验不很好,后来采用插件 pinch-zoom GitHub地址: https://github.com/manuelstofer/...
redis 初步了解
1.连接redis 通过java操作 1.首先 导入redis驱动 2.连接redis通过jedis 2.创建redis连接池 连接redis通过 jedis 相当于HTTPclient 1.创建单例模式的方法 在调用的时候被创建 2.创建私有静态 jedisPool 3. 创建私有类 创建静态代码块 放入连接池的基本配置 4.有 最大连接数 最大空闲书 最小空闲连接数 5. 创建连接redis对...
