4848
4949#define AX_MAIN_AFFINITY OS_THREAD_ATTRIB_AFFINITY_CPU1
5050
51- #define WIIU_DEVICE_TV 0
52- #define WIIU_DEVICE_GAMEPAD 1
53- #define WIIU_DEVICE_MIRRORED 2
51+ #define WIIU_DEVICE_TV 1
52+ #define WIIU_DEVICE_GAMEPAD 2
53+ #define WIIU_DEVICE_MIRRORED 3
5454#define WIIU_MAX_DEVICES 3
5555
56- static int mirroredHandle ;
57- static int tvHandle ;
58- static int drcHandle ;
59-
6056static void _WIIUAUDIO_framecallback ();
6157static SDL_AudioDevice * wiiuDevices [WIIU_MAX_DEVICES ];
6258static int deviceType ;
6359static int deviceCount ;
6460
61+ // Protects wiiuDevices/deviceCount during device open/close while the frame callback is running
62+ static SDL_SpinLock deviceListLock = 0 ;
6563/* Some helpers for AX-related math */
6664/* Absolute address to an AXVoiceOffsets offset */
6765#define calc_ax_offset (offs , addr ) (((void*)addr - offs.data) \
@@ -255,8 +253,10 @@ static int _WIIUAUDIO_OpenDeviceFunction(_THIS) {
255253 AXVoiceEnd (this -> hidden -> voice [i ]);
256254 }
257255
256+ SDL_AtomicLock (& deviceListLock );
258257 wiiuDevices [deviceCount ] = this ;
259258 deviceCount ++ ;
259+ SDL_AtomicUnlock (& deviceListLock );
260260
261261 return 0 ;
262262}
@@ -279,9 +279,9 @@ static void WIIUAUDIO_DetectDevices(void) {
279279
280280 SDL_CalculateAudioSpec (& spec );
281281
282- SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_MIRRORED , & spec , & mirroredHandle );
283- SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_TV , & spec , & tvHandle );
284- SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_GAMEPAD , & spec , & drcHandle );
282+ SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_MIRRORED , & spec , ( void * ) WIIU_DEVICE_MIRRORED );
283+ SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_TV , & spec , ( void * ) WIIU_DEVICE_TV );
284+ SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_GAMEPAD , & spec , ( void * ) WIIU_DEVICE_GAMEPAD );
285285}
286286
287287static int WIIUAUDIO_OpenDevice (_THIS , const char * devname ) {
@@ -293,10 +293,10 @@ static int WIIUAUDIO_OpenDevice(_THIS, const char *devname) {
293293
294294 deviceType = WIIU_DEVICE_MIRRORED ;
295295
296- if (this -> handle == & tvHandle ) {
296+ if (this -> handle == ( void * ) WIIU_DEVICE_TV ) {
297297 deviceType = WIIU_DEVICE_TV ;
298298 }
299- else if (this -> handle == & drcHandle ) {
299+ else if (this -> handle == ( void * ) WIIU_DEVICE_GAMEPAD ) {
300300 deviceType = WIIU_DEVICE_GAMEPAD ;
301301 }
302302
@@ -348,8 +348,18 @@ static int WIIUAUDIO_OpenDevice(_THIS, const char *devname) {
348348
349349/* Called every 3ms before a frame of audio is rendered. Keep it fast! */
350350static void _WIIUAUDIO_framecallback () {
351- for (int deviceIndex = 0 ; deviceIndex < deviceCount ; ++ deviceIndex ) {
352- SDL_AudioDevice * dev = wiiuDevices [deviceIndex ];
351+ SDL_AudioDevice * local [WIIU_MAX_DEVICES ];
352+ int count ;
353+
354+ SDL_AtomicLock (& deviceListLock );
355+ count = deviceCount ;
356+ for (int i = 0 ; i < count ; i ++ ) {
357+ local [i ] = wiiuDevices [i ];
358+ }
359+ SDL_AtomicUnlock (& deviceListLock );
360+
361+ for (int deviceIndex = 0 ; deviceIndex < count ; ++ deviceIndex ) {
362+ SDL_AudioDevice * dev = local [deviceIndex ];
353363
354364 int playing_buffer = -1 ;
355365 AXVoiceOffsets offs [6 ];
@@ -492,7 +502,18 @@ static void WIIUAUDIO_CloseDevice(_THIS) {
492502 if (this -> hidden -> deintvbuf ) SDL_free (this -> hidden -> deintvbuf );
493503 SDL_free (this -> hidden );
494504
495- deviceCount -- ;
505+ SDL_AtomicLock (& deviceListLock );
506+ for (int i = 0 ; i < deviceCount ; ++ i ) {
507+ if (wiiuDevices [i ] == this ) {
508+ for (int j = i ; j < deviceCount - 1 ; ++ j ) {
509+ wiiuDevices [j ] = wiiuDevices [j + 1 ];
510+ }
511+ wiiuDevices [deviceCount - 1 ] = NULL ;
512+ deviceCount -- ;
513+ break ;
514+ }
515+ }
516+ SDL_AtomicUnlock (& deviceListLock );
496517}
497518
498519static void WIIUAUDIO_ThreadInit (_THIS ) {
0 commit comments