【问题标题】:About the wav data sub-chunk关于 wav 数据子块
【发布时间】:2016-11-06 03:11:40
【问题描述】:

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

我已阅读有关 wav 文件的信息,我想从阅读其中一个文件开始。

有一件事我不明白:

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

我的问题是:

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

谁能解释一下?

提前致谢

【问题讨论】:

  • 任何 WAV 格式的基本指南都会解释这一点。您是否遇到过与编程相关的问题?
  • 是的,我也需要编程指导..
  • 如果你不理解格式,你怎么能围绕它编写任何有用的东西?

标签: c audio wav


【解决方案1】:

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

相关摘录:

在单通道 WAVE 文件中,样本是连续存储的。为了 立体声 WAVE 文件,通道 0 代表左通道,通道 1 代表右声道。扬声器位置映射更多 目前未定义多于两个通道。在多通道 WAVE 文件,样本是交错的。

样本的数据格式

每个样本都包含在一个整数 i 中。 i 的大小是 包含指定样本所需的最小字节数 尺寸。首先存储最低有效字节。那些位 表示样本幅度存储在最高有效位 i,其余位设置为零。

例如,如果样本大小(记录在 nBitsPerSample 中)为 12 位,然后每个样本都存储在一个两字节整数中。至少 第一个(最低有效)字节的有效四位设置为 零。

PCM波形的数据格式和最大值最小值 各种尺寸的样品如下:

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

注意:即使文件的音频分辨率 >8 位,您也应该将文件读取为 unsigned char 的数组,并按照上述规范手动重构较大的样本。 不要尝试直接通过原生 C ints 数组读取示例,因为它们的布局和大小取决于平台,因此不应在任何代码中依赖它们。

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

【讨论】:

    【解决方案2】:

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

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

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

    • 读数时除以二

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

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

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

    libsndfile
    sndlib

    希望这能有所帮助。

    【讨论】:

    • "获取 0 到 255 之间的值意味着音频样本是无符号八位格式。" OP 已经表示他们正在使用 8 位文件进行测试。但是如果读入unsigned char 的数组,any 文件也是如此。 (这比普通的char 更可取,因为后者是实现定义的。)这并不一定意味着数据实际上是 8 位的。必须在标题中检查格式,并使用生成的知识来重构样本。
    • 我从来没有对文件数据格式做过任何假设。解释如何编写通用 API 来读取和处理音频文件将超出回答任何 SO 兼容问题的范围。有或多或少复杂的开源 API 可以将任何文件数据格式转换为目标数据格式,但我不相信这就是 OP 的全部意义所在。我相信这只是处理最简单的情况,@underscore_d。不过,感谢您的意见。 (-:
    • 我不知道你为什么认为我在谈论“通用 API”或任何东西。我只是抢先一步,OP 可能想要处理 16 位 WAV 文件。然后他们仍然会在数据中看到 8 位字节,但这些字节在重组为 16 位样本之前没有用。这样做并不太难。这就是我的意思。不客气!
    • @HanounFouad 你需要告诉你的编译器/IDE将你安装sndfile.h的目录添加到它在你的项目中遇到#include语句时搜索的目录列表中,所以它将是能够在那里找到文件。每当#includeing 一个新文件位于当前目录之外的其他位置时,您都需要这样做。请查阅您的开发环境的基本文档以了解如何执行此操作和其他常规任务。
    • 您需要发布一个新问题,指定您的编译器/IDE、项目结构以及尝试编译时使用的所有命令行/设置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    相关资源
    最近更新 更多