e14743d1 |
1 | /* |
2 | SDL - Simple DirectMedia Layer |
3 | Copyright (C) 1997-2009 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 = (Uint16)delta; |
112 | state->iSamp2 = state->iSamp1; |
113 | state->iSamp1 = (Sint16)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 | unsigned 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] = (Uint8)(state[c].sample&0xFF); |
375 | decoded[1] = (Uint8)(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 | chunk.data = NULL; |
444 | } |
445 | lenread = ReadChunk(src, &chunk); |
446 | if ( lenread < 0 ) { |
447 | was_error = 1; |
448 | goto done; |
449 | } |
450 | /* 2 Uint32's for chunk header+len, plus the lenread */ |
451 | headerDiff += lenread + 2 * sizeof(Uint32); |
452 | } while ( (chunk.magic == FACT) || (chunk.magic == LIST) ); |
453 | |
454 | /* Decode the audio data format */ |
455 | format = (WaveFMT *)chunk.data; |
456 | if ( chunk.magic != FMT ) { |
457 | SDL_SetError("Complex WAVE files not supported"); |
458 | was_error = 1; |
459 | goto done; |
460 | } |
461 | MS_ADPCM_encoded = IMA_ADPCM_encoded = 0; |
462 | switch (SDL_SwapLE16(format->encoding)) { |
463 | case PCM_CODE: |
464 | /* We can understand this */ |
465 | break; |
466 | case MS_ADPCM_CODE: |
467 | /* Try to understand this */ |
468 | if ( InitMS_ADPCM(format) < 0 ) { |
469 | was_error = 1; |
470 | goto done; |
471 | } |
472 | MS_ADPCM_encoded = 1; |
473 | break; |
474 | case IMA_ADPCM_CODE: |
475 | /* Try to understand this */ |
476 | if ( InitIMA_ADPCM(format) < 0 ) { |
477 | was_error = 1; |
478 | goto done; |
479 | } |
480 | IMA_ADPCM_encoded = 1; |
481 | break; |
482 | case MP3_CODE: |
483 | SDL_SetError("MPEG Layer 3 data not supported", |
484 | SDL_SwapLE16(format->encoding)); |
485 | was_error = 1; |
486 | goto done; |
487 | default: |
488 | SDL_SetError("Unknown WAVE data format: 0x%.4x", |
489 | SDL_SwapLE16(format->encoding)); |
490 | was_error = 1; |
491 | goto done; |
492 | } |
493 | SDL_memset(spec, 0, (sizeof *spec)); |
494 | spec->freq = SDL_SwapLE32(format->frequency); |
495 | switch (SDL_SwapLE16(format->bitspersample)) { |
496 | case 4: |
497 | if ( MS_ADPCM_encoded || IMA_ADPCM_encoded ) { |
498 | spec->format = AUDIO_S16; |
499 | } else { |
500 | was_error = 1; |
501 | } |
502 | break; |
503 | case 8: |
504 | spec->format = AUDIO_U8; |
505 | break; |
506 | case 16: |
507 | spec->format = AUDIO_S16; |
508 | break; |
509 | default: |
510 | was_error = 1; |
511 | break; |
512 | } |
513 | if ( was_error ) { |
514 | SDL_SetError("Unknown %d-bit PCM data format", |
515 | SDL_SwapLE16(format->bitspersample)); |
516 | goto done; |
517 | } |
518 | spec->channels = (Uint8)SDL_SwapLE16(format->channels); |
519 | spec->samples = 4096; /* Good default buffer size */ |
520 | |
521 | /* Read the audio data chunk */ |
522 | *audio_buf = NULL; |
523 | do { |
524 | if ( *audio_buf != NULL ) { |
525 | SDL_free(*audio_buf); |
526 | *audio_buf = NULL; |
527 | } |
528 | lenread = ReadChunk(src, &chunk); |
529 | if ( lenread < 0 ) { |
530 | was_error = 1; |
531 | goto done; |
532 | } |
533 | *audio_len = lenread; |
534 | *audio_buf = chunk.data; |
535 | if(chunk.magic != DATA) headerDiff += lenread + 2 * sizeof(Uint32); |
536 | } while ( chunk.magic != DATA ); |
537 | headerDiff += 2 * sizeof(Uint32); /* for the data chunk and len */ |
538 | |
539 | if ( MS_ADPCM_encoded ) { |
540 | if ( MS_ADPCM_decode(audio_buf, audio_len) < 0 ) { |
541 | was_error = 1; |
542 | goto done; |
543 | } |
544 | } |
545 | if ( IMA_ADPCM_encoded ) { |
546 | if ( IMA_ADPCM_decode(audio_buf, audio_len) < 0 ) { |
547 | was_error = 1; |
548 | goto done; |
549 | } |
550 | } |
551 | |
552 | /* Don't return a buffer that isn't a multiple of samplesize */ |
553 | samplesize = ((spec->format & 0xFF)/8)*spec->channels; |
554 | *audio_len &= ~(samplesize-1); |
555 | |
556 | done: |
557 | if ( format != NULL ) { |
558 | SDL_free(format); |
559 | } |
560 | if ( src ) { |
561 | if ( freesrc ) { |
562 | SDL_RWclose(src); |
563 | } else { |
564 | /* seek to the end of the file (given by the RIFF chunk) */ |
565 | SDL_RWseek(src, wavelen - chunk.length - headerDiff, RW_SEEK_CUR); |
566 | } |
567 | } |
568 | if ( was_error ) { |
569 | spec = NULL; |
570 | } |
571 | return(spec); |
572 | } |
573 | |
574 | /* Since the WAV memory is allocated in the shared library, it must also |
575 | be freed here. (Necessary under Win32, VC++) |
576 | */ |
577 | void SDL_FreeWAV(Uint8 *audio_buf) |
578 | { |
579 | if ( audio_buf != NULL ) { |
580 | SDL_free(audio_buf); |
581 | } |
582 | } |
583 | |
584 | static int ReadChunk(SDL_RWops *src, Chunk *chunk) |
585 | { |
586 | chunk->magic = SDL_ReadLE32(src); |
587 | chunk->length = SDL_ReadLE32(src); |
588 | chunk->data = (Uint8 *)SDL_malloc(chunk->length); |
589 | if ( chunk->data == NULL ) { |
590 | SDL_Error(SDL_ENOMEM); |
591 | return(-1); |
592 | } |
593 | if ( SDL_RWread(src, chunk->data, chunk->length, 1) != 1 ) { |
594 | SDL_Error(SDL_EFREAD); |
595 | SDL_free(chunk->data); |
596 | chunk->data = NULL; |
597 | return(-1); |
598 | } |
599 | return(chunk->length); |
600 | } |