关于 wav 数据子块

About the wav data sub-chunk

我正在做一个项目,其中我必须使用 C 合并两个 8 位 .wav 文件,但我仍然不知道该怎么做。

我已经阅读了有关 wav 文件的内容,我想从阅读其中一个文件开始。

有一件事我不明白:

假设我有一个 8 位 WAV 音频文件,并且我能够读取(即使我仍在尝试)从 44 字节之后开始的数据,我将在逻辑上得到 0 到 255 之间的数字。

我的问题是:

这些数字是什么意思? 如果我得到 255 或 0,它们是什么意思? 它们是来自 wave 的样本吗?

谁能解释一下?

提前致谢

有关数据块中样本格式的信息,请参阅任何好的 WAVE 指南,例如我发现的这个:http://www.neurophys.wisc.edu/auditory/riff-format.txt

相关摘录:

In a single-channel WAVE file, samples are stored consecutively. For stereo WAVE files, channel 0 represents the left channel, and channel 1 represents the right channel. The speaker position mapping for more than two channels is currently undefined. In multiple-channel WAVE files, samples are interleaved.

Data Format of the Samples

Each sample is contained in an integer i. The size of i is the smallest number of bytes required to contain the specified sample size. The least significant byte is stored first. The bits that represent the sample amplitude are stored in the most significant bits of i, and the remaining bits are set to zero.

For example, if the sample size (recorded in nBitsPerSample) is 12 bits, then each sample is stored in a two-byte integer. The least significant four bits of the first (least significant) byte is set to zero.

The data format and maximum and minimums values for PCM waveform samples of various sizes are as follows:

Sample Size  Data Format Maximum Value  Minimum Value

One to       Unsigned    255 (0xFF)     0
eight bits   integer

Nine or      Signed      Largest        Most negative more bits   
integer i    positive    value of i
             value of i

N.B.: 即使文件的音频分辨率大于 8 位,您也应该将文件读取为 unsigned char 的数组,并按照上述规范手动重构较大的样本。 不要尝试做任何事情,比如直接在原生 C int 数组上读取示例,因为它们的布局和大小是 platform-dependent,因此不应该在任何代码中都依赖。

另请注意,header 不是 保证为 44 字节长:How can I detect whether a WAV file has a 44 or 46-byte header? 您需要读取长度并处理 header 基于此,而不是任何假设。

假设我们不处理文件格式问题,获取 0 到 255 之间的值意味着音频样本是 无符号八位 格式,如您所说.
合并数据的一种方法包括将数据从文件读取到缓冲区、数组 ab,然后按值对它们求和:c[i] = a[i] + b[i]。通过这样做,您必须注意以下事项:

  • 文件的长度可能不相等
  • 对无符号 8 位缓冲区求和,例如您的缓冲区几乎肯定会溢出

这通常使用 for 循环来实现。你首先得到块的大小。您的 for 循环必须以这样一种方式编写,即它既不会读取数组边界,也不会忽略可以读取的内容。为了防止溢出,您可以:

  • 阅读时将数值除以二

  • 读取(转换)为不会溢出的格式,然后规范化合并数据并将其转换回原始格式或所需的任何格式。

对于读取和写入 .wav 格式文件的所有细节,您可以使用一些现有的音频文件库,或编写您自己的例程。不过,处理音频文件格式并不是一件小事。这是关于 .wav format 的参考。

以下是一些值得关注的音频文件 API:

libsndfile
sndlib

希望对您有所帮助。