Search code examples
cstructwav

Reading binary file and storing it to struct in c


I'm trying to create a software that stores the metadata of a wav file.

Here's an MWE:


#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>

FILE   *  READ_WAV_FILE;

struct WAV_FILE_HEADER{
   char      ChunkID[4];     // RIFF
   uint32_t  ChunkSize;
   char      Format[4];      // WAVE
   char      Subchunk1ID[4]; // fmt
   uint32_t  Subchunk1Size;
   uint16_t  AudioFormat;
   uint16_t  NumChannels;
   uint32_t  SampleRate;
   uint32_t  ByteRate;
   uint16_t  BlockAlign;
   uint16_t  BitsPerSample;
};

struct WAV_FILE_HEADER WAV_FILE_0;

void print_wav_struct(){
   printf("ChunkID:      %s\n", WAV_FILE_0.ChunkID);
   printf("ChunkSize     %u\n", WAV_FILE_0.ChunkSize);
   printf("Format        %s\n", WAV_FILE_0.Format);
   printf("Subchunk1ID   %s\n", WAV_FILE_0.Subchunk1ID);
   printf("Subchunk1Size %u\n", WAV_FILE_0.Subchunk1Size);
   printf("AudioFormat   %hu\n", WAV_FILE_0.AudioFormat);
   printf("NumChannels   %hu\n", WAV_FILE_0.NumChannels);
   printf("SampleRate    %u\n", WAV_FILE_0.SampleRate);
   printf("ByteRate      %u\n", WAV_FILE_0.ByteRate);
   printf("BlockAlign    %hu\n", WAV_FILE_0.BlockAlign);
   printf("BitsPerSample %hu\n", WAV_FILE_0.BitsPerSample);

}

int read_wavfile(){

   READ_WAV_FILE = fopen("read.wav", "rb");
   fseek(READ_WAV_FILE,0,SEEK_SET);
   fread(&WAV_FILE_0,sizeof(WAV_FILE_0),1,READ_WAV_FILE);
   fclose(READ_WAV_FILE);
   return 0;
}
int main(){

   if (read_wavfile()){
      printf("Something went wrong\n");
      return -1;
   }
   print_wav_struct();
   return 0;

}

The problem here is the output of "ChunkID", "Format" and "Subchunk1ID":

ChunkID:      RIFFF
ChunkSize     48824390
Format        WAVEfmt
Subchunk1ID   fmt
Subchunk1Size 16
AudioFormat   1
NumChannels   2
SampleRate    48000
ByteRate      192000
BlockAlign    4
BitsPerSample 16

Only those string are affected in this problem. The integers were not.

The "ChunkID" should've been only "RIFF", the "Format" should've been only "WAVE" and "Subchunk1ID" should've been "fmt ".

What I went wrong reading the file?

PS Sorry for the ridiculous long code, but that's the only way I find that's minimal.


Solution

  • After three hours of research, I finally concluded that the problem was it's missing a NUL terminator. Using printf with a non-null terminated string

    This solved my problem:

    ...
    printf("ChunkID:    %.*s\n",4,WAV_HEADER.ChunkID);
    printf("ChunkSize:  %u\n",WAV_HEADER.ChunkSize);
    printf("Format:     %.*s\n",4,WAV_HEADER.Format);
    ...