首页 > 编程知识 正文

趣味语音计算器(智能客服搭建(4) - 语音流的分贝计算)

时间:2023-05-05 04:29:10 阅读:123269 作者:2465

目录1 .研究背景(1)思路)2)分贝概念)2. MRCP的声音流处理浅析)1)声音能量计算源代码)2)带VAD功能实现3声音的基本概念)1(声音强度和声压)2)声压级spl )3)声源

1 .研究背景

最近从事了一些语音相关的开发,为了计算和量化实时音频流的语音相关数据,进行了一些相关的研究。

(1)思维方式平时用电脑控制音量是0-100来调整的,这是相对的音量感觉,标准测量不好。 之后,在网上查了资料,决定使用分贝客观地评价声音的大小。

) )分贝的概念分贝(decibel,/'ds.bl/)是测量两个相同单位的数量比的测量单位,主要用于测量声音的强度,通常用dB表示。

“分”(deci-)指十分之一,一位为“贝”(bel ),一般只采用分贝。 分贝是以美国发明家CSDfy(AlexanderGrahamBell )的名字命名的。

分贝自检表如下所示。 请作为参考。

分贝值的实际效果0分贝刚听到的声音15分贝以下安静的感觉30分贝耳语的音量大小40分贝冰箱的嗡嗡声60分贝正常对话的声音70分贝走在闹市区85分贝汽车来往的路上95分贝的欧音作为一名爱养病的作者,他曾经常播放110分贝的电钻,150分贝的MP3声、120分贝的飞机起飞时发出的150分贝的烟花爆竹,顺便引起美国语言听力协会的注意,如果长时间晚上受到50分贝的噪音,那么55分贝,60分贝对孩子的学习有负面影响,从睡梦中醒来; 70分贝,心肌梗死发病率可增加30%左右; 超过110分贝,可能会引起永久性听力损伤。

2. MRCP的语音流处理浅析)1)语音能量计算源代码在以前的MRCP Server开发过程中,阅读了源代码附带的VAD功能,源代码/libs/mpf/src/mpf _ activity

satic apr _ size _ tmpf _ activity _ detector _ level _ calculate (const mpf _ frame _ t * frame ) apr_size_tsize const apr _ int 16 _ t * cur=frame-codec _ frame.buffer; const apr_int16_t *end=cur count; for (; cur end; cur () if ) cur ) {sum -=*cur; }else {sum =*cur; } }返回和计数; }在有噪声的环境中,上述代码不会有效,因为它会根据frame中的信息粗暴地将能量相加。

)2)关于带VAD功能的安装已经叙述到这里。 另外,在MRCP的端点检测中,当调用函数mpf_activity_detector_create进行初始化时,静默能量的大小在silence_timeout参数中默认设置为300

/* * createactivitydetector */mpf _ declare (mpf _ activity _ detector _ t * ) mpf_activity_detector_create ) 检测器- level _ threshold=12;/*0. 255 * /检测器- speech _ time out=300;/* 0.3s * /检测器- silence _ time out=300;/* 0.3s * /检测器- no input _ time out=5000;//检测器-持续时间=0; 检测器- state=detector _ state _ in activity; 返回检测器; }我们可以通过mpf _ activity _ detector _ silence _ time out _ set修改VAD能量的大小。 我想用花了巨额资金买的播音员麦,用自己的语言测试的方式试验silence_timeout的合适值,后来放弃了。 (后来,播音员麦

/* * settimeoutrequiredtotriggersilence (传输流程识别器(*/mpf _ declare ) void ) mpf_activity )

r_size_t silence_timeout){detector->silence_timeout = silence_timeout;}

  具体MRCP自带VAD判断的方法在函数mpf_activity_detector_process中,感兴趣的可以自己去查看,总的思路就是设置了4种状态,需要经过这个状态来累计设定的时长,如果满足了,才会切换,否则不予切换,希望详细了解的可以参考文末的一些文章。

3 语音的基本概念

  之前查了很多资料,都是使用SPL进行计算的,写完后测试总是不符合分贝效果的预期,后来进行调试后,感觉实际用的是SL进行计算,下面进行介绍。

(1) 声强与声压

  声强(I):声波平均能流密度的大小。

  声压§:大气压受到声波扰动后产生的变化,即为大气压强的余压,它相当于在大气压强上的叠加一个声波扰动引起的压强变化。

  他们之间的关系如下公式:

I = frac{p^2}{rhonu}

  其中

I: 声强p: 声压rho: 介质密度nu: 表示水中声速 (2) 声压级SPL

  声压级定义为将待测声压有效值p(e)与参考声压p(ref)的比值取常用对数,再乘以20,用SPL表示。

SPL = 20lgfrac{p_e}{p_{ref}}

  其中

p_e: 声压有效值声压(p_e) = sqrt{声强(I)*介质密度(rho)*声速(C)}rho: 空气中介质密度1.293声速: 340m/sp_{ref}: 基准参考声压,一般在空气中的值为2*10^{-5} (Pa)

  对于数字麦克风计算声压级,看到了一篇帖子,还没有详细进行测试,相关链接放在文末,感兴趣的可以深入了解。

(3) 声源级SL

  声轴上距声源1米处产生的声强相对于参考声强的分贝数。是声纳方程中定量描述声源辐射能力的项,用 SL表示。

SL = 10lgfrac{I}{I_0}

  其中

I: 表示离声源中心1m处的声强I_0: 表示参考声强,值为0.67 4. 代码实践

  下面函数实现的功能为获取语音流数据后,对语音数据进行计算的函数:

size_t mpf_activity_detector_level_calculate(const char *data, int dataSize){ size_t sum = 0; size_t count = dataSize / 2; const short *cur = data; const short *end = cur + count; for (; cur < end; cur++) { if (*cur < 0) { sum -= *cur; } else { sum += *cur; } } size_t ret = sum / count; printf("------------mpf_activity_detector_level_calculate() I: %ldn", ret); // 声压(p)的平方=声强(i)×介质密度(ρ)×声速(c) // 声强单位是:w / m2 // 密度单位:kg / m3 // 声速:m / s double pe = sqrt((double)(ret * 1.293 * 340)); double pref = 0.00002; // SPL = 20LOG(10)[p(e) / p(ref)] // 空气中参考声压p(ref)一般取为2*10E-5帕 int SPL = (int)(20.0 * log10(pe / pref)); printf("------------mpf_activity_detector_level_calculate() SPL: %d, p(e): %lf, p(ref): %lfn", SPL, pe, pref); // https://zhuanlan.zhihu.com/p/384225760 // SL = 10LOG(10)[ I / I。] // I 离声源中心1m处的声强 // I。参考声强 0.67 int SL = (int)(10.0 * log10(ret / 0.67)); printf("------------mpf_activity_detector_level_calculate() SL: %dn", SL); printf("n"); return ret;}

以下为测试的log info,大家可以有个直观的感受。

------------mpf_activity_detector_level_calculate() I: 285------------mpf_activity_detector_level_calculate() SPL: 144, p(e): 353.965676, p(ref): 0.000020------------mpf_activity_detector_level_calculate() SL: 26------------mpf_activity_detector_level_calculate() I: 3035------------mpf_activity_detector_level_calculate() SPL: 155, p(e): 1155.095970, p(ref): 0.000020------------mpf_activity_detector_level_calculate() SL: 36------------mpf_activity_detector_level_calculate() I: 12894------------mpf_activity_detector_level_calculate() SPL: 161, p(e): 2380.852847, p(ref): 0.000020------------mpf_activity_detector_level_calculate() SL: 42------------mpf_activity_detector_level_calculate() I: 13852------------mpf_activity_detector_level_calculate() SPL: 161, p(e): 2467.714781, p(ref): 0.000020------------mpf_activity_detector_level_calculate() SL: 43------------mpf_activity_detector_level_calculate() I: 17396------------mpf_activity_detector_level_calculate() SPL: 162, p(e): 2765.434780, p(ref): 0.000020------------mpf_activity_detector_level_calculate() SL: 44------------mpf_activity_detector_level_calculate() I: 16933------------mpf_activity_detector_level_calculate() SPL: 162, p(e): 2728.385138, p(ref): 0.000020------------mpf_activity_detector_level_calculate() SL: 44

最后作者使用了SL作为分贝数,但是实际测试过程中,感觉比标准的数值要底15左右。

这个问题可能和麦克风也有关系,后面排计划进行优化的时候,再进行文档更新。

欢迎经验丰富的大佬留言指教,一起学习进步。

参考资料

unimrcp-voice-activity语音检测

WebRTC的VAD 过程解读

声压、声强、声源级、谱级

麦克风声强测量的相位一致性

声学相关基础知识

数字麦克风计算声压级

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。