声级rms

时间:2012-07-18 11:18:31

标签: java audio

我找到了一些计算麦克风声级(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.我还想在图表上绘制声音级别,声级值如何与时间相关?

2 个答案:

答案 0 :(得分:2)

采样率并不重要,但位深度,字节序以及不同方式的通道数量都很重要。

要了解原因,您必须注意到有问题的函数将字节数组作为参数,并分别处理该数组中的每个值。字节数据类型是8位值。如果你想要一些适用于16位值的东西,你需要使用不同的数据类型(短)或从字节转换为。

一旦你这样做,你仍然会得到16位与8位不同的值,因为范围不同:8位从-128到+127,16位从-32768到+32767,但它们都是测量相同的东西,意味着他们将相同的真实单词值缩放到不同的表示值。

关于声级和它们与时间的关系......这取决于你的采样率和进入这个函数的数组的大小。例如,如果您的采样率为8kHz,并且每个缓冲区有2048个样本,那么您的函数将被称为8000/2048或大约每秒3.9次,这意味着您的结果将以该速率(每256毫秒)进行。 / p>

答案 1 :(得分:0)

您始终可以将输入缩放到相同的最小 - 最大范围,以获得不同格式的类似结果。

关于声级w.r.t。时间,除了样本之外,没有任何关系以1 / SampleRate(以Hz为单位)秒间相互分开。