@@ -61,13 +61,11 @@ static SDL_AudioDevice* cb_this;
6161/* +1, but never goes above NUM_BUFFERS */
6262#define next_id (id ) (id + 1) % NUM_BUFFERS
6363
64- static int WIIUAUDIO_OpenDevice (_THIS , const char * devname ) {
65- int ret = 0 ;
64+ static int _WIIUAUDIO_OpenDeviceFunction (_THIS ) {
6665 AXVoiceOffsets offs ;
6766 AXVoiceVeData vol = {
6867 .volume = 0x8000 ,
6968 };
70- uint32_t old_affinity ;
7169 float srcratio ;
7270 Uint8 * mixbuf = NULL ;
7371 uint32_t mixbuf_allocation_count = 0 ;
@@ -80,10 +78,6 @@ static int WIIUAUDIO_OpenDevice(_THIS, const char* devname) {
8078
8179 SDL_zerop (this -> hidden );
8280
83- /* We *must not* change cores when setting stuff up */
84- old_affinity = OSGetThreadAffinity (OSGetCurrentThread ());
85- OSSetThreadAffinity (OSGetCurrentThread (), AX_MAIN_AFFINITY );
86-
8781/* Take a quick aside to init the wiiu audio */
8882 if (!AXIsInit ()) {
8983 /* Init the AX audio engine */
@@ -147,8 +141,7 @@ static int WIIUAUDIO_OpenDevice(_THIS, const char* devname) {
147141
148142 if (!mixbuf ) {
149143 printf ("Couldn't allocate mix buffer\n" );
150- ret = SDL_OutOfMemory ();
151- goto end ;
144+ return SDL_OutOfMemory ();
152145 }
153146
154147 memset (mixbuf , 0 , this -> spec .size * NUM_BUFFERS );
@@ -163,8 +156,7 @@ static int WIIUAUDIO_OpenDevice(_THIS, const char* devname) {
163156 if (this -> hidden -> deintvbuf == NULL ) {
164157 AXQuit ();
165158 printf ("DEBUG: Couldn't allocate deinterleave buffer" );
166- ret = SDL_SetError ("Couldn't allocate deinterleave buffer" );
167- goto end ;
159+ return SDL_SetError ("Couldn't allocate deinterleave buffer" );
168160 }
169161
170162
@@ -174,8 +166,7 @@ static int WIIUAUDIO_OpenDevice(_THIS, const char* devname) {
174166 if (!this -> hidden -> voice [i ]) {
175167 AXQuit ();
176168 printf ("DEBUG: couldn't get voice\n" );
177- ret = SDL_OutOfMemory ();
178- goto end ;
169+ return SDL_OutOfMemory ();
179170 }
180171
181172 /* Start messing with it */
@@ -247,10 +238,64 @@ static int WIIUAUDIO_OpenDevice(_THIS, const char* devname) {
247238 cb_this = this ; //wish there was a better way
248239 AXRegisterAppFrameCallback (_WIIUAUDIO_framecallback );
249240
250- end : ;
251- /* Put the thread affinity back to normal - we won't call any more AX funcs */
252- OSSetThreadAffinity (OSGetCurrentThread (), old_affinity );
253- return ret ;
241+ return 0 ;
242+ }
243+
244+ static void _WIIUAUDIO_ThreadDeallocator (OSThread * thread , void * stack ) {
245+ free (thread );
246+ free (stack );
247+ }
248+
249+ static void _WIIUAUDIO_ThreadCleanup (OSThread * thread , void * stack ) {
250+ }
251+
252+ static int WIIUAUDIO_OpenDevice (_THIS , const char * devname ) {
253+ int result ;
254+
255+ /* AX functions need to run from the same core.
256+ Since we cannot easily change the affinity of the currently running thread, we create a new one if necessary.
257+ This thread only runs on CPU1 (AX_MAIN_AFFINITY) and will be joined after initialization is done. */
258+ if (OSGetThreadAffinity (OSGetCurrentThread ()) != AX_MAIN_AFFINITY ) {
259+ OSThread * thread ;
260+ uint32_t stackSize = 32 * 1024 ;
261+ uint8_t * stack ;
262+ int32_t priority = OSGetThreadPriority (OSGetCurrentThread ());
263+
264+ thread = (OSThread * )memalign (16 , sizeof (OSThread ));
265+ if (!thread ) {
266+ return SDL_OutOfMemory ();
267+ }
268+
269+ stack = memalign (16 , stackSize );
270+ if (!stack ) {
271+ free (thread );
272+ return SDL_OutOfMemory ();
273+ }
274+
275+ if (!OSCreateThread (thread ,
276+ (OSThreadEntryPointFn )_WIIUAUDIO_OpenDeviceFunction ,
277+ (int32_t )this ,
278+ NULL ,
279+ stack + stackSize ,
280+ stackSize ,
281+ priority ,
282+ AX_MAIN_AFFINITY ))
283+ {
284+ return SDL_SetError ("OSCreateThread() failed" );
285+ }
286+
287+ OSSetThreadDeallocator (thread , & _WIIUAUDIO_ThreadDeallocator );
288+ OSSetThreadCleanupCallback (thread , & _WIIUAUDIO_ThreadCleanup );
289+ OSResumeThread (thread );
290+
291+ if (!OSJoinThread (thread , & result )) {
292+ return SDL_SetError ("OSJoinThread() failed" );
293+ }
294+ } else {
295+ result = _WIIUAUDIO_OpenDeviceFunction (this );
296+ }
297+
298+ return result ;
254299}
255300
256301/* Called every 3ms before a frame of audio is rendered. Keep it fast! */
@@ -405,7 +450,7 @@ static void WIIUAUDIO_ThreadInit(_THIS) {
405450 OSSetThreadPriority (currentThread , priority );
406451}
407452
408- static SDL_bool WIIUAUDIO_Init (SDL_AudioDriverImpl * impl ) {
453+ static SDL_bool WIIUAUDIO_Init (SDL_AudioDriverImpl * impl ) {
409454 impl -> OpenDevice = WIIUAUDIO_OpenDevice ;
410455 impl -> PlayDevice = WIIUAUDIO_PlayDevice ;
411456 impl -> WaitDevice = WIIUAUDIO_WaitDevice ;
0 commit comments