4747
4848#define AX_MAIN_AFFINITY OS_THREAD_ATTRIB_AFFINITY_CPU1
4949
50- #define WIIU_DEVICE_TV 0
51- #define WIIU_DEVICE_GAMEPAD 1
52- #define WIIU_DEVICE_MIRRORED 2
50+ #define WIIU_DEVICE_TV 1
51+ #define WIIU_DEVICE_GAMEPAD 2
52+ #define WIIU_DEVICE_MIRRORED 3
5353#define WIIU_MAX_DEVICES 3
5454
55- static int mirroredHandle ;
56- static int tvHandle ;
57- static int drcHandle ;
58-
5955static void _WIIUAUDIO_framecallback ();
6056static SDL_AudioDevice * cb_this ;
6157#define cb_hidden cb_this->hidden
6258
59+ // Protects wiiuDevices/deviceCount during device open/close while the frame callback is running
60+ static SDL_SpinLock deviceListLock = 0 ;
6361/* Some helpers for AX-related math */
6462/* Absolute address to an AXVoiceOffsets offset */
6563#define calc_ax_offset (offs , addr ) (((void*)addr - offs.data) \
@@ -234,8 +232,10 @@ static int _WIIUAUDIO_OpenDeviceFunction(_THIS) {
234232 AXVoiceEnd (this -> hidden -> voice [i ]);
235233 }
236234
235+ SDL_AtomicLock (& deviceListLock );
237236 wiiuDevices [deviceCount ] = this ;
238237 deviceCount ++ ;
238+ SDL_AtomicUnlock (& deviceListLock );
239239
240240 return 0 ;
241241}
@@ -258,9 +258,9 @@ static void WIIUAUDIO_DetectDevices(void) {
258258
259259 SDL_CalculateAudioSpec (& spec );
260260
261- SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_MIRRORED , & spec , & mirroredHandle );
262- SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_TV , & spec , & tvHandle );
263- SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_GAMEPAD , & spec , & drcHandle );
261+ SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_MIRRORED , & spec , ( void * ) WIIU_DEVICE_MIRRORED );
262+ SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_TV , & spec , ( void * ) WIIU_DEVICE_TV );
263+ SDL_AddAudioDevice (SDL_FALSE , SDL_AUDIO_DEVICE_WIIU_GAMEPAD , & spec , ( void * ) WIIU_DEVICE_GAMEPAD );
264264}
265265
266266static int WIIUAUDIO_OpenDevice (_THIS , const char * devname ) {
@@ -272,10 +272,10 @@ static int WIIUAUDIO_OpenDevice(_THIS, const char *devname) {
272272
273273 deviceType = WIIU_DEVICE_MIRRORED ;
274274
275- if (this -> handle == & tvHandle ) {
275+ if (this -> handle == ( void * ) WIIU_DEVICE_TV ) {
276276 deviceType = WIIU_DEVICE_TV ;
277277 }
278- else if (this -> handle == & drcHandle ) {
278+ else if (this -> handle == ( void * ) WIIU_DEVICE_GAMEPAD ) {
279279 deviceType = WIIU_DEVICE_GAMEPAD ;
280280 }
281281
@@ -327,9 +327,22 @@ static int WIIUAUDIO_OpenDevice(_THIS, const char *devname) {
327327
328328/* Called every 3ms before a frame of audio is rendered. Keep it fast! */
329329static void _WIIUAUDIO_framecallback () {
330- int playing_buffer = -1 ;
331- AXVoiceOffsets offs [6 ];
332- void * endaddr ;
330+ SDL_AudioDevice * local [WIIU_MAX_DEVICES ];
331+ int count ;
332+
333+ SDL_AtomicLock (& deviceListLock );
334+ count = deviceCount ;
335+ for (int i = 0 ; i < count ; i ++ ) {
336+ local [i ] = wiiuDevices [i ];
337+ }
338+ SDL_AtomicUnlock (& deviceListLock );
339+
340+ for (int deviceIndex = 0 ; deviceIndex < count ; ++ deviceIndex ) {
341+ SDL_AudioDevice * dev = local [deviceIndex ];
342+
343+ int playing_buffer = -1 ;
344+ AXVoiceOffsets offs [6 ];
345+ void * endaddr ;
333346
334347 for (int i = 0 ; i < cb_this -> spec .channels ; i ++ ) {
335348 AXGetVoiceOffsets (cb_hidden -> voice [i ], & offs [i ]);
@@ -464,6 +477,19 @@ static void WIIUAUDIO_CloseDevice(_THIS) {
464477 if (this -> hidden -> mixbufs [0 ]) free (this -> hidden -> mixbufs [0 ]);
465478 if (this -> hidden -> deintvbuf ) SDL_free (this -> hidden -> deintvbuf );
466479 SDL_free (this -> hidden );
480+
481+ SDL_AtomicLock (& deviceListLock );
482+ for (int i = 0 ; i < deviceCount ; ++ i ) {
483+ if (wiiuDevices [i ] == this ) {
484+ for (int j = i ; j < deviceCount - 1 ; ++ j ) {
485+ wiiuDevices [j ] = wiiuDevices [j + 1 ];
486+ }
487+ wiiuDevices [deviceCount - 1 ] = NULL ;
488+ deviceCount -- ;
489+ break ;
490+ }
491+ }
492+ SDL_AtomicUnlock (& deviceListLock );
467493}
468494
469495static void WIIUAUDIO_ThreadInit (_THIS ) {
0 commit comments