/*****************************************************************************
common routines for .WAV files
.WAV sub-formats:
1=linear PCM
2=Microsoft ADPCM
6=A-law (ITU-T G.711, formerly CCITT G.711)
7=u-law (ITU-T G.711, formerly CCITT G.711)
34=True Speech
49=GSM
85=MP3
.WAV chunks
"fmt "
"data" xxx - this code does not handle multiple "data" chunks
"fact" xxx - this code does not skip more than one "fact" chunk
*****************************************************************************/
#include <string.h> /* memcmp() */
#include "sound.h"
/*****************************************************************************
*****************************************************************************/
int wav_validate(sound_info_t *info, unsigned sub_type)
{
unsigned char buffer[WAV_FMT_SIZE];
char *data;
long temp;
fseek(info->infile, 0, SEEK_SET);
/* is it a .WAV file? */
if(fread(buffer, 1, 12, info->infile) != 12)
return -1;
if(memcmp(buffer, "RIFF", 4) || memcmp(buffer + 8, "WAVE", 4))
return -1;
/* skip to 'fmt ' section */
do
{
if(fread(buffer, 1, 4, info->infile) != 4)
return -1;
} while (memcmp(buffer, "fmt ", 4) != 0);
/* read info from 'fmt ' section */
if(fread(buffer, 1, WAV_FMT_SIZE, info->infile) != WAV_FMT_SIZE)
return -1;
/* 1=linear PCM, 2=ADPCM, 85=MP3, etc. */
if (read_le16(buffer + WAV_FMT_FMT) != sub_type)
return -1; /* not the subtype we want */
info->channels = read_le16(buffer + WAV_FMT_CHAN);
info->depth = read_le16(buffer + WAV_FMT_DEPTH);
info->rate = read_le32(buffer + WAV_FMT_RATE);
/* skip rest of 'fmt ' section */
for(temp = read_le32(buffer) - (WAV_FMT_SIZE - 4); temp != 0; temp--)
{
if(fgetc(info->infile) == EOF)
return -1;
}
/* skip to 'data' section. This also skips the useless 'fact' sections. */
for(data = "data"; *data != '\0'; )
{
temp = fgetc(info->infile);
if(temp == EOF)
return -1;
if(temp == *data)
data++;
}
/* get length of data.
We do NOT handle .WAV files with multiple 'data' sections. */
if(fread(buffer, 1, 4, info->infile) != 4)
return -1;
info->bytes_left = read_le32(buffer);
/* valid .WAV file */
return 0;
}