ref: 5b4778fb06583fd1406769fcada9961e9c4337de
parent: 6df224400cd015598c40a0bd33f00a934a49fe79
author: Clownacy <Clownacy@users.noreply.github.com>
date: Sun Oct 11 17:16:47 EDT 2020
Fix the 3DS crash when closing For whatever reason, the 3DS *really* doesn't like it when I do all the audio mixing in the callback function. Instead, it seems I have to use a dedicated thread.
--- a/src/Backends/Audio/SoftwareMixer/3DS.cpp
+++ b/src/Backends/Audio/SoftwareMixer/3DS.cpp
@@ -22,6 +22,11 @@
static LightLock mixer_mutex;
static LightLock organya_mutex;
+static LightEvent audio_thread_event;
+
+static Thread audio_thread;
+static bool audio_thread_die;
+
static void FullBuffer(short *stream, size_t frames_total)
{
size_t frames_done = 0;
@@ -56,13 +61,25 @@
{
(void)user_data;
- if (dsp_buffers[current_dsp_buffer].status == NDSP_WBUF_DONE)
+ LightEvent_Signal(&audio_thread_event);
+}
+
+static void AudioThread(void *user_data)
+{
+ (void)user_data;
+
+ while (!audio_thread_die)
{
- FullBuffer(dsp_buffers[current_dsp_buffer].data_pcm16, dsp_buffers[current_dsp_buffer].nsamples);
+ if (dsp_buffers[current_dsp_buffer].status == NDSP_WBUF_DONE)
+ {
+ FullBuffer(dsp_buffers[current_dsp_buffer].data_pcm16, dsp_buffers[current_dsp_buffer].nsamples);
- ndspChnWaveBufAdd(0, &dsp_buffers[current_dsp_buffer]);
+ ndspChnWaveBufAdd(0, &dsp_buffers[current_dsp_buffer]);
- current_dsp_buffer = !current_dsp_buffer;
+ current_dsp_buffer = !current_dsp_buffer;
+ }
+
+ LightEvent_Wait(&audio_thread_event);
}
}
@@ -110,6 +127,12 @@
LightLock_Init(&mixer_mutex);
LightLock_Init(&organya_mutex);
+ LightEvent_Init(&audio_thread_event, RESET_ONESHOT);
+
+ audio_thread_die = false;
+
+ audio_thread = threadCreate(AudioThread, NULL, 32 * 1024, 0x18, -1, false);
+
return SAMPLE_RATE;
}
else
@@ -129,6 +152,16 @@
void SoftwareMixerBackend_Deinit(void)
{
+ ndspSetCallback(NULL, NULL);
+
+ // Kill audio thread
+ audio_thread_die = true;
+ LightEvent_Signal(&audio_thread_event);
+ threadJoin(audio_thread, UINT64_MAX);
+ threadFree(audio_thread);
+
+ ndspChnReset(0);
+
ndspExit();
linearFree(stream_buffer);