计算音频db spl level

时间:2017-10-07 15:32:12

标签: java audio

我正在尝试在java中编写一个简单的db SPL计量器,试图理解一些关于如何计算它的理论,现在得到这个代码。

import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.TargetDataLine;

public class Sound {
public static void main(String[] args) throws LineUnavailableException, InterruptedException, IOException {

    AudioFormat audioFormat = new AudioFormat(44100f, 16, 1, true, true);
    DataLine.Info info = new DataLine.Info(TargetDataLine.class, audioFormat);
    if (!AudioSystem.isLineSupported(info)) {
        System.err.println("Line is not supperted");
        return;
    }
    TargetDataLine targetDataLine = AudioSystem.getTargetDataLine(audioFormat);
    int bufferSize = targetDataLine.getBufferSize() / 5;
    targetDataLine.open(audioFormat, bufferSize);
    targetDataLine.start();

    AudioInputStream audioInputStream = new AudioInputStream(targetDataLine);
    byte[] buffer = new byte[bufferSize];
    for (int blen; (blen = audioInputStream.read(buffer, 0, buffer.length)) > -1;) {


        float[] samples = new float[buffer.length / 2];
        for (int i = 0, s = 0; i < blen;) {
            samples[s++] = (buffer[i++] << 8 | buffer[i++] & 0xFF) / 32768f;
        }

        double rms = 0;
        for(float sample : samples) {
            rms += Math.pow(sample,2);
        }
        rms = (double) Math.sqrt(rms/samples.length);

        double db = 20.0 * Math.log10(rms);

        System.out.println("rms:" + rms + " => db: " + db);
    }
    audioInputStream.close();
    targetDataLine.stop();
    targetDataLine.close();
}
}

但我得到了奇怪的负面价值观:

rms:0.022453707817984867 => db: -32.97423865942349
rms:0.03231030831709747 => db: -29.81317795523038
rms:0.022200493154558538 => db: -33.07274756330733
rms:0.03482430806204803 => db: -29.162350079742442
rms:0.044505461273788495 => db: -27.03173386777801
rms:0.11487023115936983 => db: -18.795850099565726
rms:0.09914386060902665 => db: -20.07468347812454
rms:0.10989161780818954 => db: -19.180708658988408
rms:0.13056592937751932 => db: -17.683402711408206
rms:0.12638495853786622 => db: -17.96609219396998
rms:0.14194418861687289 => db: -16.957647667311765
rms:0.13712612622742246 => db: -17.257595850171978

在麦克风的相同位置使用外部应用程序(在ios上免费使用db meter),我得到的正面感觉值大约为6-10分贝。

我如何才能正确计算此值,以至少接近或相同的应用程序值?我做错了什么?

1 个答案:

答案 0 :(得分:0)

尝试:

float db = 20.0 * Math.log10(rms);

PCM(音频)数据以32位Float处理,而不是64位Double类型。