From d7e57c83bfaffe1ae99c1ea3dbc182c9adf9a5c5 Mon Sep 17 00:00:00 2001 From: luigi__ Date: Fri, 9 Oct 2009 17:27:45 +0000 Subject: [PATCH] Okay, re-add SNDDXThread. But newer system. Synchronous with main thread. No more loopy playback while menus are opened. No more silent playback while the emu is paused. (when you open the menu, sound stutters for a quarter of second before stopping but that's acceptable) --- desmume/src/SPU.cpp | 4 +-- desmume/src/SPU.h | 2 +- desmume/src/windows/main.cpp | 14 ++++----- desmume/src/windows/snddx.cpp | 53 ++++++++++++++++++++++++++++------- 4 files changed, 52 insertions(+), 21 deletions(-) diff --git a/desmume/src/SPU.cpp b/desmume/src/SPU.cpp index 4f0850097..281b248b9 100644 --- a/desmume/src/SPU.cpp +++ b/desmume/src/SPU.cpp @@ -1021,7 +1021,7 @@ void SPU_Emulate_core() SPU_MixAudio(SPU_core,spu_core_samples); } -void SPU_Emulate_user() +void SPU_Emulate_user(bool mix) { if(!SPU_user) return; @@ -1037,7 +1037,7 @@ void SPU_Emulate_user() //printf("mix %i samples\n", audiosize); if (audiosize > SPU_user->bufsize) audiosize = SPU_user->bufsize; - SPU_MixAudio(SPU_user,audiosize); + if (mix) SPU_MixAudio(SPU_user,audiosize); SNDCore->UpdateAudio(SPU_user->outbuf, audiosize); } } diff --git a/desmume/src/SPU.h b/desmume/src/SPU.h index 21d8f38e8..aa679df57 100644 --- a/desmume/src/SPU.h +++ b/desmume/src/SPU.h @@ -140,7 +140,7 @@ void SPU_WriteByte(u32 addr, u8 val); void SPU_WriteWord(u32 addr, u16 val); void SPU_WriteLong(u32 addr, u32 val); void SPU_Emulate_core(void); -void SPU_Emulate_user(void); +void SPU_Emulate_user(bool mix = true); extern SPU_struct *SPU_core, *SPU_user; extern int spu_core_samples; diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 3473448a3..fd3b26fdb 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -265,6 +265,7 @@ extern bool userTouchesScreen; int sndcoretype=SNDCORE_DIRECTX; int sndbuffersize=735*4; int sndvolume=100; +HANDLE hSoundThreadWakeup = INVALID_HANDLE_VALUE; SoundInterface_struct *SNDCoreList[] = { &SNDDummy, @@ -1199,7 +1200,7 @@ static void StepRunLoop_Core() Lock lock; NDS_exec(); win_sound_samplecounter = 735; - SPU_Emulate_user(); + SetEvent(hSoundThreadWakeup); } inFrameBoundary = true; DRV_AviVideoUpdate((u16*)GPU_screen); @@ -1819,6 +1820,8 @@ int _main() display_invoke_done_event = CreateEvent(NULL, FALSE, FALSE, NULL); display_wakeup_event = CreateEvent(NULL, FALSE, FALSE, NULL); + hSoundThreadWakeup = CreateEvent(NULL, FALSE, FALSE, NULL); + #ifdef GDB_STUB gdbstub_handle_t arm9_gdb_stub; gdbstub_handle_t arm7_gdb_stub; @@ -2273,6 +2276,8 @@ int _main() UnregWndClass("DeSmuME"); + CloseHandle(hSoundThreadWakeup); + return 0; } @@ -2990,8 +2995,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM { case WM_ENTERMENULOOP: //Update menu items that needs to be updated dynamically { - SPU_Pause(1); - UpdateHotkeyAssignments(); //Add current hotkey mappings to menu item names MENUITEMINFO mii; @@ -3127,11 +3130,6 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM return 0; } - case WM_EXITMENULOOP: - { - SPU_Pause(0); - return 0; - } case WM_CREATE: { diff --git a/desmume/src/windows/snddx.cpp b/desmume/src/windows/snddx.cpp index 8aad1d8f4..3aced1660 100755 --- a/desmume/src/windows/snddx.cpp +++ b/desmume/src/windows/snddx.cpp @@ -71,7 +71,37 @@ static int issoundmuted; ////////////////////////////////////////////////////////////////////////////// //extern volatile int win_sound_samplecounter; +HANDLE hSNDDXThread = INVALID_HANDLE_VALUE; +extern HANDLE hSoundThreadWakeup; +bool bTerminateSoundThread = false; +bool bSilence = false; +DWORD WINAPI SNDDXThread( LPVOID ) +{ + for(;;) + { + if(bTerminateSoundThread) break; + + if (bSilence) + { + if (WaitForSingleObject(hSoundThreadWakeup, 10) == WAIT_OBJECT_0) + bSilence = false; + } + else + { + // If the sound thread wakeup event is not signaled after a quarter second, output silence + if (WaitForSingleObject(hSoundThreadWakeup, 250) == WAIT_TIMEOUT) + bSilence = true; + } + + { + Lock lock; + SPU_Emulate_user(!bSilence); + } + } + + return 0; +} int SNDDXInit(int buffersize) { @@ -169,6 +199,10 @@ int SNDDXInit(int buffersize) soundvolume = DSBVOLUME_MAX; issoundmuted = 0; + bSilence = false; + bTerminateSoundThread = false; + hSNDDXThread = CreateThread(0, 0, SNDDXThread, 0, 0, 0); + return 0; } @@ -178,6 +212,10 @@ void SNDDXDeInit() { DWORD status=0; + bTerminateSoundThread = true; + SetEvent(hSoundThreadWakeup); + WaitForSingleObject(hSNDDXThread, INFINITE); + if (lpDSB2) { lpDSB2->GetStatus(&status); @@ -200,6 +238,8 @@ void SNDDXDeInit() lpDS8->Release(); lpDS8 = NULL; } + + delete stereodata16; } ////////////////////////////////////////////////////////////////////////////// @@ -211,14 +251,6 @@ void SNDDXUpdateAudio(s16 *buffer, u32 num_samples) DWORD buffer1_size, buffer2_size; DWORD status; -/* int samplecounter; - { - Lock lock; - samplecounter = win_sound_samplecounter -= num_samples; - } - - bool silence = (samplecounter<-44100*15/60); //behind by more than a quarter second -> silence -*/ lpDSB2->GetStatus(&status); if (status & DSBSTATUS_BUFFERLOST) @@ -226,12 +258,13 @@ void SNDDXUpdateAudio(s16 *buffer, u32 num_samples) lpDSB2->Lock(soundoffset, num_samples * sizeof(s16) * 2, &buffer1, &buffer1_size, &buffer2, &buffer2_size, 0); -/* if(silence) { + if(bSilence) + { memset(buffer1, 0, buffer1_size); if(buffer2) memset(buffer2, 0, buffer2_size); } - else*/ + else { memcpy(buffer1, buffer, buffer1_size); if (buffer2)