首页 > 解决方案 > 读取 PCM 音频文件有时会给出错误的样本

问题描述

我有一个16 位、48kHz、1 通道(单声道)PCM音频文件(没有标题,但无论如何它与 WAV 标题相同),我可以使用Audacity等软件正确读取该文件,但是当我尝试以编程方式阅读它(在C++中),一些示例似乎不合适,而在比较 Audacity 值时大多数是正确的。

我读取 PCM 文件的过程如下:

  1. 将PCM的字节数组转换为短数组,通过位移得到可读值(此处字节顺序为little-endian)
for(int i = 0; i < bytesSize - 1; i += 2)
    shortValue[i] = bytes[i] | bytes[i + 1] << 8;

注意bytescharPCM 文件的二进制内容的数组。并且shortValue是一个short数组。

  1. 通过除以short (32767)的最大值将 short 值转换为浮点数组中的振幅级别
for(int i = 0; i < shortsSize ; i++)
    amplitude[i] = static_cast<float>(shortValue[i]) / 32767;

这显然不是最佳代码,我可以在一个循环中完成,但为了解释,我将两个步骤分开。

那么究竟发生了什么,当我试图在我的最后一个数组中找到幅度电平的非常大的变化时,它会向我显示不正确的样本?就像在 Audacity 中一样,请注意波浪是如何完美平滑的,以及指向绿色的样本 276,467是如何比下一个指向红色的样本略低一点,应该在 -0.17 左右。

带有两个样本的正常波的大胆截图

但是,当从我的代码中读取时,我得到了一个完全错误的红色样本值(-0.002),同时仍然得到了一个很好的绿色样本值(大约 -0.17),红色样本之后的样本也是正确的(大约-0.17 以及)。

Visual Studio 调试手表的屏幕截图显示红色样本的幅度值错误

我真的不明白发生了什么以及 Audacity 如何正确读取这些字节,我尝试使用多个 PCM/WAV 文件并得到相同的结果。任何帮助将不胜感激!

标签: c++audiopcmaudacity

解决方案


推荐阅读