我找到了一些代码来计算麦克风声级(RMS):
public int calculateRMSLevel(byte[] audioData) {
// audioData might be buffered data read from a data line
long lSum = 0;
for (int i = 0; i < audioData.length; i++) {
lSum = lSum + audioData[i];
}
double dAvg = lSum / audioData.length;
double sumMeanSquare = 0d;
for (int j = 0; j < audioData.length; j++) {
sumMeanSquare = sumMeanSquare + Math.pow(audioData[j] - dAvg, 2d);
}
double averageMeanSquare = sumMeanSquare / audioData.length;
return (int) (Math.pow(averageMeanSquare, 0.5d) + 0.5);
}
但它仅适用于以下音频格式:
private AudioFormat getAudioFormat() {
float sampleRate = 8000.0F;
int sampleSizeInBits = 8;
int channels = 1;
boolean signed = true;
boolean bigEndian = true;
return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed,
bigEndian);
}
如何扩展代码,使其可以与其他位一起工作?如果我将位数更改为16,则在静音时返回50左右的值,而当8位返回1或2时,它返回的值约为50。此外,我想在图表上绘制声级,声级值与时间有何关系?
最佳答案
采样率无关紧要,但是位深度,字节序以及以不同方式确定的通道数都很重要。
要了解原因,您必须简单地注意所讨论的函数将字节数组作为参数并分别处理该数组中的每个值。字节数据类型是8位值。如果要使用16位值,则需要使用其他数据类型(短)或从字节转换为该数据类型。
一旦执行此操作,由于范围不同,您仍将获得16位和8位的不同值:8位从-128到+127,而16位从-32768到+32767,但是它们都测量相同事物,这意味着它们会将相同的实词值缩放为不同的表示值。
至于声级及其与时间的关系。。。这取决于您的采样率和进入此功能的阵列的大小。例如,如果采样率为8kHz,每个缓冲区有2048个采样,那么函数将被称为8000/2048或每秒约3.9次,这意味着结果以该速率(每256毫秒)传入。
关于java - 声级均方根,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11540094/