comparison decoders/wav.c @ 185:6bb68b3bdcf1

ADPCM decoder seems to be complete, other fixes too...
author Ryan C. Gordon <icculus@icculus.org>
date Thu, 27 Dec 2001 23:05:05 +0000
parents 26996236d790
children 6cd07211a235
comparison
equal deleted inserted replaced
184:47cc2de2ae36 185:6bb68b3bdcf1
99 99
100 /* Chunk management code... */ 100 /* Chunk management code... */
101 101
102 #define riffID 0x46464952 /* "RIFF", in ascii. */ 102 #define riffID 0x46464952 /* "RIFF", in ascii. */
103 #define waveID 0x45564157 /* "WAVE", in ascii. */ 103 #define waveID 0x45564157 /* "WAVE", in ascii. */
104 #define factID 0x74636166 /* "fact", in ascii. */
104 105
105 106
106 /***************************************************************************** 107 /*****************************************************************************
107 * The FORMAT chunk... * 108 * The FORMAT chunk... *
108 *****************************************************************************/ 109 *****************************************************************************/
112 #define FMT_NORMAL 0x0001 /* Uncompressed waveform data. */ 113 #define FMT_NORMAL 0x0001 /* Uncompressed waveform data. */
113 #define FMT_ADPCM 0x0002 /* ADPCM compressed waveform data. */ 114 #define FMT_ADPCM 0x0002 /* ADPCM compressed waveform data. */
114 115
115 typedef struct 116 typedef struct
116 { 117 {
117 Uint16 iCoef1; 118 Sint16 iCoef1;
118 Uint16 iCoef2; 119 Sint16 iCoef2;
119 } ADPCMCOEFSET; 120 } ADPCMCOEFSET;
120 121
121 typedef struct 122 typedef struct
122 { 123 {
123 Uint8 bPredictor; 124 Uint8 bPredictor;
135 Uint32 dwSamplesPerSec; 136 Uint32 dwSamplesPerSec;
136 Uint32 dwAvgBytesPerSec; 137 Uint32 dwAvgBytesPerSec;
137 Uint16 wBlockAlign; 138 Uint16 wBlockAlign;
138 Uint16 wBitsPerSample; 139 Uint16 wBitsPerSample;
139 140
141 Uint32 sample_frame_size;
142
140 void (*free)(struct S_WAV_FMT_T *fmt); 143 void (*free)(struct S_WAV_FMT_T *fmt);
141 Uint32 (*read_sample)(Sound_Sample *sample); 144 Uint32 (*read_sample)(Sound_Sample *sample);
142 145
143 union 146 union
144 { 147 {
147 Uint16 cbSize; 150 Uint16 cbSize;
148 Uint16 wSamplesPerBlock; 151 Uint16 wSamplesPerBlock;
149 Uint16 wNumCoef; 152 Uint16 wNumCoef;
150 ADPCMCOEFSET *aCoef; 153 ADPCMCOEFSET *aCoef;
151 ADPCMBLOCKHEADER *blockheaders; 154 ADPCMBLOCKHEADER *blockheaders;
155 Uint32 samples_left_in_block;
156 int nibble_state;
157 Sint8 nibble;
152 } adpcm; 158 } adpcm;
153 159
154 /* put other format-specific data here... */ 160 /* put other format-specific data here... */
155 } fmt; 161 } fmt;
156 } fmt_t; 162 } fmt_t;
224 230
225 /***************************************************************************** 231 /*****************************************************************************
226 * Normal, uncompressed waveform handler... * 232 * Normal, uncompressed waveform handler... *
227 *****************************************************************************/ 233 *****************************************************************************/
228 234
235 /*
236 * Sound_Decode() lands here for uncompressed WAVs...
237 */
229 static Uint32 read_sample_fmt_normal(Sound_Sample *sample) 238 static Uint32 read_sample_fmt_normal(Sound_Sample *sample)
230 { 239 {
231 Uint32 retval; 240 Uint32 retval;
232 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; 241 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
233 wav_t *w = (wav_t *) internal->decoder_private; 242 wav_t *w = (wav_t *) internal->decoder_private;
272 281
273 /***************************************************************************** 282 /*****************************************************************************
274 * ADPCM compression handler... * 283 * ADPCM compression handler... *
275 *****************************************************************************/ 284 *****************************************************************************/
276 285
277 static int read_adpcm_block_headers(SDL_RWops *rw, fmt_t *fmt) 286 #define FIXED_POINT_COEF_BASE 256
278 { 287 #define FIXED_POINT_ADAPTION_BASE 256
279 ADPCMBLOCKHEADER *headers = fmt->fmt.adpcm.blockheaders; 288 #define SMALLEST_ADPCM_DELTA 16
280 int i; 289
281 int max = fmt->wChannels; 290
282 291 static inline int read_adpcm_block_headers(Sound_Sample *sample)
283 for (i = 0; i < max; i++)
284 BAIL_IF_MACRO(!read_uint8(rw, &headers[i].bPredictor), NULL, 0);
285
286 for (i = 0; i < max; i++)
287 BAIL_IF_MACRO(!read_le16(rw, &headers[i].iDelta), NULL, 0);
288
289 for (i = 0; i < max; i++)
290 BAIL_IF_MACRO(!read_le16(rw, &headers[i].iSamp1), NULL, 0);
291
292 for (i = 0; i < max; i++)
293 BAIL_IF_MACRO(!read_le16(rw, &headers[i].iSamp2), NULL, 0);
294
295 return(1);
296 } /* read_adpcm_block_headers */
297
298
299 static int decode_adpcm_block(Sound_Sample *sample)
300 { 292 {
301 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; 293 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
302 SDL_RWops *rw = internal->rw; 294 SDL_RWops *rw = internal->rw;
303 wav_t *w = (wav_t *) internal->decoder_private; 295 wav_t *w = (wav_t *) internal->decoder_private;
304 fmt_t *fmt = w->fmt; 296 fmt_t *fmt = w->fmt;
305 ADPCMBLOCKHEADER *headers = fmt->fmt.adpcm.blockheaders; 297 ADPCMBLOCKHEADER *headers = fmt->fmt.adpcm.blockheaders;
306 int i; 298 int i;
307 int max = fmt->wChannels; 299 int max = fmt->wChannels;
308 300
309 if (!read_adpcm_block_headers(rw, fmt)) 301 if (w->bytesLeft < fmt->wBlockAlign)
310 { 302 {
311 sample->flags |= SOUND_SAMPLEFLAG_ERROR; 303 sample->flags |= SOUND_SAMPLEFLAG_EOF;
312 return(0); 304 return(0);
313 } /* if */ 305 } /* if */
314 306
307 w->bytesLeft -= fmt->wBlockAlign;
308
315 for (i = 0; i < max; i++) 309 for (i = 0; i < max; i++)
316 { 310 BAIL_IF_MACRO(!read_uint8(rw, &headers[i].bPredictor), NULL, 0);
317 Uint16 iCoef1 = fmt->fmt.adpcm.aCoef[headers[i].bPredictor].iCoef1; 311
318 Uint16 iCoef2 = fmt->fmt.adpcm.aCoef[headers[i].bPredictor].iCoef2; 312 for (i = 0; i < max; i++)
319 /* 313 BAIL_IF_MACRO(!read_le16(rw, &headers[i].iDelta), NULL, 0);
314
315 for (i = 0; i < max; i++)
316 BAIL_IF_MACRO(!read_le16(rw, &headers[i].iSamp1), NULL, 0);
317
318 for (i = 0; i < max; i++)
319 BAIL_IF_MACRO(!read_le16(rw, &headers[i].iSamp2), NULL, 0);
320
321 fmt->fmt.adpcm.samples_left_in_block = fmt->fmt.adpcm.wSamplesPerBlock;
322 fmt->fmt.adpcm.nibble_state = 0;
323 return(1);
324 } /* read_adpcm_block_headers */
325
326
327 static inline void do_adpcm_nibble(Uint8 nib,
328 ADPCMBLOCKHEADER *header,
329 Sint32 lPredSamp)
330 {
331 static const Sint32 max_audioval = ((1<<(16-1))-1);
332 static const Sint32 min_audioval = -(1<<(16-1));
333 static const Sint32 AdaptionTable[] =
334 {
335 230, 230, 230, 230, 307, 409, 512, 614,
336 768, 614, 512, 409, 307, 230, 230, 230
337 };
338
339 Sint32 lNewSamp;
340 Sint32 delta;
341
342 if (nib & 0x08)
343 lNewSamp = lPredSamp + (header->iDelta * (nib - 0x10));
344 else
345 lNewSamp = lPredSamp + (header->iDelta * nib);
346
347 /* clamp value... */
348 if (lNewSamp < min_audioval)
349 lNewSamp = min_audioval;
350 else if (lNewSamp > max_audioval)
351 lNewSamp = max_audioval;
352
353 delta = ((Sint32) header->iDelta * AdaptionTable[nib]) /
354 FIXED_POINT_ADAPTION_BASE;
355
356 if (delta < SMALLEST_ADPCM_DELTA)
357 delta = SMALLEST_ADPCM_DELTA;
358
359 header->iDelta = delta;
360 header->iSamp2 = header->iSamp1;
361 header->iSamp1 = lNewSamp;
362 } /* do_adpcm_nibble */
363
364
365 static inline int decode_adpcm_sample_frame(Sound_Sample *sample)
366 {
367 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
368 wav_t *w = (wav_t *) internal->decoder_private;
369 fmt_t *fmt = w->fmt;
370 ADPCMBLOCKHEADER *headers = fmt->fmt.adpcm.blockheaders;
371 SDL_RWops *rw = internal->rw;
372 int i;
373 int max = fmt->wChannels;
374 Sint32 delta;
375 Uint8 nib = fmt->fmt.adpcm.nibble;
376
377 for (i = 0; i < max; i++)
378 {
379 Uint8 byte;
380 Sint16 iCoef1 = fmt->fmt.adpcm.aCoef[headers[i].bPredictor].iCoef1;
381 Sint16 iCoef2 = fmt->fmt.adpcm.aCoef[headers[i].bPredictor].iCoef2;
320 Sint32 lPredSamp = ((headers[i].iSamp1 * iCoef1) + 382 Sint32 lPredSamp = ((headers[i].iSamp1 * iCoef1) +
321 (headers[i].iSamp2 * iCoef2)) / 383 (headers[i].iSamp2 * iCoef2)) /
322 FIXED_POINT_COEF_BASE; 384 FIXED_POINT_COEF_BASE;
323 */ 385
386 if (fmt->fmt.adpcm.nibble_state == 0)
387 {
388 BAIL_IF_MACRO(!read_uint8(rw, &nib), NULL, 0);
389 fmt->fmt.adpcm.nibble_state = 1;
390 do_adpcm_nibble(nib >> 4, &headers[i], lPredSamp);
391 } /* if */
392 else
393 {
394 fmt->fmt.adpcm.nibble_state = 0;
395 do_adpcm_nibble(nib & 0x0F, &headers[i], lPredSamp);
396 } /* else */
324 } /* for */ 397 } /* for */
325 } /* decode_adpcm_block */ 398
326 399 fmt->fmt.adpcm.nibble = nib;
327 400 return(1);
401 } /* decode_adpcm_sample_frame */
402
403
404 static inline void put_adpcm_sample_frame1(Uint8 *_buf, fmt_t *fmt)
405 {
406 Uint16 *buf = (Uint16 *) _buf;
407 ADPCMBLOCKHEADER *headers = fmt->fmt.adpcm.blockheaders;
408 int i;
409 for (i = 0; i < fmt->wChannels; i++)
410 *(buf++) = headers[i].iSamp1;
411 } /* put_adpcm_sample_frame1 */
412
413
414 static inline void put_adpcm_sample_frame2(Uint8 *_buf, fmt_t *fmt)
415 {
416 Uint16 *buf = (Uint16 *) _buf;
417 ADPCMBLOCKHEADER *headers = fmt->fmt.adpcm.blockheaders;
418 int i;
419 for (i = 0; i < fmt->wChannels; i++)
420 *(buf++) = headers[i].iSamp2;
421 } /* put_adpcm_sample_frame2 */
422
423
424 /*
425 * Sound_Decode() lands here for ADPCM-encoded WAVs...
426 */
328 static Uint32 read_sample_fmt_adpcm(Sound_Sample *sample) 427 static Uint32 read_sample_fmt_adpcm(Sound_Sample *sample)
329 { 428 {
330 /* !!! FIXME: Write this. */ 429 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
331 Sound_SetError("WAV: Not implemented. Soon."); 430 wav_t *w = (wav_t *) internal->decoder_private;
332 sample->flags |= SOUND_SAMPLEFLAG_ERROR; 431 fmt_t *fmt = w->fmt;
333 return(0); 432 Uint32 bw = 0;
433
434 while (bw < internal->buffer_size)
435 {
436 /* write ongoing sample frame before reading more data... */
437 switch (fmt->fmt.adpcm.samples_left_in_block)
438 {
439 case 0: /* need to read a new block... */
440 if (!read_adpcm_block_headers(sample))
441 {
442 if ((sample->flags & SOUND_SAMPLEFLAG_EOF) == 0)
443 sample->flags |= SOUND_SAMPLEFLAG_ERROR;
444 return(bw);
445 } /* if */
446
447 /* only write first sample frame for now. */
448 put_adpcm_sample_frame2(internal->buffer + bw, fmt);
449 fmt->fmt.adpcm.samples_left_in_block--;
450 bw += fmt->sample_frame_size;
451 break;
452
453 case 1: /* output last sample frame of block... */
454 put_adpcm_sample_frame1(internal->buffer + bw, fmt);
455 fmt->fmt.adpcm.samples_left_in_block--;
456 bw += fmt->sample_frame_size;
457 break;
458
459 default: /* output latest sample frame and read a new one... */
460 put_adpcm_sample_frame1(internal->buffer + bw, fmt);
461 fmt->fmt.adpcm.samples_left_in_block--;
462 bw += fmt->sample_frame_size;
463
464 if (!decode_adpcm_sample_frame(sample))
465 {
466 sample->flags |= SOUND_SAMPLEFLAG_ERROR;
467 return(bw);
468 } /* if */
469 } /* switch */
470 } /* while */
471
472 return(bw);
334 } /* read_sample_fmt_adpcm */ 473 } /* read_sample_fmt_adpcm */
335 474
336 475
476 /*
477 * Sound_FreeSample() lands here for ADPCM-encoded WAVs...
478 */
337 static void free_fmt_adpcm(fmt_t *fmt) 479 static void free_fmt_adpcm(fmt_t *fmt)
338 { 480 {
339 if (fmt->fmt.adpcm.aCoef != NULL) 481 if (fmt->fmt.adpcm.aCoef != NULL)
340 free(fmt->fmt.adpcm.aCoef); 482 free(fmt->fmt.adpcm.aCoef);
341 483
359 501
360 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.cbSize), NULL, 0); 502 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.cbSize), NULL, 0);
361 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.wSamplesPerBlock), NULL, 0); 503 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.wSamplesPerBlock), NULL, 0);
362 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.wNumCoef), NULL, 0); 504 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.wNumCoef), NULL, 0);
363 505
364 /*
365 * !!! FIXME: SDL seems nervous about this, so I'll make a debug
366 * !!! FIXME: note for the time being...
367 */
368 if (fmt->fmt.adpcm.wNumCoef != 7)
369 {
370 SNDDBG(("WAV: adpcm's wNumCoef is NOT seven (it's %d)!\n",
371 fmt->fmt.adpcm.wNumCoef));
372 } /* if */
373
374 /* fmt->free() is always called, so these malloc()s will be cleaned up. */ 506 /* fmt->free() is always called, so these malloc()s will be cleaned up. */
507
375 i = sizeof (ADPCMCOEFSET) * fmt->fmt.adpcm.wNumCoef; 508 i = sizeof (ADPCMCOEFSET) * fmt->fmt.adpcm.wNumCoef;
376 fmt->fmt.adpcm.aCoef = (ADPCMCOEFSET *) malloc(i); 509 fmt->fmt.adpcm.aCoef = (ADPCMCOEFSET *) malloc(i);
377 BAIL_IF_MACRO(fmt->fmt.adpcm.aCoef == NULL, ERR_OUT_OF_MEMORY, 0); 510 BAIL_IF_MACRO(fmt->fmt.adpcm.aCoef == NULL, ERR_OUT_OF_MEMORY, 0);
378 511
512 for (i = 0; i < fmt->fmt.adpcm.wNumCoef; i++)
513 {
514 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.aCoef[i].iCoef1), NULL, 0);
515 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.aCoef[i].iCoef2), NULL, 0);
516 } /* for */
517
379 i = sizeof (ADPCMBLOCKHEADER) * fmt->wChannels; 518 i = sizeof (ADPCMBLOCKHEADER) * fmt->wChannels;
380 fmt->fmt.adpcm.blockheaders = (ADPCMBLOCKHEADER *) malloc(i); 519 fmt->fmt.adpcm.blockheaders = (ADPCMBLOCKHEADER *) malloc(i);
381 BAIL_IF_MACRO(fmt->fmt.adpcm.blockheaders == NULL, ERR_OUT_OF_MEMORY, 0); 520 BAIL_IF_MACRO(fmt->fmt.adpcm.blockheaders == NULL, ERR_OUT_OF_MEMORY, 0);
382
383 for (i = 0; i < fmt->fmt.adpcm.wNumCoef; i++)
384 {
385 int rc;
386 rc = SDL_RWread(rw, &fmt->fmt.adpcm.aCoef[i].iCoef1,
387 sizeof (fmt->fmt.adpcm.aCoef[i].iCoef1), 1);
388 BAIL_IF_MACRO(rc != 1, ERR_IO_ERROR, 0);
389
390 rc = SDL_RWread(rw, &fmt->fmt.adpcm.aCoef[i].iCoef2,
391 sizeof (fmt->fmt.adpcm.aCoef[i].iCoef2), 1);
392 BAIL_IF_MACRO(rc != 1, ERR_IO_ERROR, 0);
393 } /* for */
394 521
395 return(1); 522 return(1);
396 } /* read_fmt_adpcm */ 523 } /* read_fmt_adpcm */
397 524
398 525
445 */ 572 */
446 static int find_chunk(SDL_RWops *rw, Uint32 id) 573 static int find_chunk(SDL_RWops *rw, Uint32 id)
447 { 574 {
448 Sint32 siz = 0; 575 Sint32 siz = 0;
449 Uint32 _id = 0; 576 Uint32 _id = 0;
577 Uint32 pos = SDL_RWtell(rw);
450 578
451 while (1) 579 while (1)
452 { 580 {
453 BAIL_IF_MACRO(!read_le32(rw, &_id), NULL, 0); 581 BAIL_IF_MACRO(!read_le32(rw, &_id), NULL, 0);
454 if (_id == id) 582 if (_id == id)
455 return(1); 583 return(1);
456 584
457 /* skip ahead and see what next chunk is... */ 585 /* skip ahead and see what next chunk is... */
458 BAIL_IF_MACRO(!read_le32(rw, &siz), NULL, 0); 586 BAIL_IF_MACRO(!read_le32(rw, &siz), NULL, 0);
459 assert(siz > 0); 587 assert(siz >= 0);
460 BAIL_IF_MACRO(SDL_RWseek(rw, siz, SEEK_SET) != siz, NULL, 0); 588 pos += (sizeof (Uint32) * 2) + siz;
589 if (siz > 0)
590 BAIL_IF_MACRO(SDL_RWseek(rw, pos, SEEK_SET) != pos, NULL, 0);
461 } /* while */ 591 } /* while */
462 592
463 return(0); /* shouldn't hit this, but just in case... */ 593 return(0); /* shouldn't hit this, but just in case... */
464 } /* find_chunk */ 594 } /* find_chunk */
465 595
468 { 598 {
469 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; 599 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque;
470 SDL_RWops *rw = internal->rw; 600 SDL_RWops *rw = internal->rw;
471 data_t d; 601 data_t d;
472 wav_t *w; 602 wav_t *w;
603 Uint32 pos;
473 604
474 BAIL_IF_MACRO(SDL_ReadLE32(rw) != riffID, "WAV: Not a RIFF file.", 0); 605 BAIL_IF_MACRO(SDL_ReadLE32(rw) != riffID, "WAV: Not a RIFF file.", 0);
475 SDL_ReadLE32(rw); /* throw the length away; we get this info later. */ 606 SDL_ReadLE32(rw); /* throw the length away; we get this info later. */
476 BAIL_IF_MACRO(SDL_ReadLE32(rw) != waveID, "WAV: Not a WAVE file.", 0); 607 BAIL_IF_MACRO(SDL_ReadLE32(rw) != waveID, "WAV: Not a WAVE file.", 0);
477 BAIL_IF_MACRO(!find_chunk(rw, fmtID), "WAV: No format chunk.", 0); 608 BAIL_IF_MACRO(!find_chunk(rw, fmtID), "WAV: No format chunk.", 0);
478 BAIL_IF_MACRO(!read_fmt_chunk(rw, fmt), "WAV: Can't read format chunk.", 0); 609 BAIL_IF_MACRO(!read_fmt_chunk(rw, fmt), "WAV: Can't read format chunk.", 0);
479 610
480 sample->actual.channels = (Uint8) fmt->wChannels; 611 sample->actual.channels = (Uint8) fmt->wChannels;
481 sample->actual.rate = fmt->dwSamplesPerSec; 612 sample->actual.rate = fmt->dwSamplesPerSec;
482 if (fmt->wBitsPerSample <= 8) 613 if (fmt->wBitsPerSample == 4)
614 sample->actual.format = AUDIO_S16SYS; /* !!! FIXME ? */
615 else if (fmt->wBitsPerSample == 8)
483 sample->actual.format = AUDIO_U8; 616 sample->actual.format = AUDIO_U8;
484 else if (fmt->wBitsPerSample <= 16) 617 else if (fmt->wBitsPerSample == 16)
485 sample->actual.format = AUDIO_S16LSB; 618 sample->actual.format = AUDIO_S16LSB;
486 else 619 else
487 BAIL_MACRO("WAV: Unsupported sample size.", 0); 620 BAIL_MACRO("WAV: Unsupported sample size.", 0);
488 621
489 BAIL_IF_MACRO(!read_fmt(rw, fmt), NULL, 0); 622 BAIL_IF_MACRO(!read_fmt(rw, fmt), NULL, 0);
492 625
493 w = (wav_t *) malloc(sizeof(wav_t)); 626 w = (wav_t *) malloc(sizeof(wav_t));
494 BAIL_IF_MACRO(w == NULL, ERR_OUT_OF_MEMORY, 0); 627 BAIL_IF_MACRO(w == NULL, ERR_OUT_OF_MEMORY, 0);
495 w->fmt = fmt; 628 w->fmt = fmt;
496 w->bytesLeft = d.chunkSize; 629 w->bytesLeft = d.chunkSize;
630
631 /* !!! FIXME: Move this to Sound_SampleInfo ? */
632 fmt->sample_frame_size = ( ((sample->actual.format & 0xFF) / 8) *
633 sample->actual.channels );
634
497 internal->decoder_private = (void *) w; 635 internal->decoder_private = (void *) w;
498 636
499 sample->flags = SOUND_SAMPLEFLAG_NONE; 637 sample->flags = SOUND_SAMPLEFLAG_NONE;
500 638
501 SNDDBG(("WAV: Accepting data stream.\n")); 639 SNDDBG(("WAV: Accepting data stream.\n"));