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