Newer
Older
Scratch / mobius / src / drivers / sound / wav.c
/*****************************************************************************
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;
}