comparison mediaplayer.c @ 2290:c4980d89614b

Support WAVE files in media player
author Michael Pavone <pavone@retrodev.com>
date Sat, 04 Feb 2023 23:31:11 -0800
parents 92449b47cce8
children 789802d99629
comparison
equal deleted inserted replaced
2289:92449b47cce8 2290:c4980d89614b
408 } 408 }
409 } 409 }
410 410
411 void wave_frame(media_player *player) 411 void wave_frame(media_player *player)
412 { 412 {
413 render_sleep_ms(15); 413 for (uint32_t remaining_samples = player->wave->sample_rate / 60; remaining_samples > 0; remaining_samples--)
414 {
415 uint32_t sample_size = player->wave->bits_per_sample * player->wave->num_channels / 8;
416 if (sample_size > player->media->size || player->current_offset > player->media->size - sample_size) {
417 player->current_offset = player->wave->format_header.size + offsetof(wave_header, audio_format);
418 player->state = STATE_PAUSED;
419 return;
420 }
421 if (player->wave->bits_per_sample == 16) {
422 int16_t value = read_word_le(player);
423 if (player->wave->num_channels == 1) {
424 render_put_mono_sample(player->audio, value);
425 } else {
426 int16_t right = read_word_le(player);
427 render_put_stereo_sample(player->audio, value, right);
428 }
429 } else {
430 uint8_t sample = read_byte(player);
431 int16_t value = sample * 257 - 128 * 257;
432 if (player->wave->num_channels == 1) {
433 render_put_mono_sample(player->audio, value);
434 } else {
435 sample = read_byte(player);
436 int16_t right = sample * 257 - 128 * 257;
437 render_put_stereo_sample(player->audio, value, right);
438 }
439 }
440
441 }
414 } 442 }
415 443
416 void flac_frame(media_player *player) 444 void flac_frame(media_player *player)
417 { 445 {
418 render_sleep_ms(15); 446 render_sleep_ms(15);
509 }; 537 };
510 } 538 }
511 player->current_offset = player->vgm->data_offset + offsetof(vgm_header, data_offset); 539 player->current_offset = player->vgm->data_offset + offsetof(vgm_header, data_offset);
512 } 540 }
513 541
542 static void wave_player_init(media_player *player)
543 {
544 player->wave = calloc(1, sizeof(wave_header));
545 memcpy(player->wave, player->media->buffer, offsetof(wave_header, data_header));
546 if (memcmp(player->wave->chunk.format, "WAVE", 4)) {
547 goto format_error;
548 }
549 if (player->wave->chunk.size < offsetof(wave_header, data_header)) {
550 goto format_error;
551 }
552 if (memcmp(player->wave->format_header.id, "fmt ", 4)) {
553 goto format_error;
554 }
555 if (player->wave->format_header.size < offsetof(wave_header, data_header) - offsetof(wave_header, audio_format)) {
556 goto format_error;
557 }
558 if (player->wave->bits_per_sample != 8 && player->wave->bits_per_sample != 16) {
559 goto format_error;
560 }
561 uint32_t data_sub_chunk = player->wave->format_header.size + offsetof(wave_header, audio_format);
562 if (data_sub_chunk > player->media->size || player->media->size - data_sub_chunk < sizeof(riff_sub_chunk)) {
563 goto format_error;
564 }
565 memcpy(&player->wave->data_header, ((uint8_t *)player->media->buffer) + data_sub_chunk, sizeof(riff_sub_chunk));
566 player->current_offset = data_sub_chunk;
567 player->audio = render_audio_source("Audio File", player->wave->sample_rate, 1, player->wave->num_channels);
568 return;
569 format_error:
570 player->media_type = MEDIA_UNKNOWN;
571 free(player->wave);
572 }
573
514 static void resume_player(system_header *system) 574 static void resume_player(system_header *system)
515 { 575 {
516 media_player *player = (media_player *)system; 576 media_player *player = (media_player *)system;
517 player->should_return = 0; 577 player->should_return = 0;
518 while (!player->header.should_exit && !player->should_return) 578 while (!player->header.should_exit && !player->should_return)
587 return MEDIA_UNKNOWN; 647 return MEDIA_UNKNOWN;
588 } 648 }
589 return AUDIO_VGM; 649 return AUDIO_VGM;
590 } 650 }
591 if (!memcmp(media->buffer, "RIFF", 4)) { 651 if (!memcmp(media->buffer, "RIFF", 4)) {
652 if (media->size < sizeof(wave_header)) {
653 return MEDIA_UNKNOWN;
654 }
592 return AUDIO_WAVE; 655 return AUDIO_WAVE;
593 } 656 }
594 if (!memcmp(media->buffer, "fLaC", 4)) { 657 if (!memcmp(media->buffer, "fLaC", 4)) {
595 return AUDIO_FLAC; 658 return AUDIO_FLAC;
596 } 659 }
621 switch (player->media_type) 684 switch (player->media_type)
622 { 685 {
623 case AUDIO_VGM: 686 case AUDIO_VGM:
624 vgm_init(player, opts); 687 vgm_init(player, opts);
625 break; 688 break;
689 case AUDIO_WAVE:
690 wave_player_init(player);
691 break;
626 } 692 }
627 693
628 return player; 694 return player;
629 } 695 }