很多场合我们需要动态显示实时语音的音量分贝,以展示人的说话声音的大小,以便可以动态条件声音的大小,比较常见的几种音量分贝检测算法有如下几种, 下面做一下简单说明和比较
1、计算音频能量数据和
算法原理:
算法比较简单,首先我们分别累加每个采样点的数值,除以采样个数,得到声音数据求平均能量值。然后再将其做0--32767之间的等比量化。得到1-100的量化值,返回结果。
通过实际测试,通常情况下,人声一般都分布在较低的能量范围内,人说话的声音基本在0-35之间,很难达到50以上,这样就会使量化后的音量数据大致分布在1-35这个区域之间,不能够很敏感的感知音频数据的音量变化。
改进方式:
可以得到的音频分贝数据等比放大3倍,然后再做溢出处理即可,这样算法基本可用,但是实际效果也不是很理想。
2、计算均方根求分贝值
算法原理:
在数据统计分析中,将所有值平方求和,求其均值,再开平方,就得到均方根值。在物理学中,我们常用均方根值来分析噪声、音量分贝。这也是一个标准算法,但是实际测试中,一样效果差强人意。
3、均方根算法改进
以上几种算法在实际测试应用中,效果都不是很理想,只是理论上可行,所以我针对这些算法做了一些优化和改进,可以针对PCM音频数据完成音量值的检测,测试效果比较准确,并量化到0--100能量数据值,欢迎大家测试;
下面是一段音频文件:
这个是上面文件对应输出的音频能量值,应该说还是比较准确的。
测试代码:
int main(int argc, char* argv[])
{
FILE *input_fd = NULL, *output_fd = NULL;
short* pshInBuff = NULL;
int iEnergy = 0, iRet = 0;
//input_fd = fopen(argv[1], "rb");
input_fd = fopen("input_8k.pcm", "rb");
output_fd = fopen("result.txt", "wb");
if(input_fd == NULL)
{
printf("Error:can not open audio input file %s.\n", argv[2]);
return (-1);
};
pshInBuff = (short*)malloc(sizeof(short)*DEFAULT_SAMPLE_FRAME_LEN);
if(pshInBuff == NULL)
{
printf("Error\n");
return (-1);
}
while (!feof(input_fd))
{
if((iRet = fread(pshInBuff, sizeof(short), DEFAULT_SAMPLE_FRAME_LEN, input_fd))!= DEFAULT_SAMPLE_FRAME_LEN)
{
printf("while Exit and file over.\n ");
break;
}
iEnergy = uniqueVolDetection(pshInBuff, 320);
printf("Voice Energy %d\n", iEnergy);
fprintf(output_fd, "%02d ", iEnergy);
if (iEnergy > 70)
{
printf("Voice Energy Too High! \n");
}
}
fclose(input_fd);
fclose(output_fd);
if (pshInBuff)
{
free(pshInBuff);
}
getchar();
return 0;
}
项目地址:https://download.csdn.net/download/unique_no1/85034214
里面包含测试程序和可执行文件,windows平台和linux平台的我都已经编译好了,大家可以测试看下效果,如果技术合作、交流的也非常欢迎。
联系方式:
tel:18108010758
vx:unique_no_1