c++ - 读取 PCM 音频文件有时会给出错误的样本
问题描述
我有一个16 位、48kHz、1 通道(单声道)PCM音频文件(没有标题,但无论如何它与 WAV 标题相同),我可以使用Audacity等软件正确读取该文件,但是当我尝试以编程方式阅读它(在C++中),一些示例似乎不合适,而在比较 Audacity 值时大多数是正确的。
我读取 PCM 文件的过程如下:
- 将PCM的字节数组转换为短数组,通过位移得到可读值(此处字节顺序为little-endian)。
for(int i = 0; i < bytesSize - 1; i += 2)
shortValue[i] = bytes[i] | bytes[i + 1] << 8;
注意:bytes
是char
PCM 文件的二进制内容的数组。并且shortValue
是一个short
数组。
- 通过除以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 以及)。
我真的不明白发生了什么以及 Audacity 如何正确读取这些字节,我尝试使用多个 PCM/WAV 文件并得到相同的结果。任何帮助将不胜感激!
解决方案
推荐阅读
- haskell - 在 Haskell 中,为什么即使启用了 AllowAmbiguousTypes,类型也会模棱两可?
- broadcastreceiver - 如何在 Android Oreo 及更高版本中在后台运行警报
- python - 反向移植不适用于 Python 3.6.3,但适用于 2.7.8
- python - 读取 CSV 文件和打印每个用户的日期列表的代码
- android - 如何在 YoutubePlayerView android 中启用右键单击事件和左键单击事件
- svelte - 将 Svelte 生成的节点注入静态 DOM
- javascript - 如何从名为 George 的对象中获取价值
- python - 为什么我的正则表达式有一个奇怪的行为?这是一个错误吗?
- python - 在分页的情况下,用于fundtion的烧瓶网址不起作用
- linux-kernel - 如何在 ubuntu 上为 qemu 和 kvm 设置 Beaglebone black?