1

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.

Spade 000
  • 109
  • 1
  • 11
  • For future reader: I tried allocating the struct using malloc to see if the padding is removed, but the problem still persists. – Spade 000 May 20 '20 at 06:30

2 Answers2

0
 fread(&WAV_FILE_0,sizeof(WAV_FILE_0),1,READ_WAV_FILE);

I think the fread function is your problem. If the structure has padding but the data was written without padding , then the data cannot be read as you've done it.

In this case you have to read each element of the struct, for example, using fscanf.

You can see the examples for reading the data from WAV file: Parsing a WAV file in C and Reading and processing WAV file data in C/C++

Other links for reading struct from the file maybe help you:

fread into struct reads data incorrectly

fread() a struct in c

How to fread() structs?

Hitokiri
  • 3,607
  • 1
  • 9
  • 29
  • @Spade000 Sorry, i don’t get your idea. My answer is about fread not malloc function – Hitokiri May 19 '20 at 15:32
  • My bad. My comment should actually be put in my question. – Spade 000 May 20 '20 at 06:29
  • @Spade000 your first problem is `fread` as my answer. If you want to ask about `malloc`, you should create new question, because your question has no code for `malloc` or update the question with the problem of allocation – Hitokiri May 20 '20 at 10:24
0

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);
...
Spade 000
  • 109
  • 1
  • 11