diff --git a/src/Backends/Audio/SoftwareMixer/Solaris.cpp b/src/Backends/Audio/SoftwareMixer/Solaris.cpp index 32df74e9..cfc7487a 100644 --- a/src/Backends/Audio/SoftwareMixer/Solaris.cpp +++ b/src/Backends/Audio/SoftwareMixer/Solaris.cpp @@ -2,8 +2,10 @@ // See LICENCE.txt for details. #include "Backend.h" +#include "../../Misc.h" -#include +#include +#include #include #include #include @@ -15,8 +17,10 @@ #include #include -int sndfp; -void (*parent_callback)(long *stream, size_t frames_total); +static pthread_t mainThread; +static int sndfp; +static void (*parent_callback)(long *stream, size_t frames_total); +static bool audioDone = false; static void* soundcheckthread(void*) { unsigned long for_as_long_as_it_seems_we_should = 0; @@ -38,17 +42,35 @@ static void* soundcheckthread(void*) { long mix[0x400 * 2]; memset(mix, 0, 0x400 * 2); + + // park the main thread since the game probably expects it to not be + // doing anything else while we're requesting audio frames. + audioDone = false; + pthread_kill(mainThread, SIGUSR1); + parent_callback(mix, 0x400 * 2); + // unpark the main thread now that we're not using game state anymore + audioDone = true; + write(sndfp, mix, 0x400 * 2); for_as_long_as_it_seems_we_should = (0x400 / 48000) * 1000000; } } +static void threadPark(int signo) { + while(audioDone == false); +} + unsigned long SoftwareMixerBackend_Init(void (*callback)(long *stream, size_t frames_total)) { sndfp = open("/dev/audio", 0, O_WRONLY); + if(sndfp == -1) { + Backend_PrintError("Failed to open audio device.\n"); + return 0; + } + audio_prinfo_t audioInfo; ioctl(sndfp, AUDIO_GETINFO, &audioInfo); audioInfo.sample_rate = 48000; @@ -58,6 +80,13 @@ unsigned long SoftwareMixerBackend_Init(void (*callback)(long *stream, size_t fr audioInfo.port = AUDIO_SPEAKER; ioctl(sndfp, AUDIO_SETINFO, &audioInfo); + if(signal(SIGUSR1, threadPark) == SIG_ERR) { + Backend_PrintError("Failed to register thread park signal handler for audio system.\n"); + return 0; + } + + mainThread = pthread_self(); + pthread_t thread; pthread_attr_t thread_attr; pthread_attr_init(&thread_attr);