comparison libblastem.c @ 1927:9fd4bedc1a31

Update libretro target to use render_audio shared audio code
author Mike Pavone <pavone@retrodev.com>
date Thu, 16 Apr 2020 22:37:01 -0700
parents 94f37e4b1469
children b387f1c5a1d0
comparison
equal deleted inserted replaced
1926:94f37e4b1469 1927:9fd4bedc1a31
46 RETRO_API void retro_set_video_refresh(retro_video_refresh_t rvf) 46 RETRO_API void retro_set_video_refresh(retro_video_refresh_t rvf)
47 { 47 {
48 retro_video_refresh = rvf; 48 retro_video_refresh = rvf;
49 } 49 }
50 50
51 static retro_audio_sample_t retro_audio_sample;
52 RETRO_API void retro_set_audio_sample(retro_audio_sample_t ras) 51 RETRO_API void retro_set_audio_sample(retro_audio_sample_t ras)
53 { 52 {
54 retro_audio_sample = ras; 53 }
55 } 54
56 55 static retro_audio_sample_batch_t retro_audio_sample_batch;
57 RETRO_API void retro_set_audio_sample_batch(retro_audio_sample_batch_t rasb) 56 RETRO_API void retro_set_audio_sample_batch(retro_audio_sample_batch_t rasb)
58 { 57 {
58 retro_audio_sample_batch = rasb;
59 } 59 }
60 60
61 static retro_input_poll_t retro_input_poll; 61 static retro_input_poll_t retro_input_poll;
62 RETRO_API void retro_set_input_poll(retro_input_poll_t rip) 62 RETRO_API void retro_set_input_poll(retro_input_poll_t rip)
63 { 63 {
79 system_header *current_system; 79 system_header *current_system;
80 system_media media; 80 system_media media;
81 81
82 RETRO_API void retro_init(void) 82 RETRO_API void retro_init(void)
83 { 83 {
84 render_audio_initialized(RENDER_AUDIO_S16, 53693175 / (7 * 6 * 4), 2, 4, sizeof(int16_t));
84 } 85 }
85 86
86 RETRO_API void retro_deinit(void) 87 RETRO_API void retro_deinit(void)
87 { 88 {
88 if (current_system) { 89 if (current_system) {
141 double master_clock = video_standard == VID_NTSC ? 53693175 : 53203395; 142 double master_clock = video_standard == VID_NTSC ? 53693175 : 53203395;
142 double lines = video_standard == VID_NTSC ? 262 : 313; 143 double lines = video_standard == VID_NTSC ? 262 : 313;
143 info->timing.fps = master_clock / (3420.0 * lines); 144 info->timing.fps = master_clock / (3420.0 * lines);
144 info->timing.sample_rate = master_clock / (7 * 6 * 24); //sample rate of YM2612 145 info->timing.sample_rate = master_clock / (7 * 6 * 24); //sample rate of YM2612
145 sample_rate = info->timing.sample_rate; 146 sample_rate = info->timing.sample_rate;
147 render_audio_initialized(RENDER_AUDIO_S16, info->timing.sample_rate, 2, 4, sizeof(int16_t));
148 //force adjustment of resampling parameters since target sample rate may have changed slightly
149 current_system->set_speed_percent(current_system, 100);
146 } 150 }
147 151
148 RETRO_API void retro_set_controller_port_device(unsigned port, unsigned device) 152 RETRO_API void retro_set_controller_port_device(unsigned port, unsigned device)
149 { 153 {
150 } 154 }
235 stype = detect_system_type(&media); 239 stype = detect_system_type(&media);
236 current_system = alloc_config_system(stype, &media, 0, 0); 240 current_system = alloc_config_system(stype, &media, 0, 0);
237 241
238 unsigned format = RETRO_PIXEL_FORMAT_XRGB8888; 242 unsigned format = RETRO_PIXEL_FORMAT_XRGB8888;
239 retro_environment(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &format); 243 retro_environment(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &format);
244
240 return current_system != NULL; 245 return current_system != NULL;
241 } 246 }
242 247
243 /* Loads a "special" kind of game. Should not be used, 248 /* Loads a "special" kind of game. Should not be used,
244 * except in extreme cases. */ 249 * except in extreme cases. */
439 } 444 }
440 void render_infobox(char *title, char *message) 445 void render_infobox(char *title, char *message)
441 { 446 {
442 } 447 }
443 448
444 typedef struct { 449 uint8_t render_is_audio_sync(void)
445 int32_t freq; 450 {
446 int32_t left_accum; 451 //whether this is true depends on the libretro frontend implementation
447 int32_t right_accum; 452 //but the sync to audio path works better here
448 int32_t num_samples; 453 return 1;
449 } audio_source; 454 }
450 455
451 static audio_source *audio_sources[8]; 456 void render_buffer_consumed(audio_source *src)
452 static uint8_t num_audio_sources; 457 {
453 audio_source *render_audio_source(uint64_t master_clock, uint64_t sample_divider, uint8_t channels) 458 }
454 { 459
455 audio_sources[num_audio_sources] = calloc(1, sizeof(audio_source)); 460 void *render_new_audio_opaque(void)
456 audio_sources[num_audio_sources]->freq = master_clock / sample_divider; 461 {
457 return audio_sources[num_audio_sources++]; 462 return NULL;
458 } 463 }
459 464
460 void render_audio_adjust_clock(audio_source *src, uint64_t master_clock, uint64_t sample_divider) 465 void render_free_audio_opaque(void *opaque)
461 { 466 {
462 } 467 }
463 468
464 void render_audio_source_gaindb(audio_source *src, float gain) 469 void render_lock_audio(void)
465 { 470 {
466 //TODO: Implement this once I hook up a core option for individual FM/PSG gain 471 }
467 } 472
468 473 void render_unlock_audio()
469 static void check_put_sample(void) 474 {
470 { 475 }
471 for (int i = 0; i < num_audio_sources; i++) 476
472 { 477 uint32_t render_min_buffered(void)
473 int32_t min_samples = audio_sources[i]->freq / sample_rate; 478 {
474 if (audio_sources[i]->num_samples < min_samples) { 479 //not actually used in the sync to audio path
475 return; 480 return 4;
476 } 481 }
477 } 482
478 int16_t left = 0, right = 0; 483 uint32_t render_audio_syncs_per_sec(void)
479 for (int i = 0; i < num_audio_sources; i++) 484 {
480 { 485 return 0;
481 left += audio_sources[i]->left_accum / audio_sources[i]->num_samples; 486 }
482 right += audio_sources[i]->right_accum / audio_sources[i]->num_samples; 487
483 audio_sources[i]->left_accum = audio_sources[i]->right_accum = audio_sources[i]->num_samples = 0; 488 void render_audio_created(audio_source *src)
484 } 489 {
485 retro_audio_sample(left, right); 490 }
486 } 491
487 492 void render_do_audio_ready(audio_source *src)
488 void render_put_mono_sample(audio_source *src, int16_t value) 493 {
489 { 494 int16_t *tmp = src->front;
490 src->left_accum += value; 495 src->front = src->back;
491 src->right_accum += value; 496 src->back = tmp;
492 src->num_samples++; 497 src->front_populated = 1;
493 check_put_sample(); 498 src->buffer_pos = 0;
494 } 499 if (all_sources_ready()) {
495 void render_put_stereo_sample(audio_source *src, int16_t left, int16_t right) 500 int16_t buffer[8];
496 { 501 int min_remaining_out;
497 src->left_accum += left; 502 mix_and_convert((uint8_t *)buffer, sizeof(buffer), &min_remaining_out);
498 src->right_accum += right; 503 retro_audio_sample_batch(buffer, sizeof(buffer)/(2*sizeof(*buffer)));
499 src->num_samples++; 504 }
500 check_put_sample(); 505 }
501 } 506
502 507 void render_source_paused(audio_source *src, uint8_t remaining_sources)
503 void render_free_source(audio_source *src) 508 {
504 { 509 }
505 int index; 510
506 for (index = 0; index < num_audio_sources; index++) 511 void render_source_resumed(audio_source *src)
507 { 512 {
508 if (audio_sources[index] == src) {
509 break;
510 }
511 }
512 num_audio_sources--;
513 audio_sources[index] = audio_sources[num_audio_sources];
514 free(src);
515 } 513 }
516 514
517 void bindings_set_mouse_mode(uint8_t mode) 515 void bindings_set_mouse_mode(uint8_t mode)
518 { 516 {
519 } 517 }