简体   繁体   English

获取WAV文件的帧和样本

[英]Get frames and samples of a wav file

First, I'm trying to do this without any proprietary libraries so that it is more portable, and I get a better/hands-dirty understanding of what's going on here. 首先,我试图在没有任何专有库的情况下执行此操作,以使其具有更高的可移植性,并且我对这里发生的事情有了更好的了解。 I'm ok writing my own classes and libraries to handle repetitive functionality (parsing headers, etc). 我可以编写自己的类和库来处理重复的功能(解析标头等)。

So I'm wondering how one could read a WAV/RIFF file through a stream in order that one can calculate information about said audio file (ie length of the audio in the file, how many samples, how many frames, etc). 因此,我想知道如何通过流读取WAV / RIFF文件,以便可以计算有关所述音频文件的信息(即文件中音频的长度,多少样本,多少帧等)。 and then iterate through those frames or samples for other functionality. 然后遍历那些框架或样本以实现其他功能。

I know it would be reading it in as a binary file through fstream and allowing for the header (and getting some info from the header) as specified in the RIFF specs but how does one discern the bytes to frames or samples, and that to length? 我知道它将通过fstream将其读取为二进制文件,并按照RIFF规范中的说明允许头文件(并从头文件中获取一些信息),但是如何辨别字节到帧或样本以及长度?

I can find issues dealing with this in other languages, but haven't seen anything directly related to it in C++. 我可以在其他语言中找到解决此问题的方法,但是在C ++中没有看到与其直接相关的任何内容。

I believe it is the same to read a WAV file as to read any binary files, such as a bit map. 我相信读取WAV文件和读取任何二进制文件(例如位图)都是一样的。 The basic idea is to read the file's header firstly, and then read the data according to the information shown in the header. 基本思想是先读取文件的标头,然后根据标头中显示的信息读取数据。 The header could typically fill into a C data structure, and you may directly use the information. 标头通常可以填充到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
}

I don't think there is frame in the WAV file, just make sure the length of each sample point, which is wavinfo.bits_per_sample / 8 . 我认为WAV文件中没有框架,只需确保每个采样点的长度为wavinfo.bits_per_sample / 8 If the value is 2, we can read a short as a sample. 如果值为2,我们可以读取一个short示例。

Here is a blog, there is some more sample code, but I guess you still need to have some debug. 是一个博客,还有更多示例代码,但是我想您仍然需要进行一些调试。

The WAV/RIFF header tells you the sampling size (8 bits, 16 bits, etc...); WAV / RIFF标头告诉您采样大小(8位,16位等); it also tells you the endian-ness, and whether each sample should be interpreted as a signed or an unsigned number (for 16 bits+); 它还会告诉您字节顺序,以及每个样本应被解释为带符号还是无符号(16位以上)。 and also the number of channels. 以及频道数

Not sure what else you need. 不知道您还需要什么。 That's pretty much all that's needed to chew through the file. 这几乎是浏览文件所需要的全部。 Reading the cited link, it seems to pretty much answer all your questions. 阅读引用的链接,似乎几乎可以回答所有问题。

This happens to be the same link I used as a reference when throwing together a quick little hack to grab audio from my sound card which I attached to my radio. 碰巧是一个快速的小技巧,可以从我连接到收音机的声卡中获取音频时,将其用作参考。 The aforementioned hack analyzed the audio it on the fly to find the silent spots, then split the audio stream, at the silent spots, into individual files. 前面提到的hack会动态分析音频,以找到无声点,然后将无声点处的音频流拆分为单个文件。 The resulting data passed enough for a .wav file to be acceptable to my .mp3 encoder, producing .mp3 files that I could dump onto my mp3 player, so that I could listen to my favorite radio shows later. 生成的数据通过了足以使.mp3编码器接受的.wav文件,产生了.mp3文件,可以将其转储到mp3播放器中,以便以后可以收听我喜欢的广播节目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM