It's easy just comply with the WAVE file format, based on that, you can extract the data byte by byte and interpret it. So once you have the correct path of the file you can do something like this: This is a piece of code of my wav file reader in Android (not complete but has the main parts that read the pcm data out of wav file along with it's descriptors)
typedef struct wav_file {
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 byteRate;
uint16_t blockAlign;
uint16_t bitsPerSample;
unsigned char subchunk2Id[4];
uint32_t subchunk2Size;
unsigned char * data;
} WavFile;
void swap_endian16(uint16_t val) {
val = (val<<8) | (val>>8);
}
void swap_endian32(uint32_t val) {
val = (val<<24) | ((val<<8) & 0x00ff0000) |
((val>>8) & 0x0000ff00) | (val>>24);
}
WavError loadWavFile(char filePath[], WavFile * wavFile) {
WavError rc = NO_ERROR;
FILE *fp = fopen(filePath,"rb");
printf("wavreader file Path = %s from %s", (fp ? "file opened" : "failed to open file"), filePath);
if(!fp) {
rc = CANNOT_OPEN_FILE_ERROR;
goto out1;
}
//chunkId
size_t len = fread(wavFile->chunkId, sizeof(unsigned char), 4, fp);
wavFile->chunkId[len] = '\0';
printf("wavreader len:%d chunkId: %s", (int) len , wavFile->chunkId);
if (strcmp((const char *) wavFile->chunkId, "RIFF")) {
rc = NOT_WAV_FILE_ERROR;
goto out1;
}
//chunkSize
fread(&wavFile->chunkSize, sizeof(uint32_t), 1, fp);
swap_endian32(wavFile->chunkSize);
printf("wavreader chunkSize: %d", wavFile->chunkSize);
//format
len = fread(wavFile->format, sizeof(unsigned char), 4, fp);
wavFile->format[len] = '\0';
printf("wavreader format: %s", wavFile->format);
if (strcmp((const char *)wavFile->format,"WAVE")) {
rc = FMT_ERROR;
goto out1;
}
//subchunk1Id
len = fread(wavFile->subchunk1Id, sizeof(unsigned char), 4, fp);
wavFile->subchunk1Id[len] = '\0';
printf("wavreader subchunk1Id: %s", wavFile->subchunk1Id);
if (strcmp((const char *)wavFile->subchunk1Id,"fmt ")) {
rc = FMT_ID_ERROR;
goto out1;
}
//subchunk1Size
fread(&wavFile->subchunk1Size, sizeof(uint32_t), 1, fp);
swap_endian32(wavFile->subchunk1Size);
printf("wavreader subchunk1Size: %d", wavFile->subchunk1Size);
//audioFormat
fread(&wavFile->audioFormat, sizeof(uint16_t), 1, fp);
swap_endian16(wavFile->audioFormat);
printf("wavreader audioFormat: %d", wavFile->audioFormat);
//numChannels
fread(&wavFile->numChannels, sizeof(uint16_t), 1, fp);
swap_endian16(wavFile->numChannels);
printf("wavreader numChannels: %d", wavFile->numChannels);
//sampleRate
fread(&wavFile->sampleRate, sizeof(uint32_t), 1, fp);
swap_endian32(wavFile->sampleRate);
printf("wavreader sampleRate: %d", wavFile->sampleRate);
//byteRate
fread(&wavFile->byteRate, sizeof(uint32_t), 1, fp);
swap_endian32(wavFile->byteRate);
printf("wavreader byteRate: %d", wavFile->byteRate);
//blockAlign
fread(&wavFile->blockAlign, sizeof(uint16_t), 1, fp);
swap_endian16(wavFile->blockAlign);
printf("wavreader blockAlign: %d", wavFile->blockAlign);
//bitsPerSample
fread(&wavFile->bitsPerSample, sizeof(uint16_t), 1, fp);
swap_endian16(wavFile->bitsPerSample);
printf("wavreader bitsPerSample: %d", wavFile->bitsPerSample);
//subchunk2Id
fread(wavFile->subchunk2Id, sizeof(unsigned char), 4, fp);
wavFile->subchunk2Id[len] = '\0';
printf("wavreader subchunk2Id: %s", wavFile->subchunk2Id);
fread(&wavFile->subchunk2Size, sizeof(uint32_t), 1, fp);
swap_endian32(wavFile->subchunk2Size);
printf("wavreader subchunk2Size: %d", wavFile->subchunk2Size);
wavFile->data = (unsigned char *) malloc (sizeof(unsigned char) * wavFile->subchunk2Size); //set aside sound buffer space
fread(wavFile->data, sizeof(unsigned char), wavFile->subchunk2Size, fp); //read in our whole sound data chunk
fclose(fp);
out1:
return rc;
}
in wavFile->data you get the actual pcm data from the file.
PS: you should use this link as reference