Last active
August 10, 2022 22:03
-
-
Save tilkinsc/254773a31167d01a8e05a53cbe32ec19 to your computer and use it in GitHub Desktop.
A simpilex wave file parser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "wave.h" | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
// wave.h start | |
typedef struct WaveData { | |
unsigned int channels; | |
unsigned int bps; | |
unsigned int sample_rate; | |
unsigned int sound_size; | |
unsigned char* data; | |
unsigned char* sound_data; | |
} WaveData; | |
WaveData* wave_load(const char* path); | |
void wave_free(void* wd); | |
// wave.h end | |
// loads data stored in wave file into a struct, returns said struct | |
WaveData* wave_load(const char* path) { | |
WaveData* data = 0; | |
unsigned char* buffer = 0; | |
// open and read all file contents | |
FILE* f = 0; | |
if((f = fopen(path, "rb")) == 0) | |
goto exit; | |
fseek(f, 0, SEEK_END); | |
long file_size = ftell(f); | |
fseek(f, 0, SEEK_SET); | |
buffer = malloc(file_size * sizeof(unsigned char)); | |
if(buffer == 0) { | |
puts("Could not allocate memory."); | |
fclose(f); | |
goto exit; | |
} | |
fread(buffer, 1, file_size, f); | |
fclose(f); | |
// ensure the file type is a wave file, identified by RIFF | |
if(memcmp(buffer, "RIFF", 4) != 0) { | |
puts("Invalid file header!"); | |
goto exit; | |
} | |
// pull out different useful data parameters from buffer | |
unsigned int channels = buffer[22] | (buffer[23] << 8); | |
unsigned int sample_rate = buffer[24] | (buffer[25] << 8) | (buffer[26] << 16) | (buffer[27] << 24); | |
unsigned int bps = buffer[34] | (buffer[35] << 8); | |
// skip `useless to us` chunks | |
size_t chunk_offset = 36; | |
while(memcmp(buffer + chunk_offset, "data", 4) != 0) { | |
chunk_offset += 4; | |
chunk_offset += buffer[chunk_offset] | (buffer[chunk_offset+1] << 8) | (buffer[chunk_offset+2] << 16) | (buffer[chunk_offset+3] << 24); | |
chunk_offset += 4; | |
} | |
unsigned char* b_data = &(buffer[chunk_offset+8]); | |
data = malloc(1 * sizeof(WaveData)); | |
if(data == 0) { | |
puts("Could not allocate memory."); | |
goto exit; | |
} | |
data->channels = channels; | |
data->bps = bps; | |
data->sample_rate = sample_rate; | |
data->sound_size = file_size - chunk_offset; | |
data->data = buffer; // this needs to be free'd; it is leaked and cleaned by wave_free() | |
data->sound_data = b_data; | |
return data; | |
exit: | |
free(buffer); | |
free(data); | |
return data; | |
} | |
void wave_free(void* wd) { | |
WaveData* wavedata = (WaveData*) wd; | |
free(wavedata->data); | |
free(wavedata); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment