java - 读入 WAV 文件并计算 RMS

标签 java audio wav volume pcm

所以我正在尝试测试一些分析某些 PCM 数据量的代码。我得到了一些奇怪的体积测量值,这些测量值与我从 audacity 获得的数据没有任何意义。看来我的测量结果到处都是。

我不确定我的错误是否在于我读取 WAV 数据的方式,或者是否在于我计算音量的方式。

因此,这里是我以字节形式读取数据并转换为 Shorts 的地方,因为它是 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;

然后,短 [] 会直接传递到我的分析器,然后我将数据分割成 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 数据错误。我通过添加结束小字节序来修复它。但是我仍然对如何计算体积感到困惑。这些值更好,但仍然难以解读,我不确定我的 RMS 的单位以及引用值的单位。

最佳答案

您的计算中有错误 - sumOfSamples = originalPcm[i]*originalPcm[i]; 应为 sumOfSamples += originalPcm[i]*originalPcm[i]; code>,这样您就可以累积这些值。
至于引用值——为什么用20?通常您使用尽可能低的值(在本例中为 1),或者您可以使用最大值(即 sqrt(32768)),并且您的所有值都将低于该值,因此您将得到负 dB 值.

关于java - 读入 WAV 文件并计算 RMS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55305330/

相关文章:

java - 在尝试一些 ProGuard 规则后,使用 ProGuard 会导致构建失败或强制关闭并显示空 UI

c++ - 双簧管异步音频提取

javascript - Mediaelement.js 简单音频播放列表皮肤

java - 如何在两个 Weblogic 域之间进行通信?

java - 运行默认 Gluon 项目后出错(: dex FAILED)

java - 如何获取覆盖 hashCode() 的对象的唯一 ID?

audio - NAudio-WaveOut与WaveOffsetStream一起使用时不会引发PlaybackStopped事件

c++ - SDL_mixer WAVE 音频格式质量差

java - 使用 TARSOS DSP 从 WavFiles JAVA 中提取 MFCC 的困难

audio - .wav文件全部为1's or -1'会发生什么?