Mercurial > SDL_sound_CoreAudio
comparison decoders/voc.c @ 335:f6475949cd59
Implemented seek method.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Mon, 20 May 2002 12:11:55 +0000 |
parents | c97be6e1bd27 |
children | cbb15ecf423a |
comparison
equal
deleted
inserted
replaced
334:f0f894d897bf | 335:f6475949cd59 |
---|---|
378 continue; /* get next block */ | 378 continue; /* get next block */ |
379 } | 379 } |
380 } | 380 } |
381 | 381 |
382 return 1; | 382 return 1; |
383 } | 383 } /* voc_get_block */ |
384 | 384 |
385 | 385 |
386 static int voc_read_waveform(Sound_Sample *sample) | 386 static int voc_read_waveform(Sound_Sample *sample, int fill_buf, Uint32 max) |
387 { | 387 { |
388 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | 388 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; |
389 SDL_RWops *src = internal->rw; | 389 SDL_RWops *src = internal->rw; |
390 vs_t *v = (vs_t *) internal->decoder_private; | 390 vs_t *v = (vs_t *) internal->decoder_private; |
391 int done = 0; | 391 int done = 0; |
394 | 394 |
395 if (v->rest == 0) | 395 if (v->rest == 0) |
396 { | 396 { |
397 if (!voc_get_block(sample)) | 397 if (!voc_get_block(sample)) |
398 return 0; | 398 return 0; |
399 } | 399 } /* if */ |
400 | 400 |
401 if (v->rest == 0) | 401 if (v->rest == 0) |
402 return 0; | 402 return 0; |
403 | 403 |
404 max = (v->rest < max) ? v->rest : max; | |
405 | |
404 if (v->silent) | 406 if (v->silent) |
405 { | 407 { |
406 if (v->size == ST_SIZE_WORD) | 408 if (v->size == ST_SIZE_WORD) |
407 silence = 0x00; | 409 silence = 0x00; |
408 | 410 |
409 /* Fill in silence */ | 411 /* Fill in silence */ |
410 memset(buf, silence, v->rest); | 412 if (fill_buf) |
411 done = v->rest; | 413 memset(buf + v->bufpos, silence, max); |
412 v->rest = 0; | 414 |
413 } | 415 done = max; |
416 v->rest -= done; | |
417 } /* if */ | |
414 | 418 |
415 else | 419 else |
416 { | 420 { |
417 Uint32 max = (v->rest < internal->buffer_size) ? | 421 if (fill_buf) |
418 v->rest : internal->buffer_size; | 422 done = SDL_RWread(src, buf + v->bufpos, 1, max); |
419 done = SDL_RWread(src, buf + v->bufpos, 1, max); | 423 else |
424 { | |
425 int cur, rc; | |
426 cur = SDL_RWtell(src); | |
427 if (cur >= 0) | |
428 { | |
429 rc = SDL_RWseek(src, max, SEEK_CUR); | |
430 if (rc >= 0) | |
431 done = rc - cur; | |
432 } /* if */ | |
433 } /* else */ | |
434 | |
420 v->rest -= done; | 435 v->rest -= done; |
421 v->bufpos += done; | 436 v->bufpos += done; |
422 } | 437 } /* else */ |
423 | 438 |
424 return done; | 439 return done; |
425 } /* voc_read_waveform */ | 440 } /* voc_read_waveform */ |
426 | 441 |
427 | 442 |
454 } /* if */ | 469 } /* if */ |
455 | 470 |
456 SNDDBG(("VOC: Accepting data stream.\n")); | 471 SNDDBG(("VOC: Accepting data stream.\n")); |
457 sample->actual.format = (v->size == ST_SIZE_WORD) ? AUDIO_S16LSB:AUDIO_U8; | 472 sample->actual.format = (v->size == ST_SIZE_WORD) ? AUDIO_S16LSB:AUDIO_U8; |
458 sample->actual.channels = v->channels; | 473 sample->actual.channels = v->channels; |
459 sample->flags = SOUND_SAMPLEFLAG_NONE; | 474 sample->flags = SOUND_SAMPLEFLAG_CANSEEK; |
460 return(1); | 475 return(1); |
461 } /* VOC_open */ | 476 } /* VOC_open */ |
462 | 477 |
463 | 478 |
464 static void VOC_close(Sound_Sample *sample) | 479 static void VOC_close(Sound_Sample *sample) |
474 vs_t *v = (vs_t *) internal->decoder_private; | 489 vs_t *v = (vs_t *) internal->decoder_private; |
475 | 490 |
476 v->bufpos = 0; | 491 v->bufpos = 0; |
477 while (v->bufpos < internal->buffer_size) | 492 while (v->bufpos < internal->buffer_size) |
478 { | 493 { |
479 Uint32 rc = voc_read_waveform(sample); | 494 Uint32 rc = voc_read_waveform(sample, 1, internal->buffer_size); |
480 if (rc == 0) /* !!! FIXME: Could be an error... */ | 495 if (rc == 0) /* !!! FIXME: Could be an error... */ |
481 { | 496 { |
482 sample->flags |= SOUND_SAMPLEFLAG_EOF; | 497 sample->flags |= SOUND_SAMPLEFLAG_EOF; |
483 break; | 498 break; |
484 } /* if */ | 499 } /* if */ |
505 } /* VOC_rewind */ | 520 } /* VOC_rewind */ |
506 | 521 |
507 | 522 |
508 static int VOC_seek(Sound_Sample *sample, Uint32 ms) | 523 static int VOC_seek(Sound_Sample *sample, Uint32 ms) |
509 { | 524 { |
510 BAIL_MACRO("!!! FIXME: Not implemented", 0); | 525 /* |
526 * VOCs don't lend themselves well to seeking, since you have to | |
527 * parse each section, which is an arbitrary size. The best we can do | |
528 * is rewind, set a flag saying not to write the waveforms to a buffer, | |
529 * and decode to the point that we want. Ugh. Fortunately, there's | |
530 * really no such thing as a large VOC, due to the era and hardware that | |
531 * spawned them, so even though this is inefficient, this is still a | |
532 * relatively fast operation in most cases. | |
533 */ | |
534 | |
535 Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; | |
536 vs_t *v = (vs_t *) internal->decoder_private; | |
537 int offset = __Sound_convertMsToBytePos(&sample->actual, ms); | |
538 int origpos = SDL_RWtell(internal->rw); | |
539 int origrest = v->rest; | |
540 | |
541 BAIL_IF_MACRO(!VOC_rewind(sample), NULL, 0); | |
542 | |
543 v->bufpos = 0; | |
544 | |
545 while (offset > 0) | |
546 { | |
547 Uint32 rc = voc_read_waveform(sample, 0, offset); | |
548 if ( (rc == 0) || (!voc_get_block(sample)) ) | |
549 { | |
550 SDL_RWseek(internal->rw, origpos, SEEK_SET); | |
551 v->rest = origrest; | |
552 return(0); | |
553 } /* if */ | |
554 | |
555 offset -= rc; | |
556 } /* while */ | |
557 | |
558 return(1); | |
511 } /* VOC_seek */ | 559 } /* VOC_seek */ |
512 | 560 |
513 | |
514 #endif /* SOUND_SUPPORTS_VOC */ | 561 #endif /* SOUND_SUPPORTS_VOC */ |
515 | 562 |
516 /* end of voc.c ... */ | 563 /* end of voc.c ... */ |