From 4a56a883fa722a7a8807170c3d534a5e88f546e8 Mon Sep 17 00:00:00 2001 From: LiquidFenrir Date: Tue, 14 Jun 2022 12:54:02 +0200 Subject: [PATCH] make audio safer - centralized stop function - freeing the struct not from the thread while waiting on handle in it - thread not detached - maybe fixes hang on exit from HM in ndsp status check loop --- include/music.h | 3 ++- source/loading.c | 1 - source/main.c | 13 ++++--------- source/music.c | 23 ++++++++++++++++------- source/remote.c | 16 ++++------------ 5 files changed, 26 insertions(+), 30 deletions(-) diff --git a/include/music.h b/include/music.h index d962e59..eb2c17c 100644 --- a/include/music.h +++ b/include/music.h @@ -46,9 +46,10 @@ typedef struct { u32 filesize; volatile bool stop; - Handle finished; + Thread playing_thread; } audio_s; void play_audio(audio_s *); +void stop_audio(audio_s**); #endif diff --git a/source/loading.c b/source/loading.c index ce04056..858fc56 100644 --- a/source/loading.c +++ b/source/loading.c @@ -608,7 +608,6 @@ Result load_audio(Entry_s entry, audio_s *audio) } audio->mix[0] = audio->mix[1] = 1.0f; // Determines volume for the 12 (?) different outputs. See http://smealum.github.io/ctrulib/channel_8h.html#a30eb26f1972cc3ec28370263796c0444 - svcCreateEvent(&audio->finished, RESET_STICKY); ndspChnSetInterp(0, NDSP_INTERP_LINEAR); ndspChnSetMix(0, audio->mix); // See mix comment above diff --git a/source/main.c b/source/main.c index 0d07958..91426fc 100644 --- a/source/main.c +++ b/source/main.c @@ -37,7 +37,7 @@ bool quit = false; bool dspfirm = false; -audio_s * audio = NULL; +static audio_s * audio = NULL; static bool homebrew = false; static bool installed_themes = false; @@ -165,8 +165,7 @@ void exit_function(bool power_pressed) { if(audio) { - audio->stop = true; - svcWaitSynchronization(audio->finished, U64_MAX); + stop_audio(&audio); } free_lists(); svcCloseHandle(update_icons_mutex); @@ -512,9 +511,7 @@ int main(void) preview_mode = false; if(current_mode == MODE_THEMES && audio) { - audio->stop = true; - svcWaitSynchronization(audio->finished, U64_MAX); - audio = NULL; + stop_audio(&audio); } } continue; @@ -524,9 +521,7 @@ int main(void) preview_mode = false; if(current_mode == MODE_THEMES && audio) { - audio->stop = true; - svcWaitSynchronization(audio->finished, U64_MAX); - audio = NULL; + stop_audio(&audio); } continue; } diff --git a/source/music.c b/source/music.c index c7afe41..deb9106 100644 --- a/source/music.c +++ b/source/music.c @@ -69,17 +69,26 @@ void thread_audio(void* data) { while(!audio->stop) { update_audio(audio); } - free(audio->filebuf); + ndspChnWaveBufClear(0); + ndspChnReset(0); ov_clear(&audio->vf); + free(audio->filebuf); linearFree((void*)audio->wave_buf[0].data_vaddr); linearFree((void*)audio->wave_buf[1].data_vaddr); - while (audio->wave_buf[0].status != NDSP_WBUF_DONE || audio->wave_buf[1].status != NDSP_WBUF_DONE) svcSleepThread(1e7); - svcSignalEvent(audio->finished); - svcSleepThread(1e8); - svcCloseHandle(audio->finished); - free(audio); } void play_audio(audio_s *audio) { - threadCreate(thread_audio, audio, 0x1000, 0x3F, 1, true); + audio->playing_thread = threadCreate(thread_audio, audio, 0x1000, 0x3F, 1, false); +} + +void stop_audio(audio_s** audio_ptr) { + audio_s* audio = *audio_ptr; + if(audio->playing_thread) + { + audio->stop = true; + threadJoin(audio->playing_thread, U64_MAX); + threadFree(audio->playing_thread); + } + free(audio); + *audio_ptr = NULL; } diff --git a/source/remote.c b/source/remote.c index 797e495..048bb00 100644 --- a/source/remote.c +++ b/source/remote.c @@ -569,9 +569,7 @@ bool themeplaza_browser(EntryMode mode) preview_mode = false; if (mode == MODE_THEMES && audio != NULL) { - audio->stop = true; - svcWaitSynchronization(audio->finished, U64_MAX); - audio = NULL; + stop_audio(&audio); } } } @@ -582,9 +580,7 @@ bool themeplaza_browser(EntryMode mode) preview_mode = false; if (mode == MODE_THEMES && audio != NULL) { - audio->stop = true; - svcWaitSynchronization(audio->finished, U64_MAX); - audio = NULL; + stop_audio(&audio); } } else @@ -650,9 +646,7 @@ bool themeplaza_browser(EntryMode mode) preview_mode = false; if (mode == MODE_THEMES && audio) { - audio->stop = true; - svcWaitSynchronization(audio->finished, U64_MAX); - audio = NULL; + stop_audio(&audio); } continue; } @@ -721,9 +715,7 @@ bool themeplaza_browser(EntryMode mode) if (audio) { - audio->stop = true; - svcWaitSynchronization(audio->finished, U64_MAX); - audio = NULL; + stop_audio(&audio); } free_preview(preview);