Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Simple experiment with parsing wav-files
#include <stdio.h>
#include <stdlib.h>
#define FormatID 'fmt ' /* chunkID for Format Chunk. NOTE: There is a space at the end of this ID. */
struct GlobalFormat {
unsigned int id;
unsigned int size;
unsigned int type;
};
struct FormatChunk {
short wFormatTag;
unsigned short wChannels;
unsigned long dwSamplesPerSec;
unsigned long dwAvgBytesPerSec;
unsigned short wBlockAlign;
unsigned short wBitsPerSample;
/* Note: there may be additional fields here, depending upon wFormatTag. */
};
int main(int argc, char** argv)
{
if (argc != 2) {
printf("specify file.\n");
return 0;
}
FILE* fh = fopen(argv[1], "r");
struct GlobalFormat format;
fread(&format, sizeof(struct GlobalFormat), 1, fh);
char id[5];
memcpy(&id, &format.id, 4);
id[4] = 0;
int size = format.size;
char type[5];
memcpy(&type, &format.type, 4);
type[4] = 0;
printf("chunkid: %s\n", id);
printf("size: %d\n", format.size);
printf("type: %s\n", type);
printf("\n");
while (!feof(fh)) {
char chunkid[5];
fread(chunkid, sizeof(char), 4, fh);
chunkid[4] = 0;
int i_chunkid = *((int*)chunkid);
printf("chunkid: %s\n", chunkid);
printf("hex: %x\n", i_chunkid);
int chunksize;
fread(&chunksize, sizeof(int), 1, fh);
printf("chunksize: %d\n", chunksize);
long pos;
int done = 0;
double avg = 0;
unsigned short a;
long c;
struct FormatChunk* fmt = (struct FormatChunk*)malloc(sizeof(struct FormatChunk));
switch (i_chunkid) {
case 0x20746d66: // fmt
fread(fmt, sizeof(struct FormatChunk), 1, fh);
printf("formatTag: %d\n", fmt->wFormatTag);
printf("channels: %d\n", fmt->wChannels);
printf("samplesPerSec: %d\n", fmt->dwSamplesPerSec);
printf("dwAvgBytesPerSec: %d\n", fmt->dwAvgBytesPerSec);
printf("wBlockAlign: %d\n", fmt->wBlockAlign);
printf("wBitsPerSample: %d\n", fmt->wBitsPerSample);
break;
case 0x61746164: // data
for (c = 0; c < chunksize; c+=2) {
fread(&a, sizeof(unsigned short), 1, fh);
printf("%d\n", a);
avg += a;
}
avg /= c;
printf("average amplitude: %d\n", avg);
break;
default:
pos = ftell(fh);
if (pos + chunksize >= size) {
done = 1;
}
if (fseek(fh, chunksize, SEEK_CUR) == -1) {
done = 1;
}
}
if (done == 1) {
break;
}
printf("\n");
}
fclose(fh);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment