1

首先,我试图在没有任何专有库的情况下做到这一点,以便它更便携,并且我对这里发生的事情有了更好的/不熟悉的理解。我可以编写自己的类和库来处理重复的功能(解析标头等)。

所以我想知道如何通过流读取WAV/RIFF文件,以便计算有关所述音频文件的信息(即文件中音频的长度、多少样本、多少帧等)。然后遍历这些帧或样本以获取其他功能。

我知道它将以二进制文件的形式读取它,并允许RIFF 规范fstream中指定的标头(并从标头中获取一些信息),但是如何识别字节到帧或样本,以及长度?

我可以在其他语言中找到处理此问题的问题,但在 C++ 中没有看到与它直接相关的任何内容。

4

2 回答 2

2

我相信读取 WAV 文件与读取任何二进制文件(例如位图)是一样的。基本思路是先读取文件头,然后根据头中显示的信息读取数据。标头通常可以填充到 C 数据结构中,您可以直接使用该信息。

struct wavfile
{
    char   id[4];            // should always contain "RIFF"
    int    totallength;      // total file length minus 8
    char   wavefmt[8];       // should be "WAVEfmt "
    int    format;           // 16 for PCM format
    short  pcm;              // 1 for PCM format
    short  channels;         // channels
    int    frequency;        // sampling frequency
    int    bytes_per_second;
    short  bytes_by_capture;
    short  bits_per_sample;
    char   data[4];          // should always contain "data"
    int    bytes_in_data;
};

FILE * fp = fopen("file.wav", "rb");
wavfile info;
if (fp) {
    fread(&info, 1, sizeof(wavfile), fp);
    // try to read data here
}

我认为WAV文件中没有框架,只需确保每个采样点的长度,即wavinfo.bits_per_sample / 8. 如果值为 2,我们可以读取 ashort作为样本。

是一个博客,还有一些示例代码,但我想您仍然需要进行一些调试。

于 2014-09-03T01:09:03.203 回答
0

WAV/RIFF 标头告诉您采样大小(8 位、16 位等...);它还告诉您字节序,以及每个样本是否应被解释为有符号数或无符号数(对于 16 位以上);还有频道的数量。

不知道你还需要什么。这几乎就是浏览文件所需的全部内容。阅读引用的链接,它似乎几乎回答了你所有的问题。

这恰好是我用作参考的相同链接,当我拼凑一个快速的小技巧以从我连接到我的收音机的声卡中获取音频时。前面提到的黑客会动态分析音频以找到静音点,然后在静音点将音频流拆分为单独的文件。生成的数据足以让 .wav 文件被我的 .mp3 编码器接受,生成 .mp3 文件,我可以将这些文件转储到我的 mp3 播放器上,这样我以后就可以收听我最喜欢的广播节目了。

于 2014-09-03T00:35:11.460 回答