简体   繁体   中英

How to read correct Riff Wav fmt Header data correctly for all wav files

I have a program that reads header information like the number of channels etc, from.wav files that use RIFF wav fmt. I want to make it compatible with any.wav extension file that follows the riff wav fmt. This is the code I have so far.

WaveReader.h:

typedef struct {

    unsigned char   ChunkID[4];
    uint32_t        ChunkSize;
    unsigned char   Format[4];
    unsigned char   SubChunk1ID[4];
    uint32_t        SubChunk1Size;
    uint16_t        AudioFormat;
    uint16_t        NumChannels;
    uint32_t        SampleRate;
    uint32_t        BytesRate;
    uint16_t        BlockAlign;
    uint16_t        BitsPerSample;
    unsigned char   SubChunk2ID[4];
    uint32_t        SubChunk2Size;

} RiffWav;

WaveReader.cpp

RiffWav         Header;
InFile = fopen(m_strFileName, "rb");
uint64_t Header_Size = 44;// sizeof(InFile);
CHAR* HeaderBuffer = new CHAR[Header_Size];
fread(HeaderBuffer, 0x01, Header_Size, InFile);

int NumChannels = Header.NumChannels;
int BitsPerSample = Header.BitsPerSample

The issue I am facing with this code is that it does not always read the correct information for each.wav file on its own and I would have to use the fseek function in order to tailor the fread function to read the correct header data from each specific file.

If I do not use the fseek function the program reads the correct data from most.wav files with the exception of a few.

Is there a way I do not have to use the fseek function in order for this program to be compatible with any RIFF wav fmt files?

Edit: I chose the fseek offset manually by using an online.wav file reader and then I used the visual studio to see how much offset the header data was.

In context, the number of channels for one of the files was 2 according to the online.wav file reader and this program had the number of channels as 5200 and the BitsPerSample equal to 2. So after using fseek(InFile, 12, SEEK_SET) the header data read was correct.

The provided example code seems to assume that fmt is always the first sub chunk. According to RIFF specification the fmt sub chunk needs to be before data sub chunk. However, there seems to be no restriction to placing other sub chunks before fmt .

In order to conform to the specification, the code would need to implement support for parsing arbitrary sub blocks, skip any blocks it does not understand, and process the relevant sub blocks after the parser has discovered their locations.

As a quick fix the code could be modified to check that SubChunk1ID equals fmt , and return an "Unsupported sub chunk order" error when the first sub chunk is something else. That would make the error visible and make it possible to gather statistics to gain understanding about the magnitude of the issue.

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