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