语音检测
最近公司给我安排了一个新任务,写一个工具可以判断mp3是否有声音
因为业务需求,统一都是mp3格式录音文件
网上找了许多,发现了sound包可以实现,也借鉴了一下大佬
java数字音频最强教程之如何检测一段音频中是否有声音
当运行发现AudioInputStream识别不了mp3格式,会报错
所以去研究了一下,添加了以下代码
//URL url = new URL(path); url地址上的mp3文件
File f = new File(path); //本地路径的mp3文件
AudioInputStream audioStream = AudioSystem.getAudioInputStream(f);
AudioFormat sourceFormat = audioStream.getFormat();
/*
* 因为AudioInputStream不支持mp3格式,需要转换一下format配置
* --> AudioFormat.Encoding.PCM_SIGNED // PCM_UNSIGNED // PCM_FLOAT
*/
AudioFormat mp3tFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
sourceFormat.getSampleRate(), 16, sourceFormat.getChannels(),
sourceFormat.getChannels() * 2, sourceFormat.getSampleRate(), false);
AudioInputStream mp3AudioInputStream = AudioSystem.getAudioInputStream(mp3tFormat, audioStream);
接下来流程都差不多,读取流里面的数据,并根据某些算法来计算声贝这些
看了大佬的算法,也去网上找了其他的算法,都大同小异(看得懂,但是并不知道为什么要这样算)
学习中。。。
这里贴一个另外一种算法
/**
* 计算输入数据段的db值,按公式应该为20*Math.log10(当前振幅值/最大振幅值);
* 位深为16bit,则代表两个字节表示一个音量采集单位;
* 此处用平方和平均值进行计算;
*
* @param data 输入pcm音频数据
* @param bit 位深,8或16
* @return 当前分贝值
*/
public int calculateVolume(byte[] data, int bit) {
int[] newBuffer = null;
int len = data.length;
int index;
//排列
if (bit == 8) {
newBuffer = new int[len];
for (index = 0; index < len; ++index) {
newBuffer[index] = data[index];
}
} else if (bit == 16) {
newBuffer = new int[len / 2];
for (index = 0; index < len / 2; ++index) {
byte byteH= data[index * 2];
byte byteL = data[index * 2 + 1];
newBuffer[index] = bytesToShort(byteH, byteL);
}
}
//平方和求平均值
if (newBuffer != null && newBuffer.length != 0) {
float avg = 0.0F;
for (int i = 0; i < newBuffer.length; ++i) {
avg += (float) (newBuffer[i] * newBuffer[i]);
}
avg /= (float) newBuffer.length;
int db = (int) (10.0D * Math.log10(avg + 1));
return db;
} else {
return 0;
}
}
首次发帖,请多关照!
努力学习中。。。