From 4990b8910bc0fe5d576f92396f761a79b3f1a7e3 Mon Sep 17 00:00:00 2001 From: magumagu Date: Wed, 9 Apr 2014 13:41:27 -0700 Subject: [PATCH] DSound: use DSound notifications to produce sound. Pretty straightforward; IDirectSoundNotify lets you register for notifications after a certain amount of sound has played, so use that instead of depending on Update() notifications from the CPU thread. Also, while I'm here, reduce the buffer size by a factor of 4; this seems to reduce the latency, although the difference is sort of subtle. --- Source/Core/AudioCommon/DSoundStream.cpp | 26 ++++++++++++++++-------- Source/Core/AudioCommon/DSoundStream.h | 5 ++--- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Source/Core/AudioCommon/DSoundStream.cpp b/Source/Core/AudioCommon/DSoundStream.cpp index 2ffbe9794b..13ddb6b5b2 100644 --- a/Source/Core/AudioCommon/DSoundStream.cpp +++ b/Source/Core/AudioCommon/DSoundStream.cpp @@ -27,7 +27,7 @@ bool DSound::CreateBuffer() // Fill out DSound buffer description. dsbdesc.dwSize = sizeof(DSBUFFERDESC); - dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS; + dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY; dsbdesc.dwBufferBytes = bufferSize = BUFSIZE; dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&pcmwf; dsbdesc.guid3DAlgorithm = DS3DALG_DEFAULT; @@ -37,6 +37,20 @@ bool DSound::CreateBuffer() { dsBuffer->SetCurrentPosition(0); dsBuffer->SetVolume(m_volume); + + soundSyncEvent = CreateEvent(NULL, TRUE, FALSE, TEXT("DSound Buffer Notification")); + + IDirectSoundNotify *dsnotify; + dsBuffer->QueryInterface(IID_IDirectSoundNotify, (void**)&dsnotify); + DSBPOSITIONNOTIFY notify_positions[3]; + for (unsigned i = 0; i < ARRAYSIZE(notify_positions); ++i) + { + notify_positions[i].dwOffset = i * (BUFSIZE / ARRAYSIZE(notify_positions)); + notify_positions[i].hEventNotify = soundSyncEvent; + } + dsnotify->SetNotificationPositions(ARRAYSIZE(notify_positions), notify_positions); + dsnotify->Release(); + return true; } else @@ -101,7 +115,7 @@ void DSound::SoundLoop() WriteDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender); lastPos = ModBufferSize(lastPos + numBytesToRender); } - soundSyncEvent.Wait(); + WaitForSingleObject(soundSyncEvent, INFINITE); } } @@ -134,11 +148,6 @@ void DSound::SetVolume(int volume) dsBuffer->SetVolume(m_volume); } -void DSound::Update() -{ - soundSyncEvent.Set(); -} - void DSound::Clear(bool mute) { m_muted = mute; @@ -160,11 +169,12 @@ void DSound::Stop() { threadData = 1; // kick the thread if it's waiting - soundSyncEvent.Set(); + SetEvent(soundSyncEvent); thread.join(); dsBuffer->Stop(); dsBuffer->Release(); ds->Release(); + CloseHandle(soundSyncEvent); } diff --git a/Source/Core/AudioCommon/DSoundStream.h b/Source/Core/AudioCommon/DSoundStream.h index 331c4581d3..d653272087 100644 --- a/Source/Core/AudioCommon/DSoundStream.h +++ b/Source/Core/AudioCommon/DSoundStream.h @@ -12,14 +12,14 @@ #include #include -#define BUFSIZE (1024 * 8 * 4) +#define BUFSIZE (256 * 8 * 4) #endif class DSound final : public SoundStream { #ifdef _WIN32 std::thread thread; - Common::Event soundSyncEvent; + HANDLE soundSyncEvent; void *hWnd; IDirectSound8* ds; @@ -65,7 +65,6 @@ public: virtual void Stop(); virtual void Clear(bool mute); static bool isValid() { return true; } - virtual void Update(); #else public: