读取WAV文件并计算RMS

问题描述 投票:0回答:1

所以我试图测试一些分析一些PCM数据量的代码。我得到了一些奇怪的音量测量,这些测量对于我从大胆中获得的数据没有意义。似乎我的测量结果到处都是。

我不确定我的错误是否与我正在阅读WAV数据的方式有关,或者它是否与我计算音量的方式不同。

所以这里我将数据读入字节并转换为短路,因为它是PCM 16位。

        InputStream pcmStream = this.getClass().getClassLoader().getResourceAsStream("Test-16Bit-PCM.wav");
        ArrayList<Byte> bytes = new ArrayList<>();
        int b = pcmStream.read();
        while(b != -1)
        {
            bytes.add((byte)b);
            b = pcmStream.read();
       }

       // First 44 bytes of WAV file are file info, we already know PCM properties since we recorded test audio
        byte [] bytesArray = new byte[bytes.size()-44];
        for(int i = 44; i < bytes.size(); i++)
        {
            bytesArray[i-44] = bytes.get(i);
        }
        bytes = null;
        pcmStream = null;
        short [] pcm = new short[bytesArray.length/2];
        ByteBuffer bb = ByteBuffer.wrap(bytesArray).asShortBuffer().get(pcm);
        bb.order(ByteOrder.LITTLE_ENDIAN);
        bb.asShortBuffer().get(pcm);
        bytesArray = null;

然后将short []直接传递给我的分析仪,然后将数据分成0.1秒的时间步长,并在每个时间步长上平均音量。

这是我计算RMS和dB的地方

        double sumOfSamples = 0;
        double numOfSamples = settings.shortsPerTimeStep();
        for(int i = start; i < start+settings.shortsPerTimeStep(); i++)
        {
           sumOfSamples = originalPcm[i]*originalPcm[i];
        }
        double rms = Math.sqrt(sumOfSamples/numOfSamples);
        // Convert to decibels
        calculatedVolume = 20*Math.log10(rms/20);

我正在读取的音频以44100 MONO录制,并以大胆保存为WAV 16 Signed PCM。不确定我做错了什么。

任何帮助将不胜感激!谢谢

编辑:发现我正在阅读错误的WAV数据。我通过添加end endianess来修复它。但是我仍然对如何计算音量感到困惑。值更好但仍难以破译,我不确定我的RMS所在的单位和参考值应该在的单位。

java audio wav volume pcm
1个回答
1
投票

你的计算中有一个错误 - sumOfSamples = originalPcm[i]*originalPcm[i];应该由sumOfSamples += originalPcm[i]*originalPcm[i];,所以你将积累这些值。 至于参考值 - 你为什么用20?通常使用最低可能值(在这种情况下为1),或者您可以使用最大值(即sqrt(32768)),并且您的所有值都将低于该值,因此您将获得负dB值。

© www.soinside.com 2019 - 2024. All rights reserved.