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