Mercurial > repos > blastem
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 } |