Mercurial > SDL_sound_CoreAudio
comparison decoders/wav.c @ 333:565ae12fa74e
Implemented seek support for ADPCM-compressed WAVs.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Mon, 20 May 2002 11:19:50 +0000 |
parents | eb7c929193dd |
children | 069ce624d6cf |
comparison
equal
deleted
inserted
replaced
332:8ba541e81c1e | 333:565ae12fa74e |
---|---|
525 } /* rewind_sample_fmt_adpcm */ | 525 } /* rewind_sample_fmt_adpcm */ |
526 | 526 |
527 | 527 |
528 static int seek_sample_fmt_adpcm(Sound_Sample *sample, Uint32 ms) | 528 static int seek_sample_fmt_adpcm(Sound_Sample *sample, Uint32 ms) |
529 { | 529 { |
530 return(0); /* !!! FIXME: Can we reasonably implement this? */ | 530 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
531 wav_t *w = (wav_t *) internal->decoder_private; | |
532 fmt_t *fmt = w->fmt; | |
533 Uint32 origsampsleft = fmt->fmt.adpcm.samples_left_in_block; | |
534 int origpos = SDL_RWtell(internal->rw); | |
535 int offset = __Sound_convertMsToBytePos(&sample->actual, ms); | |
536 int bpb = (fmt->fmt.adpcm.wSamplesPerBlock * fmt->sample_frame_size); | |
537 int skipsize = (offset / bpb) * fmt->wBlockAlign; | |
538 int pos = skipsize + fmt->data_starting_offset; | |
539 int rc = SDL_RWseek(internal->rw, pos, SEEK_SET); | |
540 BAIL_IF_MACRO(rc != pos, ERR_IO_ERROR, 0); | |
541 | |
542 /* The offset we need is in this block, so we need to decode to there. */ | |
543 skipsize += (offset % bpb); | |
544 rc = (offset % bpb); /* bytes into this block we need to decode */ | |
545 if (!read_adpcm_block_headers(sample)) | |
546 { | |
547 SDL_RWseek(internal->rw, origpos, SEEK_SET); /* try to make sane. */ | |
548 return(0); | |
549 } /* if */ | |
550 | |
551 /* first sample frame of block is a freebie. :) */ | |
552 fmt->fmt.adpcm.samples_left_in_block--; | |
553 rc -= fmt->sample_frame_size; | |
554 while (rc > 0) | |
555 { | |
556 if (!decode_adpcm_sample_frame(sample)) | |
557 { | |
558 SDL_RWseek(internal->rw, origpos, SEEK_SET); | |
559 fmt->fmt.adpcm.samples_left_in_block = origsampsleft; | |
560 return(0); | |
561 } /* if */ | |
562 | |
563 fmt->fmt.adpcm.samples_left_in_block--; | |
564 rc -= fmt->sample_frame_size; | |
565 } /* while */ | |
566 | |
567 w->bytesLeft = fmt->total_bytes - skipsize; | |
568 return(1); /* success. */ | |
531 } /* seek_sample_fmt_adpcm */ | 569 } /* seek_sample_fmt_adpcm */ |
532 | 570 |
533 | 571 |
534 /* | 572 /* |
535 * Read in the adpcm-specific info from disk. This makes this process | 573 * Read in the adpcm-specific info from disk. This makes this process |
542 | 580 |
543 memset(&fmt->fmt.adpcm, '\0', sizeof (fmt->fmt.adpcm)); | 581 memset(&fmt->fmt.adpcm, '\0', sizeof (fmt->fmt.adpcm)); |
544 fmt->free = free_fmt_adpcm; | 582 fmt->free = free_fmt_adpcm; |
545 fmt->read_sample = read_sample_fmt_adpcm; | 583 fmt->read_sample = read_sample_fmt_adpcm; |
546 fmt->rewind_sample = rewind_sample_fmt_adpcm; | 584 fmt->rewind_sample = rewind_sample_fmt_adpcm; |
585 fmt->seek_sample = seek_sample_fmt_adpcm; | |
547 | 586 |
548 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.cbSize), NULL, 0); | 587 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.cbSize), NULL, 0); |
549 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.wSamplesPerBlock), NULL, 0); | 588 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.wSamplesPerBlock), NULL, 0); |
550 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.wNumCoef), NULL, 0); | 589 BAIL_IF_MACRO(!read_le16(rw, &fmt->fmt.adpcm.wNumCoef), NULL, 0); |
551 | 590 |
675 w = (wav_t *) malloc(sizeof(wav_t)); | 714 w = (wav_t *) malloc(sizeof(wav_t)); |
676 BAIL_IF_MACRO(w == NULL, ERR_OUT_OF_MEMORY, 0); | 715 BAIL_IF_MACRO(w == NULL, ERR_OUT_OF_MEMORY, 0); |
677 w->fmt = fmt; | 716 w->fmt = fmt; |
678 fmt->total_bytes = w->bytesLeft = d.chunkSize; | 717 fmt->total_bytes = w->bytesLeft = d.chunkSize; |
679 fmt->data_starting_offset = SDL_RWtell(rw); | 718 fmt->data_starting_offset = SDL_RWtell(rw); |
680 | |
681 /* !!! FIXME: Move this to Sound_SampleInfo ? */ | |
682 fmt->sample_frame_size = ( ((sample->actual.format & 0xFF) / 8) * | 719 fmt->sample_frame_size = ( ((sample->actual.format & 0xFF) / 8) * |
683 sample->actual.channels ); | 720 sample->actual.channels ); |
684 | 721 |
685 internal->decoder_private = (void *) w; | 722 internal->decoder_private = (void *) w; |
686 | 723 |
687 sample->flags = SOUND_SAMPLEFLAG_NONE; | 724 sample->flags = SOUND_SAMPLEFLAG_NONE; |
688 if (fmt->wFormatTag == FMT_NORMAL) | 725 if (fmt->seek_sample != NULL) |
689 sample->flags |= SOUND_SAMPLEFLAG_CANSEEK; | 726 sample->flags |= SOUND_SAMPLEFLAG_CANSEEK; |
690 | 727 |
691 SNDDBG(("WAV: Accepting data stream.\n")); | 728 SNDDBG(("WAV: Accepting data stream.\n")); |
692 return(1); /* we'll handle this data. */ | 729 return(1); /* we'll handle this data. */ |
693 } /* WAV_open_internal */ | 730 } /* WAV_open_internal */ |