现在来分析静音检测
语音通话,基本上是一方听,一方说,采用静音检测可以起到节省一半带宽的作用
网络上有很多静音检测的代码,基本的思路,都是构造一个自适应的能量探测试,
低于阀值时,就认为出现静音
g723的思路基本与此相同
Comp_Vad 这个函数负责静音栽决,看代码吧,
这里笔者只分析算法,不再纠结定点数运算引起的数值缩放的问题了
g723的静音检测,检测了当前帧的180个样点(后60样点由于没有在当前帧里处理)
首先看到ScfTab这个静态数组
因为门限值的计算涉及到log,采用了类似711里的算法,用一系列折线段来近似指数函数
底为0.89 参考门限值公式10^(-0.05)约等于0.89
static Word16 ScfTab[11] = {//lsc 这里是一系列折线的斜率,用于计算近似的指数函数 注意:因为采用的是归一化的位移作自变量,所以这个表是递增的,把0.89的指数函数的第一象限"反"过来看(这里显得很绕,笔者也纠结了很久)
9170 ,
9170 ,
9170 ,
9170 ,//lsc 0.277 * 32768 = 9093 这个点基本吻合 0.277 为 0.89^11
10289 ,//lsc 0.313995361328125=10,
11544 ,//lsc 0.352294921875=9?
12953 ,//lsc 0.395=8?
14533 ,//lsc 0.4435=0.89^7 ?
16306 ,//lsc 6 0.49761962890625=0.89^6
18296 ,//lsc 5 0.558349609375=0.89^5
20529 ,//lsc 0.626=0.89^4
} ;
这个数组里的值为0.89^(n)扩大32768倍, n取值范围(4~11)
从四个子帧里找出基音周基最小的一个,存入Minp
/* Find Minimum pitch period */ //lsc VadStat.Polp 是从Line.Olp中取来的,每一帧保存两个(因为基音周期是每120采样计算一次)
Minp = PitchMax ;
for ( i = 0 ; i < 4 ; i ++ ) {
if ( Minp > VadStat.Polp[i] )
Minp = VadStat.Polp[i] ;
}
判断当前帧是否处理浊音段,依据为,如果所有子帧的基音周期都约为Minp的整数倍,
即认为当前帧是浊音段,代码片段
//lsc itu的中文翻译有误,当tm2=4时,应认为是浊音,见itu的英文版,是voice
Tm2 = 0 ;
for ( i = 0 ; i < 4 ; i ++ ) {
Tm1 = Minp ;
for ( j = 0 ; j < 8 ; j ++ ) {
Tm0 = sub( Tm1, VadStat.Polp[i] ) ;
Tm0 = abs_s( Tm0 ) ;
if ( Tm0 <= 3 )//lsc 如果在倍数附近,差值不大于3,为浊音加分,都在倍数附近,就是浊音了
Tm2 ++ ;
Tm1 = add( Tm1, Minp ) ;//lsc 用减法和加法,循环8次,代替除法
}
}
尾响处理,如果是浊音,之后的6个帧会被认为非静音,这个处理是避免元音段被不正确地截了
代码片段
/* Update adaptation enable counter if not periodic and not sine */
if ( (Tm2 == 4) || (CodStat.SinDet < 0) )//lsc 浊音,要添加尾响
VadStat.Aen += 2 ;
else
VadStat.Aen -- ;
/* Clip it */
if ( VadStat.Aen > 6 )//lsc 尾响限制为6帧
VadStat.Aen = 6 ;
if ( VadStat.Aen < 0 )
VadStat.Aen = 0 ;
与网络上流行的算法不同的是,g723做了滤波,对静音的判断是基于激励的能量
逆向滤波代码片段如下:
//lsc 逆向滤波
/* Inverse filter the data */
Acc1 = 0L ;
for ( i = SubFrLen ; i < Frame ; i ++ ) {
Acc0 = L_mult( Dpnt[i], 0x2000 ) ;
for ( j = 0 ; j < LpcOrder ; j ++ )
Acc0 = L_msu( Acc0, Dpnt[i-j-1], VadStat.NLpc[j] ) ;
Tm0 = round ( Acc0 ) ;
Acc1 = L_mac( Acc1, Tm0, Tm0 ) ;//lsc 计算出能量
}
其中的VadStat.NLpc这个数组,是在计算舒适背景音时,形成的一个平均滤波器,笔者将
在介绍舒适背景音时详细介绍这个lpc系数的生成,这里,只需要知道它是一个滤波器,
可以得到残差信号即可
噪声能量估值
/* Scale the rezidual energy */
Acc1 = L_mls( Acc1, (Word16) 2913 ) ;//lsc 这可能是除11.22(32768/2913=11.24),噪声能量估值 2913 * 11.22 = 32684(32767?) 10^1.05 = 11.220184543019634355910389464779
这里要注意,观察itu g723文档的vad章节的 A-5公式,它把10^1.05这个因子挪过来了,而把80这个因子移给了thrd的计算,绕得很
对噪声能量做个限制
/* Clip noise level in any case */ //lsc 如果噪声能量太大,更新噪声的能量,加前一帧噪声能量估值的3/4,再取1/4,形成当前噪声能量
if ( VadStat.Nlev > VadStat.Penr ) {
Acc0 = L_sub( VadStat.Penr, L_shr( VadStat.Penr, 2 ) ) ;
VadStat.Nlev = L_add( Acc0, L_shr( VadStat.Nlev, 2 ) ) ;
}
根据当前帧是元音还是辅音,做一个适当放大处理,盖因辅音段,在g723的编码模型里,就认为是由一个随机信号激励形成的
/* Update the noise level, if adaptation is enabled */
if ( !VadStat.Aen ) {//lsc 如果是清音
VadStat.Nlev = L_add( VadStat.Nlev, L_shr( VadStat.Nlev, 5 ) ) ;
}
/* Decay Nlev by small amount */
else {//lsc 如果是浊音,或者处于尾响阶段
VadStat.Nlev = L_sub( VadStat.Nlev, L_shr( VadStat.Nlev,11 ) ) ;
}
近一步限制噪声能量的取值范围 最小128 最大16383
/* Update previous energy */
VadStat.Penr = Acc1 ;
/* CLip Noise Level */
if ( VadStat.Nlev < 0x00000080L )
VadStat.Nlev = 0x00000080L ;
if ( VadStat.Nlev > 0x0001ffffL )
VadStat.Nlev = 0x0001ffffL ;
接来计算门限系数,这里涉及到用折线段来模拟指数函数,
知道是这么处理的就可以了.
最后将噪声能量估值与门限系数相乘,然后与激励能量比较,来判断是否为静音帧
代码片段如下:
/* Compute the threshold */ //lsc 这里计算门限,本质而言,还是一个能量探测器
Acc0 = L_shl( VadStat.Nlev, 13 ) ;
Tm0 = norm_l( Acc0 ) ;
Acc0 = L_shl( Acc0, Tm0 ) ;
Acc0 &= 0x3f000000L ;//lsc 笔者认为,itu可能把10这个因子塞在这里了,把10拆成(10^0.005)^20,塞进指数里,做了缩放,纠结的运算啊
Acc0 <<= 1 ;//lsc
Tm1 = extract_h( Acc0 ) ;
Acc0 = L_deposit_h( ScfTab[Tm0] ) ;
Acc0 = L_mac( Acc0, Tm1, ScfTab[Tm0-1] ) ;//lsc 这两行计算斜率,插值
Acc0 = L_msu( Acc0, Tm1, ScfTab[Tm0] ) ;
Tm1 = extract_h( Acc0 ) ;
Tm0 = extract_l( L_shr( VadStat.Nlev, 2 ) ) ;
Acc0 = L_mult( Tm0, Tm1 ) ;
Acc0 >>= 11 ;//lsc 这里隐含着扩大8位, 15+1-2=14 而只右移11位,则扩大了8倍,这样基本算是找到了文档的1/80分之一的因子了
/* Compare with the threshold */ //lsc 0表示为静音 笔者认为文档中的描述有误,应该是thr*nlev与能量比较,至少从代码看,是这样,纠结啊
if ( Acc0 > Acc1 )
VadState = 0 ;
尾响处理,如果是元音,后面的6帧认为非静音,比较简单,笔者就不列出代码了
总结:
g723的能量检测仍然基于能量检测的
林绍川
2012.1.5 于杭州
分享到:
相关推荐
《G.723源码分析注释》 在深入探讨G.723编码技术之前,我们首先要了解什么是G.723。G.723是国际电信联盟(ITU)制定的一种音频压缩标准,主要用于低带宽的语音通信,如VoIP(Voice over IP)系统。该标准定义了两种...
19--[星光小学计算机特长班作品----静音时钟].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码19--[星光小学计算机特长班作品----静音时钟].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码19--...
Ext grid中渲染进度条,超帅 源码-----下载不扣分,回帖加1分,欢迎下载,童叟无欺。Ext grid中渲染进度条,超帅 源码-----下载不扣分,回帖加1分,欢迎下载,童叟无欺。Ext grid中渲染进度条,超帅 源码-----下载不扣分...
医学影像分析-基于python的3D-CT影像的肺结节检测算法源码+文档说明+数据集医学影像分析-基于python的3D-CT影像的肺结节检测算法源码+文档说明+数据集医学影像分析-基于python的3D-CT影像的肺结节检测算法源码+文档...
医学影像分析-基于python的3D-CT影像的肺结节检测算法源码+项目说明+LUNA16数据集.zip 医学影像分析-基于python的3D-CT影像的肺结节检测算法源码+项目说明+LUNA16数据集.zip 医学影像分析-基于python的3D-CT影像的肺...
茶叶目标检测_基于YOLOv5实现茶叶目标检测算法_附项目源码+流程教程_优质项目实战
使用TensorRT部署RT-DETR目标检测算法python源码.zip使用TensorRT部署RT-DETR目标检测算法python源码.zip使用TensorRT部署RT-DETR目标检测算法python源码.zip使用TensorRT部署RT-DETR目标检测算法python源码.zip使用...
9-DeformableDetr物体检测源码分析 10-MedicalTrasnformer论文解读 11-MedicalTransformer源码解读 12-商汤LoFTR算法解读 13-局部特征关键点匹配实战 14-分割模型Maskformer系列 15-Mask2former源码解读 16-BEV特征...
基于object-c实现人脸识别活体检测眨眼检测ios源码.zip基于object-c实现人脸识别活体检测眨眼检测ios源码.zip基于object-c实现人脸识别活体检测眨眼检测ios源码.zip基于object-c实现人脸识别活体检测眨眼检测ios源码...
缺陷检测-基于深度学习实现的高效轮胎磨损+缺陷检测算法实现python源码.zip缺陷检测-基于深度学习实现的高效轮胎磨损+缺陷检测算法实现python源码.zip缺陷检测-基于深度学习实现的高效轮胎磨损+缺陷检测算法实现...
原生微信小程序源码 - -人脸检测 原生微信小程序源码 - -人脸检测
C#源码系列7---一个开源ERP源码(C#)
QGC地面站源码剖析-「MAVLink检测」页面
这篇文档将详细解析`GestureDetector`的使用方法,并结合提供的源码进行深入探讨。 ### 一、GestureDetector简介 `GestureDetector`是Android框架中的一个工具类,主要用于识别和处理常见的触摸屏手势。它可以监听...
静音检测(VAD)是一种音频处理技术,用于判断输入的音频流是否包含语音。在WebRTC中,VAD被用于识别并丢弃静默时间段的音频数据,这对于网络通信尤其重要,因为减少无用数据传输可以显著降低延迟并优化网络资源利用...
Python开发基于Opencv的车道线检测源码-可作毕设.zipPython开发基于Opencv的车道线检测源码-可作毕设.zipPython开发基于Opencv的车道线检测源码-可作毕设.zipPython开发基于Opencv的车道线检测源码-可作毕设....
使用casme2数据集训练的微表情识别,支持摄像头、图片视频检测-源码+详细文档说明,含有代码注释,新手也可看懂,个人手打98分项目,导师非常认可的高分项目,毕业设计、期末大作业和课程设计高分必看,下载下来,...
Android 蓝牙配对连接源码分析文档大全,非常详细的从btif-bta-btm-hci 数据流程走向,以及从controller收到数据到btm层,将Android 源码每个函数都摘录出来,进行分析,使Android 蓝牙开发者更清楚数据收发走向,...
AutoJs源码-静音或恢复音量。本资源购买前提醒:本源码都是实际autojs项目模板,安装好autojs直接运行即可打开。1、支持低版本autojs。2、资源仅供学习与参考,请勿用于商业用途,否则产生的一切后果将由您自己承担...
Spring Security OAuth2 是一个强大的框架,用于为Java应用提供OAuth2和OpenID Connect...通过阅读和分析`spring-security-oauth-master`中的源码,可以更深入地了解其实现细节,有助于在实际项目中灵活运用和定制。