@@ -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 open_device_thread (_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,49 @@ 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 thread_deallocator (OSThread * thread , void * stack ) {
245+ free (thread );
246+ free (stack );
247+ }
248+
249+ static void thread_cleanup (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
257+ we simply create a new one which only runs on CPU1 (AX_MAIN_AFFINITY), then join it */
258+ OSThread * thread = (OSThread * )memalign (16 , sizeof (OSThread ));
259+ uint32_t stackSize = 32 * 1024 ;
260+ uint8_t * stack = memalign (16 , stackSize );
261+ int32_t priority = OSGetThreadPriority (OSGetCurrentThread ());
262+
263+ if (!OSCreateThread (thread ,
264+ (OSThreadEntryPointFn )open_device_thread ,
265+ (int32_t )this ,
266+ NULL ,
267+ stack + stackSize ,
268+ stackSize ,
269+ priority ,
270+ AX_MAIN_AFFINITY ))
271+ {
272+ return SDL_SetError ("OSCreateThread() failed" );
273+ }
274+
275+ OSSetThreadDeallocator (thread , & thread_deallocator );
276+ OSSetThreadCleanupCallback (thread , & thread_cleanup );
277+ OSResumeThread (thread );
278+
279+ if (!OSJoinThread (thread , & result )) {
280+ return SDL_SetError ("OSJoinThread() failed" );
281+ }
282+
283+ return result ;
254284}
255285
256286/* Called every 3ms before a frame of audio is rendered. Keep it fast! */
0 commit comments