comparison render_sdl.c @ 1590:220ede292e97

Initial attempt at handling switches between sync modes at runtime. Needs work
author Michael Pavone <pavone@retrodev.com>
date Thu, 21 Jun 2018 09:44:34 -0700
parents 780604a036e4
children 5cfc7e4a207e
comparison
equal deleted inserted replaced
1589:780604a036e4 1590:220ede292e97
61 uint8_t num_channels; 61 uint8_t num_channels;
62 uint8_t front_populated; 62 uint8_t front_populated;
63 }; 63 };
64 64
65 static audio_source *audio_sources[8]; 65 static audio_source *audio_sources[8];
66 static audio_source *inactive_audio_sources[8];
66 static uint8_t num_audio_sources; 67 static uint8_t num_audio_sources;
68 static uint8_t num_inactive_audio_sources;
67 static uint8_t sync_to_audio; 69 static uint8_t sync_to_audio;
68 static uint32_t min_buffered; 70 static uint32_t min_buffered;
69 71
70 typedef int32_t (*mix_func)(audio_source *audio, void *vstream, int len); 72 typedef int32_t (*mix_func)(audio_source *audio, void *vstream, int len);
71 73
296 } 298 }
297 unlock_audio(); 299 unlock_audio();
298 if (need_pause) { 300 if (need_pause) {
299 SDL_PauseAudio(1); 301 SDL_PauseAudio(1);
300 } 302 }
303 inactive_audio_sources[num_inactive_audio_sources++] = src;
301 } 304 }
302 305
303 void render_resume_source(audio_source *src) 306 void render_resume_source(audio_source *src)
304 { 307 {
305 lock_audio(); 308 lock_audio();
306 if (num_audio_sources < 8) { 309 if (num_audio_sources < 8) {
307 audio_sources[num_audio_sources++] = src; 310 audio_sources[num_audio_sources++] = src;
308 } 311 }
309 unlock_audio(); 312 unlock_audio();
313 for (uint8_t i = 0; i < num_inactive_audio_sources; i++)
314 {
315 if (inactive_audio_sources[i] == src) {
316 inactive_audio_sources[i] = inactive_audio_sources[--num_inactive_audio_sources];
317 }
318 }
310 if (sync_to_audio) { 319 if (sync_to_audio) {
311 SDL_PauseAudio(0); 320 SDL_PauseAudio(0);
312 } 321 }
313 } 322 }
314 323
1106 1115
1107 atexit(render_quit); 1116 atexit(render_quit);
1108 } 1117 }
1109 #include<unistd.h> 1118 #include<unistd.h>
1110 static int in_toggle; 1119 static int in_toggle;
1120 static void update_source(audio_source *src, double rc, uint8_t sync_changed)
1121 {
1122 double alpha = src->dt / (src->dt + rc);
1123 int32_t lowpass_alpha = (int32_t)(((double)0x10000) * alpha);
1124 src->lowpass_alpha = lowpass_alpha;
1125 if (sync_changed) {
1126 uint32_t alloc_size = sync_to_audio ? src->num_channels * buffer_samples : nearest_pow2(min_buffered * 4 * src->num_channels);
1127 src->back = realloc(src->back, alloc_size);
1128 if (sync_to_audio) {
1129 src->front = malloc(alloc_size * sizeof(int16_t));
1130 } else {
1131 free(src->front);
1132 src->front = src->back;
1133 }
1134 src->mask = sync_to_audio ? 0xFFFFFFFF : alloc_size-1;
1135 src->read_start = 0;
1136 src->read_end = sync_to_audio ? buffer_samples * src->num_channels : 0;
1137 src->buffer_pos = 0;
1138 }
1139 }
1140
1111 void render_config_updated(void) 1141 void render_config_updated(void)
1112 { 1142 {
1113 uint8_t old_sync_to_audio = sync_to_audio; 1143 uint8_t old_sync_to_audio = sync_to_audio;
1114 1144
1115 free_surfaces(); 1145 free_surfaces();
1164 1194
1165 uint8_t was_paused = SDL_GetAudioStatus() == SDL_AUDIO_PAUSED; 1195 uint8_t was_paused = SDL_GetAudioStatus() == SDL_AUDIO_PAUSED;
1166 render_close_audio(); 1196 render_close_audio();
1167 quitting = 0; 1197 quitting = 0;
1168 init_audio(); 1198 init_audio();
1169 if (!was_paused) { 1199 render_set_video_standard(video_standard);
1170 SDL_PauseAudio(0);
1171 }
1172 1200
1173 double lowpass_cutoff = get_lowpass_cutoff(config); 1201 double lowpass_cutoff = get_lowpass_cutoff(config);
1174 double rc = (1.0 / lowpass_cutoff) / (2.0 * M_PI); 1202 double rc = (1.0 / lowpass_cutoff) / (2.0 * M_PI);
1175 lock_audio(); 1203 lock_audio();
1176 for (uint8_t i = 0; i < num_audio_sources; i++) 1204 for (uint8_t i = 0; i < num_audio_sources; i++)
1177 { 1205 {
1178 double alpha = audio_sources[i]->dt / (audio_sources[i]->dt + rc); 1206 update_source(audio_sources[i], rc, old_sync_to_audio != sync_to_audio);
1179 int32_t lowpass_alpha = (int32_t)(((double)0x10000) * alpha);
1180 audio_sources[i]->lowpass_alpha = lowpass_alpha;
1181 } 1207 }
1182 unlock_audio(); 1208 unlock_audio();
1209 for (uint8_t i = 0; i < num_inactive_audio_sources; i++)
1210 {
1211 update_source(inactive_audio_sources[i], rc, old_sync_to_audio != sync_to_audio);
1212 }
1183 drain_events(); 1213 drain_events();
1184 in_toggle = 0; 1214 in_toggle = 0;
1215 if (!was_paused) {
1216 SDL_PauseAudio(0);
1217 }
1185 } 1218 }
1186 1219
1187 SDL_Window *render_get_window(void) 1220 SDL_Window *render_get_window(void)
1188 { 1221 {
1189 return main_window; 1222 return main_window;