Mercurial > repos > blastem
comparison render_sdl.c @ 2640:c30e5548154f
Get sync to audio working in emscripten
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 26 Feb 2025 22:55:42 -0800 |
parents | f5603b4ee14d |
children | c5c9498ff279 |
comparison
equal
deleted
inserted
replaced
2639:0046305e3fa8 | 2640:c30e5548154f |
---|---|
24 #include <SDL_opengles2.h> | 24 #include <SDL_opengles2.h> |
25 #else | 25 #else |
26 #include <GL/glew.h> | 26 #include <GL/glew.h> |
27 #endif | 27 #endif |
28 #endif | 28 #endif |
29 #ifdef __EMSCRIPTEN__ | |
30 #include <emscripten.h> | |
31 #endif | |
29 | 32 |
30 #define MAX_EVENT_POLL_PER_FRAME 2 | 33 #define MAX_EVENT_POLL_PER_FRAME 2 |
31 | 34 |
32 | 35 |
33 typedef struct { | 36 typedef struct { |
121 | 124 |
122 static void audio_callback(void * userdata, uint8_t *byte_stream, int len) | 125 static void audio_callback(void * userdata, uint8_t *byte_stream, int len) |
123 { | 126 { |
124 SDL_LockMutex(audio_mutex); | 127 SDL_LockMutex(audio_mutex); |
125 uint8_t all_ready; | 128 uint8_t all_ready; |
129 #ifdef __EMSCRIPTEN__ | |
130 if (!all_sources_ready()) { | |
131 memset(byte_stream, 0, len); | |
132 SDL_UnlockMutex(audio_mutex); | |
133 return; | |
134 } | |
135 #else | |
126 do { | 136 do { |
127 all_ready = all_sources_ready(); | 137 all_ready = all_sources_ready(); |
128 if (!quitting && !all_ready) { | 138 if (!quitting && !all_ready) { |
129 SDL_CondWait(audio_ready, audio_mutex); | 139 SDL_CondWait(audio_ready, audio_mutex); |
130 } | 140 } |
131 } while(!quitting && !all_ready); | 141 } while(!quitting && !all_ready); |
142 #endif | |
132 if (!quitting) { | 143 if (!quitting) { |
133 mix_and_convert(byte_stream, len, NULL); | 144 mix_and_convert(byte_stream, len, NULL); |
134 } | 145 } |
135 SDL_UnlockMutex(audio_mutex); | 146 SDL_UnlockMutex(audio_mutex); |
136 } | 147 } |
253 } | 264 } |
254 } | 265 } |
255 | 266 |
256 uint8_t audio_deadlock_hack(void); | 267 uint8_t audio_deadlock_hack(void); |
257 | 268 |
269 static ui_render_fun audio_full_cb; | |
270 void render_set_audio_full_fun(ui_render_fun cb) | |
271 { | |
272 audio_full_cb = cb; | |
273 } | |
274 | |
258 void render_do_audio_ready(audio_source *src) | 275 void render_do_audio_ready(audio_source *src) |
259 { | 276 { |
260 if (sync_src == SYNC_AUDIO_THREAD) { | 277 if (sync_src == SYNC_AUDIO_THREAD) { |
261 int16_t *tmp = src->front; | 278 int16_t *tmp = src->front; |
262 src->front = src->back; | 279 src->front = src->back; |
266 if (all_sources_ready()) { | 283 if (all_sources_ready()) { |
267 //we've emulated far enough to fill the current buffer | 284 //we've emulated far enough to fill the current buffer |
268 system_request_exit(current_system, 0); | 285 system_request_exit(current_system, 0); |
269 } | 286 } |
270 } else if (sync_src == SYNC_AUDIO) { | 287 } else if (sync_src == SYNC_AUDIO) { |
288 uint8_t all_ready = 0; | |
271 SDL_LockMutex(audio_mutex); | 289 SDL_LockMutex(audio_mutex); |
290 #ifndef __EMSCRIPTEN__ | |
272 if (src->front_populated) { | 291 if (src->front_populated) { |
273 if (audio_deadlock_hack()) { | 292 if (audio_deadlock_hack()) { |
274 SDL_CondSignal(audio_ready); | 293 SDL_CondSignal(audio_ready); |
275 } | 294 } |
276 } | 295 } |
277 while (src->front_populated) { | 296 while (src->front_populated) { |
278 SDL_CondWait(src->opaque, audio_mutex); | 297 SDL_CondWait(src->opaque, audio_mutex); |
279 } | 298 } |
299 #endif | |
280 int16_t *tmp = src->front; | 300 int16_t *tmp = src->front; |
281 src->front = src->back; | 301 src->front = src->back; |
282 src->back = tmp; | 302 src->back = tmp; |
283 src->front_populated = 1; | 303 src->front_populated = 1; |
284 src->buffer_pos = 0; | 304 src->buffer_pos = 0; |
305 all_ready = all_sources_ready(); | |
285 SDL_CondSignal(audio_ready); | 306 SDL_CondSignal(audio_ready); |
286 SDL_UnlockMutex(audio_mutex); | 307 SDL_UnlockMutex(audio_mutex); |
308 if (all_ready && audio_full_cb) { | |
309 audio_full_cb(); | |
310 } | |
287 } else { | 311 } else { |
288 uint32_t num_buffered; | 312 uint32_t num_buffered; |
289 SDL_LockAudio(); | 313 SDL_LockAudio(); |
290 src->read_end = src->buffer_pos; | 314 src->read_end = src->buffer_pos; |
291 num_buffered = ((src->read_end - src->read_start) & src->mask) / src->num_channels; | 315 num_buffered = ((src->read_end - src->read_start) & src->mask) / src->num_channels; |
1068 format = RENDER_AUDIO_FLOAT; | 1092 format = RENDER_AUDIO_FLOAT; |
1069 } else { | 1093 } else { |
1070 debug_message("unsupported format %X\n", actual.format); | 1094 debug_message("unsupported format %X\n", actual.format); |
1071 warning("Unsupported audio sample format: %X\n", actual.format); | 1095 warning("Unsupported audio sample format: %X\n", actual.format); |
1072 } | 1096 } |
1097 #ifdef __EMSCRIPTEN__ | |
1098 if (sync_src == SYNC_AUDIO) { | |
1099 printf("emscripten_set_main_loop_timing %d\n", actual.samples * 500 / actual.freq); | |
1100 emscripten_set_main_loop_timing(EM_TIMING_SETTIMEOUT, actual.samples * 500 / actual.freq); | |
1101 } | |
1102 #endif | |
1073 render_audio_initialized(format, actual.freq, actual.channels, actual.samples, SDL_AUDIO_BITSIZE(actual.format) / 8); | 1103 render_audio_initialized(format, actual.freq, actual.channels, actual.samples, SDL_AUDIO_BITSIZE(actual.format) / 8); |
1074 } | 1104 } |
1075 | 1105 |
1076 static void update_cursor(void) | 1106 static void update_cursor(void) |
1077 { | 1107 { |