comparison src/audio/SDL_wave.c @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children 02e27b705645
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997, 1998, 1999, 2000, 2001 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@devolution.com
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;
422 Uint32 WAVEmagic;
423
424 /* FMT chunk */
425 WaveFMT *format = NULL;
426
427 /* Make sure we are passed a valid data source */
428 was_error = 0;
429 if ( src == NULL ) {
430 was_error = 1;
431 goto done;
432 }
433
434 /* Check the magic header */
435 RIFFchunk = SDL_ReadLE32(src);
436 wavelen = SDL_ReadLE32(src);
437 WAVEmagic = SDL_ReadLE32(src);
438 if ( (RIFFchunk != RIFF) || (WAVEmagic != WAVE) ) {
439 SDL_SetError("Unrecognized file type (not WAVE)");
440 was_error = 1;
441 goto done;
442 }
443
444 /* Read the audio data format chunk */
445 chunk.data = NULL;
446 do {
447 if ( chunk.data != NULL ) {
448 free(chunk.data);
449 }
450 lenread = ReadChunk(src, &chunk);
451 if ( lenread < 0 ) {
452 was_error = 1;
453 goto done;
454 }
455 } while ( (chunk.magic == FACT) || (chunk.magic == LIST) );
456
457 /* Decode the audio data format */
458 format = (WaveFMT *)chunk.data;
459 if ( chunk.magic != FMT ) {
460 SDL_SetError("Complex WAVE files not supported");
461 was_error = 1;
462 goto done;
463 }
464 MS_ADPCM_encoded = IMA_ADPCM_encoded = 0;
465 switch (SDL_SwapLE16(format->encoding)) {
466 case PCM_CODE:
467 /* We can understand this */
468 break;
469 case MS_ADPCM_CODE:
470 /* Try to understand this */
471 if ( InitMS_ADPCM(format) < 0 ) {
472 was_error = 1;
473 goto done;
474 }
475 MS_ADPCM_encoded = 1;
476 break;
477 case IMA_ADPCM_CODE:
478 /* Try to understand this */
479 if ( InitIMA_ADPCM(format) < 0 ) {
480 was_error = 1;
481 goto done;
482 }
483 IMA_ADPCM_encoded = 1;
484 break;
485 default:
486 SDL_SetError("Unknown WAVE data format: 0x%.4x",
487 SDL_SwapLE16(format->encoding));
488 was_error = 1;
489 goto done;
490 }
491 memset(spec, 0, (sizeof *spec));
492 spec->freq = SDL_SwapLE32(format->frequency);
493 switch (SDL_SwapLE16(format->bitspersample)) {
494 case 4:
495 if ( MS_ADPCM_encoded || IMA_ADPCM_encoded ) {
496 spec->format = AUDIO_S16;
497 } else {
498 was_error = 1;
499 }
500 break;
501 case 8:
502 spec->format = AUDIO_U8;
503 break;
504 case 16:
505 spec->format = AUDIO_S16;
506 break;
507 default:
508 was_error = 1;
509 break;
510 }
511 if ( was_error ) {
512 SDL_SetError("Unknown %d-bit PCM data format",
513 SDL_SwapLE16(format->bitspersample));
514 goto done;
515 }
516 spec->channels = (Uint8)SDL_SwapLE16(format->channels);
517 spec->samples = 4096; /* Good default buffer size */
518
519 /* Read the audio data chunk */
520 *audio_buf = NULL;
521 do {
522 if ( *audio_buf != NULL ) {
523 free(*audio_buf);
524 }
525 lenread = ReadChunk(src, &chunk);
526 if ( lenread < 0 ) {
527 was_error = 1;
528 goto done;
529 }
530 *audio_len = lenread;
531 *audio_buf = chunk.data;
532 } while ( chunk.magic != DATA );
533
534 if ( MS_ADPCM_encoded ) {
535 if ( MS_ADPCM_decode(audio_buf, audio_len) < 0 ) {
536 was_error = 1;
537 goto done;
538 }
539 }
540 if ( IMA_ADPCM_encoded ) {
541 if ( IMA_ADPCM_decode(audio_buf, audio_len) < 0 ) {
542 was_error = 1;
543 goto done;
544 }
545 }
546
547 /* Don't return a buffer that isn't a multiple of samplesize */
548 samplesize = ((spec->format & 0xFF)/8)*spec->channels;
549 *audio_len &= ~(samplesize-1);
550
551 done:
552 if ( format != NULL ) {
553 free(format);
554 }
555 if ( freesrc && src ) {
556 SDL_RWclose(src);
557 }
558 if ( was_error ) {
559 spec = NULL;
560 }
561 return(spec);
562 }
563
564 /* Since the WAV memory is allocated in the shared library, it must also
565 be freed here. (Necessary under Win32, VC++)
566 */
567 void SDL_FreeWAV(Uint8 *audio_buf)
568 {
569 if ( audio_buf != NULL ) {
570 free(audio_buf);
571 }
572 }
573
574 static int ReadChunk(SDL_RWops *src, Chunk *chunk)
575 {
576 chunk->magic = SDL_ReadLE32(src);
577 chunk->length = SDL_ReadLE32(src);
578 chunk->data = (Uint8 *)malloc(chunk->length);
579 if ( chunk->data == NULL ) {
580 SDL_Error(SDL_ENOMEM);
581 return(-1);
582 }
583 if ( SDL_RWread(src, chunk->data, chunk->length, 1) != 1 ) {
584 SDL_Error(SDL_EFREAD);
585 free(chunk->data);
586 return(-1);
587 }
588 return(chunk->length);
589 }
590
591 #endif /* ENABLE_FILE */