src/audio/SDL_wave.c
author Sam Lantinga
Tue, 24 Jan 2006 07:20:18 +0000
changeset 1260 80f8c94b5199
parent 769 b8d311d90021
child 1312 c9b51268668f
permissions -rw-r--r--
Date: 10 Jun 2003 15:30:59 -0400
From: Mike Shal
Subject: [SDL] Bug in SDL_wave.c?

Hey everyone, I'm not sure if this is a bug in SDL, or if I just have
incorrect WAV files. The problem I'm having is loading multiple
concatenated WAVs from SDL_LoadWAV_RW. Some WAV files put comments at
the end of the file (which may be bad form), and SDL doesn't skip past
them when reading from the RWops. So the next WAV I try to load will
start at the comment section of the previous WAV, which obviously
doesn't work. If anyone else is having this problem, one quick fix you
can do is run sox on the bad WAVs, which strips out all of the comment
sections.
Eg:

$ sox sound.wav tmp.wav
$ mv -f tmp.wav sound.wav

The other fix is to patch SDL_wave.c, which is included with this email.
(Assuming I made the patch correctly :). All it does is calculate how
much remaining space there is in the WAV file after the data chunk, and
does SDL_RWseek to skip it. I don't think it should interfere with
anything else, but if someone could check it that would be nice :). If
the bug is really with SDL and not with my WAVs, can someone work this
into the next version of SDL? Thanks,

-Mike Shal
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2004 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 #ifdef SAVE_RCSID
    24 static char rcsid =
    25  "@(#) $Id$";
    26 #endif
    27 
    28 #ifndef DISABLE_FILE
    29 
    30 /* Microsoft WAVE file loading routines */
    31 
    32 #include <stdlib.h>
    33 #include <string.h>
    34 
    35 #include "SDL_error.h"
    36 #include "SDL_audio.h"
    37 #include "SDL_wave.h"
    38 #include "SDL_endian.h"
    39 
    40 #ifndef NELEMS
    41 #define NELEMS(array)	((sizeof array)/(sizeof array[0]))
    42 #endif
    43 
    44 static int ReadChunk(SDL_RWops *src, Chunk *chunk);
    45 
    46 struct MS_ADPCM_decodestate {
    47 	Uint8 hPredictor;
    48 	Uint16 iDelta;
    49 	Sint16 iSamp1;
    50 	Sint16 iSamp2;
    51 };
    52 static struct MS_ADPCM_decoder {
    53 	WaveFMT wavefmt;
    54 	Uint16 wSamplesPerBlock;
    55 	Uint16 wNumCoef;
    56 	Sint16 aCoeff[7][2];
    57 	/* * * */
    58 	struct MS_ADPCM_decodestate state[2];
    59 } MS_ADPCM_state;
    60 
    61 static int InitMS_ADPCM(WaveFMT *format)
    62 {
    63 	Uint8 *rogue_feel;
    64 	Uint16 extra_info;
    65 	int i;
    66 
    67 	/* Set the rogue pointer to the MS_ADPCM specific data */
    68 	MS_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);
    69 	MS_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);
    70 	MS_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);
    71 	MS_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate);
    72 	MS_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign);
    73 	MS_ADPCM_state.wavefmt.bitspersample =
    74 					 SDL_SwapLE16(format->bitspersample);
    75 	rogue_feel = (Uint8 *)format+sizeof(*format);
    76 	if ( sizeof(*format) == 16 ) {
    77 		extra_info = ((rogue_feel[1]<<8)|rogue_feel[0]);
    78 		rogue_feel += sizeof(Uint16);
    79 	}
    80 	MS_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]);
    81 	rogue_feel += sizeof(Uint16);
    82 	MS_ADPCM_state.wNumCoef = ((rogue_feel[1]<<8)|rogue_feel[0]);
    83 	rogue_feel += sizeof(Uint16);
    84 	if ( MS_ADPCM_state.wNumCoef != 7 ) {
    85 		SDL_SetError("Unknown set of MS_ADPCM coefficients");
    86 		return(-1);
    87 	}
    88 	for ( i=0; i<MS_ADPCM_state.wNumCoef; ++i ) {
    89 		MS_ADPCM_state.aCoeff[i][0] = ((rogue_feel[1]<<8)|rogue_feel[0]);
    90 		rogue_feel += sizeof(Uint16);
    91 		MS_ADPCM_state.aCoeff[i][1] = ((rogue_feel[1]<<8)|rogue_feel[0]);
    92 		rogue_feel += sizeof(Uint16);
    93 	}
    94 	return(0);
    95 }
    96 
    97 static Sint32 MS_ADPCM_nibble(struct MS_ADPCM_decodestate *state,
    98 					Uint8 nybble, Sint16 *coeff)
    99 {
   100 	const Sint32 max_audioval = ((1<<(16-1))-1);
   101 	const Sint32 min_audioval = -(1<<(16-1));
   102 	const Sint32 adaptive[] = {
   103 		230, 230, 230, 230, 307, 409, 512, 614,
   104 		768, 614, 512, 409, 307, 230, 230, 230
   105 	};
   106 	Sint32 new_sample, delta;
   107 
   108 	new_sample = ((state->iSamp1 * coeff[0]) +
   109 		      (state->iSamp2 * coeff[1]))/256;
   110 	if ( nybble & 0x08 ) {
   111 		new_sample += state->iDelta * (nybble-0x10);
   112 	} else {
   113 		new_sample += state->iDelta * nybble;
   114 	}
   115 	if ( new_sample < min_audioval ) {
   116 		new_sample = min_audioval;
   117 	} else
   118 	if ( new_sample > max_audioval ) {
   119 		new_sample = max_audioval;
   120 	}
   121 	delta = ((Sint32)state->iDelta * adaptive[nybble])/256;
   122 	if ( delta < 16 ) {
   123 		delta = 16;
   124 	}
   125 	state->iDelta = delta;
   126 	state->iSamp2 = state->iSamp1;
   127 	state->iSamp1 = new_sample;
   128 	return(new_sample);
   129 }
   130 
   131 static int MS_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
   132 {
   133 	struct MS_ADPCM_decodestate *state[2];
   134 	Uint8 *freeable, *encoded, *decoded;
   135 	Sint32 encoded_len, samplesleft;
   136 	Sint8 nybble, stereo;
   137 	Sint16 *coeff[2];
   138 	Sint32 new_sample;
   139 
   140 	/* Allocate the proper sized output buffer */
   141 	encoded_len = *audio_len;
   142 	encoded = *audio_buf;
   143 	freeable = *audio_buf;
   144 	*audio_len = (encoded_len/MS_ADPCM_state.wavefmt.blockalign) * 
   145 				MS_ADPCM_state.wSamplesPerBlock*
   146 				MS_ADPCM_state.wavefmt.channels*sizeof(Sint16);
   147 	*audio_buf = (Uint8 *)malloc(*audio_len);
   148 	if ( *audio_buf == NULL ) {
   149 		SDL_Error(SDL_ENOMEM);
   150 		return(-1);
   151 	}
   152 	decoded = *audio_buf;
   153 
   154 	/* Get ready... Go! */
   155 	stereo = (MS_ADPCM_state.wavefmt.channels == 2);
   156 	state[0] = &MS_ADPCM_state.state[0];
   157 	state[1] = &MS_ADPCM_state.state[stereo];
   158 	while ( encoded_len >= MS_ADPCM_state.wavefmt.blockalign ) {
   159 		/* Grab the initial information for this block */
   160 		state[0]->hPredictor = *encoded++;
   161 		if ( stereo ) {
   162 			state[1]->hPredictor = *encoded++;
   163 		}
   164 		state[0]->iDelta = ((encoded[1]<<8)|encoded[0]);
   165 		encoded += sizeof(Sint16);
   166 		if ( stereo ) {
   167 			state[1]->iDelta = ((encoded[1]<<8)|encoded[0]);
   168 			encoded += sizeof(Sint16);
   169 		}
   170 		state[0]->iSamp1 = ((encoded[1]<<8)|encoded[0]);
   171 		encoded += sizeof(Sint16);
   172 		if ( stereo ) {
   173 			state[1]->iSamp1 = ((encoded[1]<<8)|encoded[0]);
   174 			encoded += sizeof(Sint16);
   175 		}
   176 		state[0]->iSamp2 = ((encoded[1]<<8)|encoded[0]);
   177 		encoded += sizeof(Sint16);
   178 		if ( stereo ) {
   179 			state[1]->iSamp2 = ((encoded[1]<<8)|encoded[0]);
   180 			encoded += sizeof(Sint16);
   181 		}
   182 		coeff[0] = MS_ADPCM_state.aCoeff[state[0]->hPredictor];
   183 		coeff[1] = MS_ADPCM_state.aCoeff[state[1]->hPredictor];
   184 
   185 		/* Store the two initial samples we start with */
   186 		decoded[0] = state[0]->iSamp2&0xFF;
   187 		decoded[1] = state[0]->iSamp2>>8;
   188 		decoded += 2;
   189 		if ( stereo ) {
   190 			decoded[0] = state[1]->iSamp2&0xFF;
   191 			decoded[1] = state[1]->iSamp2>>8;
   192 			decoded += 2;
   193 		}
   194 		decoded[0] = state[0]->iSamp1&0xFF;
   195 		decoded[1] = state[0]->iSamp1>>8;
   196 		decoded += 2;
   197 		if ( stereo ) {
   198 			decoded[0] = state[1]->iSamp1&0xFF;
   199 			decoded[1] = state[1]->iSamp1>>8;
   200 			decoded += 2;
   201 		}
   202 
   203 		/* Decode and store the other samples in this block */
   204 		samplesleft = (MS_ADPCM_state.wSamplesPerBlock-2)*
   205 					MS_ADPCM_state.wavefmt.channels;
   206 		while ( samplesleft > 0 ) {
   207 			nybble = (*encoded)>>4;
   208 			new_sample = MS_ADPCM_nibble(state[0],nybble,coeff[0]);
   209 			decoded[0] = new_sample&0xFF;
   210 			new_sample >>= 8;
   211 			decoded[1] = new_sample&0xFF;
   212 			decoded += 2;
   213 
   214 			nybble = (*encoded)&0x0F;
   215 			new_sample = MS_ADPCM_nibble(state[1],nybble,coeff[1]);
   216 			decoded[0] = new_sample&0xFF;
   217 			new_sample >>= 8;
   218 			decoded[1] = new_sample&0xFF;
   219 			decoded += 2;
   220 
   221 			++encoded;
   222 			samplesleft -= 2;
   223 		}
   224 		encoded_len -= MS_ADPCM_state.wavefmt.blockalign;
   225 	}
   226 	free(freeable);
   227 	return(0);
   228 }
   229 
   230 struct IMA_ADPCM_decodestate {
   231 	Sint32 sample;
   232 	Sint8 index;
   233 };
   234 static struct IMA_ADPCM_decoder {
   235 	WaveFMT wavefmt;
   236 	Uint16 wSamplesPerBlock;
   237 	/* * * */
   238 	struct IMA_ADPCM_decodestate state[2];
   239 } IMA_ADPCM_state;
   240 
   241 static int InitIMA_ADPCM(WaveFMT *format)
   242 {
   243 	Uint8 *rogue_feel;
   244 	Uint16 extra_info;
   245 
   246 	/* Set the rogue pointer to the IMA_ADPCM specific data */
   247 	IMA_ADPCM_state.wavefmt.encoding = SDL_SwapLE16(format->encoding);
   248 	IMA_ADPCM_state.wavefmt.channels = SDL_SwapLE16(format->channels);
   249 	IMA_ADPCM_state.wavefmt.frequency = SDL_SwapLE32(format->frequency);
   250 	IMA_ADPCM_state.wavefmt.byterate = SDL_SwapLE32(format->byterate);
   251 	IMA_ADPCM_state.wavefmt.blockalign = SDL_SwapLE16(format->blockalign);
   252 	IMA_ADPCM_state.wavefmt.bitspersample =
   253 					 SDL_SwapLE16(format->bitspersample);
   254 	rogue_feel = (Uint8 *)format+sizeof(*format);
   255 	if ( sizeof(*format) == 16 ) {
   256 		extra_info = ((rogue_feel[1]<<8)|rogue_feel[0]);
   257 		rogue_feel += sizeof(Uint16);
   258 	}
   259 	IMA_ADPCM_state.wSamplesPerBlock = ((rogue_feel[1]<<8)|rogue_feel[0]);
   260 	return(0);
   261 }
   262 
   263 static Sint32 IMA_ADPCM_nibble(struct IMA_ADPCM_decodestate *state,Uint8 nybble)
   264 {
   265 	const Sint32 max_audioval = ((1<<(16-1))-1);
   266 	const Sint32 min_audioval = -(1<<(16-1));
   267 	const int index_table[16] = {
   268 		-1, -1, -1, -1,
   269 		 2,  4,  6,  8,
   270 		-1, -1, -1, -1,
   271 		 2,  4,  6,  8
   272 	};
   273 	const Sint32 step_table[89] = {
   274 		7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31,
   275 		34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130,
   276 		143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408,
   277 		449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282,
   278 		1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327,
   279 		3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630,
   280 		9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350,
   281 		22385, 24623, 27086, 29794, 32767
   282 	};
   283 	Sint32 delta, step;
   284 
   285 	/* Compute difference and new sample value */
   286 	step = step_table[state->index];
   287 	delta = step >> 3;
   288 	if ( nybble & 0x04 ) delta += step;
   289 	if ( nybble & 0x02 ) delta += (step >> 1);
   290 	if ( nybble & 0x01 ) delta += (step >> 2);
   291 	if ( nybble & 0x08 ) delta = -delta;
   292 	state->sample += delta;
   293 
   294 	/* Update index value */
   295 	state->index += index_table[nybble];
   296 	if ( state->index > 88 ) {
   297 		state->index = 88;
   298 	} else
   299 	if ( state->index < 0 ) {
   300 		state->index = 0;
   301 	}
   302 
   303 	/* Clamp output sample */
   304 	if ( state->sample > max_audioval ) {
   305 		state->sample = max_audioval;
   306 	} else
   307 	if ( state->sample < min_audioval ) {
   308 		state->sample = min_audioval;
   309 	}
   310 	return(state->sample);
   311 }
   312 
   313 /* Fill the decode buffer with a channel block of data (8 samples) */
   314 static void Fill_IMA_ADPCM_block(Uint8 *decoded, Uint8 *encoded,
   315 	int channel, int numchannels, struct IMA_ADPCM_decodestate *state)
   316 {
   317 	int i;
   318 	Sint8 nybble;
   319 	Sint32 new_sample;
   320 
   321 	decoded += (channel * 2);
   322 	for ( i=0; i<4; ++i ) {
   323 		nybble = (*encoded)&0x0F;
   324 		new_sample = IMA_ADPCM_nibble(state, nybble);
   325 		decoded[0] = new_sample&0xFF;
   326 		new_sample >>= 8;
   327 		decoded[1] = new_sample&0xFF;
   328 		decoded += 2 * numchannels;
   329 
   330 		nybble = (*encoded)>>4;
   331 		new_sample = IMA_ADPCM_nibble(state, nybble);
   332 		decoded[0] = new_sample&0xFF;
   333 		new_sample >>= 8;
   334 		decoded[1] = new_sample&0xFF;
   335 		decoded += 2 * numchannels;
   336 
   337 		++encoded;
   338 	}
   339 }
   340 
   341 static int IMA_ADPCM_decode(Uint8 **audio_buf, Uint32 *audio_len)
   342 {
   343 	struct IMA_ADPCM_decodestate *state;
   344 	Uint8 *freeable, *encoded, *decoded;
   345 	Sint32 encoded_len, samplesleft;
   346 	int c, channels;
   347 
   348 	/* Check to make sure we have enough variables in the state array */
   349 	channels = IMA_ADPCM_state.wavefmt.channels;
   350 	if ( channels > NELEMS(IMA_ADPCM_state.state) ) {
   351 		SDL_SetError("IMA ADPCM decoder can only handle %d channels",
   352 						NELEMS(IMA_ADPCM_state.state));
   353 		return(-1);
   354 	}
   355 	state = IMA_ADPCM_state.state;
   356 
   357 	/* Allocate the proper sized output buffer */
   358 	encoded_len = *audio_len;
   359 	encoded = *audio_buf;
   360 	freeable = *audio_buf;
   361 	*audio_len = (encoded_len/IMA_ADPCM_state.wavefmt.blockalign) * 
   362 				IMA_ADPCM_state.wSamplesPerBlock*
   363 				IMA_ADPCM_state.wavefmt.channels*sizeof(Sint16);
   364 	*audio_buf = (Uint8 *)malloc(*audio_len);
   365 	if ( *audio_buf == NULL ) {
   366 		SDL_Error(SDL_ENOMEM);
   367 		return(-1);
   368 	}
   369 	decoded = *audio_buf;
   370 
   371 	/* Get ready... Go! */
   372 	while ( encoded_len >= IMA_ADPCM_state.wavefmt.blockalign ) {
   373 		/* Grab the initial information for this block */
   374 		for ( c=0; c<channels; ++c ) {
   375 			/* Fill the state information for this block */
   376 			state[c].sample = ((encoded[1]<<8)|encoded[0]);
   377 			encoded += 2;
   378 			if ( state[c].sample & 0x8000 ) {
   379 				state[c].sample -= 0x10000;
   380 			}
   381 			state[c].index = *encoded++;
   382 			/* Reserved byte in buffer header, should be 0 */
   383 			if ( *encoded++ != 0 ) {
   384 				/* Uh oh, corrupt data?  Buggy code? */;
   385 			}
   386 
   387 			/* Store the initial sample we start with */
   388 			decoded[0] = state[c].sample&0xFF;
   389 			decoded[1] = state[c].sample>>8;
   390 			decoded += 2;
   391 		}
   392 
   393 		/* Decode and store the other samples in this block */
   394 		samplesleft = (IMA_ADPCM_state.wSamplesPerBlock-1)*channels;
   395 		while ( samplesleft > 0 ) {
   396 			for ( c=0; c<channels; ++c ) {
   397 				Fill_IMA_ADPCM_block(decoded, encoded,
   398 						c, channels, &state[c]);
   399 				encoded += 4;
   400 				samplesleft -= 8;
   401 			}
   402 			decoded += (channels * 8 * 2);
   403 		}
   404 		encoded_len -= IMA_ADPCM_state.wavefmt.blockalign;
   405 	}
   406 	free(freeable);
   407 	return(0);
   408 }
   409 
   410 SDL_AudioSpec * SDL_LoadWAV_RW (SDL_RWops *src, int freesrc,
   411 		SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len)
   412 {
   413 	int was_error;
   414 	Chunk chunk;
   415 	int lenread;
   416 	int MS_ADPCM_encoded, IMA_ADPCM_encoded;
   417 	int samplesize;
   418 
   419 	/* WAV magic header */
   420 	Uint32 RIFFchunk;
   421 	Uint32 wavelen = 0;
   422 	Uint32 WAVEmagic;
   423 	Uint32 headerDiff = 0;
   424 
   425 	/* FMT chunk */
   426 	WaveFMT *format = NULL;
   427 
   428 	/* Make sure we are passed a valid data source */
   429 	was_error = 0;
   430 	if ( src == NULL ) {
   431 		was_error = 1;
   432 		goto done;
   433 	}
   434 		
   435 	/* Check the magic header */
   436 	RIFFchunk	= SDL_ReadLE32(src);
   437 	wavelen		= SDL_ReadLE32(src);
   438 	if ( wavelen == WAVE ) { /* The RIFFchunk has already been read */
   439 		WAVEmagic = wavelen;
   440 		wavelen   = RIFFchunk;
   441 		RIFFchunk = RIFF;
   442 	} else {
   443 		WAVEmagic = SDL_ReadLE32(src);
   444 	}
   445 	if ( (RIFFchunk != RIFF) || (WAVEmagic != WAVE) ) {
   446 		SDL_SetError("Unrecognized file type (not WAVE)");
   447 		was_error = 1;
   448 		goto done;
   449 	}
   450 	headerDiff += sizeof(Uint32); // for WAVE
   451 
   452 	/* Read the audio data format chunk */
   453 	chunk.data = NULL;
   454 	do {
   455 		if ( chunk.data != NULL ) {
   456 			free(chunk.data);
   457 		}
   458 		lenread = ReadChunk(src, &chunk);
   459 		if ( lenread < 0 ) {
   460 			was_error = 1;
   461 			goto done;
   462 		}
   463 		// 2 Uint32's for chunk header+len, plus the lenread
   464 		headerDiff += lenread + 2 * sizeof(Uint32);
   465 	} while ( (chunk.magic == FACT) || (chunk.magic == LIST) );
   466 
   467 	/* Decode the audio data format */
   468 	format = (WaveFMT *)chunk.data;
   469 	if ( chunk.magic != FMT ) {
   470 		SDL_SetError("Complex WAVE files not supported");
   471 		was_error = 1;
   472 		goto done;
   473 	}
   474 	MS_ADPCM_encoded = IMA_ADPCM_encoded = 0;
   475 	switch (SDL_SwapLE16(format->encoding)) {
   476 		case PCM_CODE:
   477 			/* We can understand this */
   478 			break;
   479 		case MS_ADPCM_CODE:
   480 			/* Try to understand this */
   481 			if ( InitMS_ADPCM(format) < 0 ) {
   482 				was_error = 1;
   483 				goto done;
   484 			}
   485 			MS_ADPCM_encoded = 1;
   486 			break;
   487 		case IMA_ADPCM_CODE:
   488 			/* Try to understand this */
   489 			if ( InitIMA_ADPCM(format) < 0 ) {
   490 				was_error = 1;
   491 				goto done;
   492 			}
   493 			IMA_ADPCM_encoded = 1;
   494 			break;
   495 		default:
   496 			SDL_SetError("Unknown WAVE data format: 0x%.4x",
   497 					SDL_SwapLE16(format->encoding));
   498 			was_error = 1;
   499 			goto done;
   500 	}
   501 	memset(spec, 0, (sizeof *spec));
   502 	spec->freq = SDL_SwapLE32(format->frequency);
   503 	switch (SDL_SwapLE16(format->bitspersample)) {
   504 		case 4:
   505 			if ( MS_ADPCM_encoded || IMA_ADPCM_encoded ) {
   506 				spec->format = AUDIO_S16;
   507 			} else {
   508 				was_error = 1;
   509 			}
   510 			break;
   511 		case 8:
   512 			spec->format = AUDIO_U8;
   513 			break;
   514 		case 16:
   515 			spec->format = AUDIO_S16;
   516 			break;
   517 		default:
   518 			was_error = 1;
   519 			break;
   520 	}
   521 	if ( was_error ) {
   522 		SDL_SetError("Unknown %d-bit PCM data format",
   523 			SDL_SwapLE16(format->bitspersample));
   524 		goto done;
   525 	}
   526 	spec->channels = (Uint8)SDL_SwapLE16(format->channels);
   527 	spec->samples = 4096;		/* Good default buffer size */
   528 
   529 	/* Read the audio data chunk */
   530 	*audio_buf = NULL;
   531 	do {
   532 		if ( *audio_buf != NULL ) {
   533 			free(*audio_buf);
   534 		}
   535 		lenread = ReadChunk(src, &chunk);
   536 		if ( lenread < 0 ) {
   537 			was_error = 1;
   538 			goto done;
   539 		}
   540 		*audio_len = lenread;
   541 		*audio_buf = chunk.data;
   542 		if(chunk.magic != DATA) headerDiff += lenread + 2 * sizeof(Uint32);
   543 	} while ( chunk.magic != DATA );
   544 	headerDiff += 2 * sizeof(Uint32); // for the data chunk and len
   545 
   546 	if ( MS_ADPCM_encoded ) {
   547 		if ( MS_ADPCM_decode(audio_buf, audio_len) < 0 ) {
   548 			was_error = 1;
   549 			goto done;
   550 		}
   551 	}
   552 	if ( IMA_ADPCM_encoded ) {
   553 		if ( IMA_ADPCM_decode(audio_buf, audio_len) < 0 ) {
   554 			was_error = 1;
   555 			goto done;
   556 		}
   557 	}
   558 
   559 	/* Don't return a buffer that isn't a multiple of samplesize */
   560 	samplesize = ((spec->format & 0xFF)/8)*spec->channels;
   561 	*audio_len &= ~(samplesize-1);
   562 
   563 done:
   564 	if ( format != NULL ) {
   565 		free(format);
   566 	}
   567 	if ( freesrc && src ) {
   568 		SDL_RWclose(src);
   569 	}
   570 	else {
   571 		// seek to the end of the file (given by the RIFF chunk)
   572 		SDL_RWseek(src, wavelen - chunk.length - headerDiff, SEEK_CUR);
   573 	}
   574 	if ( was_error ) {
   575 		spec = NULL;
   576 	}
   577 	return(spec);
   578 }
   579 
   580 /* Since the WAV memory is allocated in the shared library, it must also
   581    be freed here.  (Necessary under Win32, VC++)
   582  */
   583 void SDL_FreeWAV(Uint8 *audio_buf)
   584 {
   585 	if ( audio_buf != NULL ) {
   586 		free(audio_buf);
   587 	}
   588 }
   589 
   590 static int ReadChunk(SDL_RWops *src, Chunk *chunk)
   591 {
   592 	chunk->magic	= SDL_ReadLE32(src);
   593 	chunk->length	= SDL_ReadLE32(src);
   594 	chunk->data = (Uint8 *)malloc(chunk->length);
   595 	if ( chunk->data == NULL ) {
   596 		SDL_Error(SDL_ENOMEM);
   597 		return(-1);
   598 	}
   599 	if ( SDL_RWread(src, chunk->data, chunk->length, 1) != 1 ) {
   600 		SDL_Error(SDL_EFREAD);
   601 		free(chunk->data);
   602 		return(-1);
   603 	}
   604 	return(chunk->length);
   605 }
   606 
   607 #endif /* ENABLE_FILE */