最近在做语音识别功能,在用户录音的时间要有个动画标识录音的音量
参考了
http://blog.youkuaiyun.com/greatpresident/article/details/38402147
发现每台手机得出的结果不一至,而且得到的音量结果的梯度不明显。
继续度娘后找到更好的解决方案
http://ikinglai.blog.51cto.com/6220785/1256781/
录音的编码主要有两种:8位pcm和16位pcm。8位pcm用一个字节表示语音的一个点,16位pcm用两个字节,也就是一个short来表示语音的一个点。需要特别注意的是,如果你用的16位pcm编码,而取录音数据用的是byte的话,需要自己将两个bye转换成一个short。将两个byte转换成一个short,有小端和大端两种,一般默认情况都是小端,但是有的开源库,比如lamemp3需要的就是大端,这个要根据不同的情况进行不同的处理。
下面以Android为例,介绍一下用平均值计算音量的方法。
private double calculateVolume(short[] buffer){
double sumVolume = 0.0;
double avgVolume = 0.0;
double volume = 0.0;
for(short b : buffer){
sumVolume += Math.abs(b);
}
avgVolume = sumVolume / buffer.length;
volume = Math.log10(1 + avgVolume) * 10;
return volume;
}
还有一个特别需要注意的问题是:如果你录音的编码是16为pcm,而录音数据数据是byte,需要将两个byte转为一个short进行处理,建议用小端的方式。
private doublecalculateVolume(byte[]
buffer){
double sumVolume = 0.0;
double avgVolume = 0.0;
double volume = 0.0;
for(int i = 0; i < buffer.length;
i+=2){
int v1 = buffer[i] & 0xFF;
int v2 = buffer[i + 1] & 0xFF;
int temp = v1 + (v2 << 8);//
小端
if (temp >= 0x8000) {
temp = 0xffff - temp;
}
sumVolume += Math.abs(temp);
}
avgVolume = sumVolume / buffer.length / 2;
volume = Math.log10(1 + avgVolume) * 10;
return volume;
}