Reputation: 164
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.
Upvotes: 1
Views: 1220
Reputation: 973
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.
Upvotes: 0