获取wav文件的帧和样本

时间:2014-09-03 00:24:47

标签: c++ audio wav riff

首先,我试图在没有任何专有库的情况下执行此操作,以便它更具可移植性,并且我对这里发生的事情有了更好/更好的理解。我可以编写自己的类和库来处理重复的功能(解析标题等)。

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

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

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

2 个答案:

答案 0 :(得分: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,我们可以读取short作为样本。

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

答案 1 :(得分:0)

WAV / RIFF标头告诉您采样大小(8位,16位等);它还告诉你endian-ness,以及每个样本是否应该被解释为有符号或无符号数(对于16位+);以及频道数量。

不确定您还需要什么。这几乎是咀嚼文件所需的全部内容。阅读引用的链接,似乎几乎可以回答所有问题。

这恰好是我用作参考的链接,当我把一个快速的小黑客一起从我的收音机连接的声卡中抓取音频时。前面提到的黑客在飞行中分析它的音频以找到无声点,然后在无声点将音频流分成单独的文件。结果数据足以使.wav文件被我的.mp3编码器接受,生成.mp3文件,我可以将其转储到我的mp3播放器上,以便我可以稍后收听我最喜欢的电台节目。