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.
This commit is contained in:
parent
6df224400c
commit
5b4778fb06
1 changed files with 37 additions and 4 deletions
|
@ -22,6 +22,11 @@ static bool current_dsp_buffer;
|
||||||
static LightLock mixer_mutex;
|
static LightLock mixer_mutex;
|
||||||
static LightLock organya_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)
|
static void FullBuffer(short *stream, size_t frames_total)
|
||||||
{
|
{
|
||||||
size_t frames_done = 0;
|
size_t frames_done = 0;
|
||||||
|
@ -56,6 +61,15 @@ static void Callback(void *user_data)
|
||||||
{
|
{
|
||||||
(void)user_data;
|
(void)user_data;
|
||||||
|
|
||||||
|
LightEvent_Signal(&audio_thread_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AudioThread(void *user_data)
|
||||||
|
{
|
||||||
|
(void)user_data;
|
||||||
|
|
||||||
|
while (!audio_thread_die)
|
||||||
|
{
|
||||||
if (dsp_buffers[current_dsp_buffer].status == NDSP_WBUF_DONE)
|
if (dsp_buffers[current_dsp_buffer].status == NDSP_WBUF_DONE)
|
||||||
{
|
{
|
||||||
FullBuffer(dsp_buffers[current_dsp_buffer].data_pcm16, dsp_buffers[current_dsp_buffer].nsamples);
|
FullBuffer(dsp_buffers[current_dsp_buffer].data_pcm16, dsp_buffers[current_dsp_buffer].nsamples);
|
||||||
|
@ -64,6 +78,9 @@ static void Callback(void *user_data)
|
||||||
|
|
||||||
current_dsp_buffer = !current_dsp_buffer;
|
current_dsp_buffer = !current_dsp_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LightEvent_Wait(&audio_thread_event);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long SoftwareMixerBackend_Init(void (*callback)(long *stream, size_t frames_total))
|
unsigned long SoftwareMixerBackend_Init(void (*callback)(long *stream, size_t frames_total))
|
||||||
|
@ -110,6 +127,12 @@ unsigned long SoftwareMixerBackend_Init(void (*callback)(long *stream, size_t fr
|
||||||
LightLock_Init(&mixer_mutex);
|
LightLock_Init(&mixer_mutex);
|
||||||
LightLock_Init(&organya_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;
|
return SAMPLE_RATE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -129,6 +152,16 @@ unsigned long SoftwareMixerBackend_Init(void (*callback)(long *stream, size_t fr
|
||||||
|
|
||||||
void SoftwareMixerBackend_Deinit(void)
|
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();
|
ndspExit();
|
||||||
|
|
||||||
linearFree(stream_buffer);
|
linearFree(stream_buffer);
|
||||||
|
|
Loading…
Add table
Reference in a new issue