简体   繁体   中英

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). 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?

I can find issues dealing with this in other languages, but haven't seen anything directly related to it in C++.

I believe it is the same to read a WAV file as to read any binary files, such as a bit map. 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.

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 . If the value is 2, we can read a short as a sample.

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...); it also tells you the endian-ness, and whether each sample should be interpreted as a signed or an unsigned number (for 16 bits+); 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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