获取wav文件的帧和样本

Get frames and samples of a wav file

本文关键字:样本 wav 文件 获取      更新时间:2023-10-16

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

因此,我想知道如何通过流读取WAV/RIFF文件,以便计算有关所述音频文件的信息(即文件中音频的长度、采样数、帧数等)。然后对那些帧或样本进行迭代以获得其他功能。

我知道它会通过fstream将其作为二进制文件读取,并允许RIFF规范中指定的标头(并从标头中获取一些信息),但如何区分字节与帧或样本,以及长度?

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

我相信读取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作为样本。

这里有一个博客,还有更多的示例代码,但我想你仍然需要一些调试。

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

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

这恰好是我在组装一个快速的小黑客从我连接到收音机的声卡中获取音频时用作参考的链接。上述黑客在飞行中分析音频,以找到无声点,然后将无声点的音频流拆分为单独的文件。生成的数据足以让.wav文件被我的.mp3编码器接受,生成.mp3文件,我可以将其转储到mp3播放器上,这样我以后就可以收听我最喜欢的广播节目。