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.
This commit is contained in:
magumagu 2014-04-09 13:41:27 -07:00
parent 7d8604ac1c
commit 4990b8910b
2 changed files with 20 additions and 11 deletions

View File

@ -27,7 +27,7 @@ bool DSound::CreateBuffer()
// Fill out DSound buffer description. // Fill out DSound buffer description.
dsbdesc.dwSize = sizeof(DSBUFFERDESC); 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.dwBufferBytes = bufferSize = BUFSIZE;
dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&pcmwf; dsbdesc.lpwfxFormat = (WAVEFORMATEX *)&pcmwf;
dsbdesc.guid3DAlgorithm = DS3DALG_DEFAULT; dsbdesc.guid3DAlgorithm = DS3DALG_DEFAULT;
@ -37,6 +37,20 @@ bool DSound::CreateBuffer()
{ {
dsBuffer->SetCurrentPosition(0); dsBuffer->SetCurrentPosition(0);
dsBuffer->SetVolume(m_volume); 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; return true;
} }
else else
@ -101,7 +115,7 @@ void DSound::SoundLoop()
WriteDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender); WriteDataToBuffer(lastPos, (char*)realtimeBuffer, numBytesToRender);
lastPos = ModBufferSize(lastPos + numBytesToRender); lastPos = ModBufferSize(lastPos + numBytesToRender);
} }
soundSyncEvent.Wait(); WaitForSingleObject(soundSyncEvent, INFINITE);
} }
} }
@ -134,11 +148,6 @@ void DSound::SetVolume(int volume)
dsBuffer->SetVolume(m_volume); dsBuffer->SetVolume(m_volume);
} }
void DSound::Update()
{
soundSyncEvent.Set();
}
void DSound::Clear(bool mute) void DSound::Clear(bool mute)
{ {
m_muted = mute; m_muted = mute;
@ -160,11 +169,12 @@ void DSound::Stop()
{ {
threadData = 1; threadData = 1;
// kick the thread if it's waiting // kick the thread if it's waiting
soundSyncEvent.Set(); SetEvent(soundSyncEvent);
thread.join(); thread.join();
dsBuffer->Stop(); dsBuffer->Stop();
dsBuffer->Release(); dsBuffer->Release();
ds->Release(); ds->Release();
CloseHandle(soundSyncEvent);
} }

View File

@ -12,14 +12,14 @@
#include <mmsystem.h> #include <mmsystem.h>
#include <dsound.h> #include <dsound.h>
#define BUFSIZE (1024 * 8 * 4) #define BUFSIZE (256 * 8 * 4)
#endif #endif
class DSound final : public SoundStream class DSound final : public SoundStream
{ {
#ifdef _WIN32 #ifdef _WIN32
std::thread thread; std::thread thread;
Common::Event soundSyncEvent; HANDLE soundSyncEvent;
void *hWnd; void *hWnd;
IDirectSound8* ds; IDirectSound8* ds;
@ -65,7 +65,6 @@ public:
virtual void Stop(); virtual void Stop();
virtual void Clear(bool mute); virtual void Clear(bool mute);
static bool isValid() { return true; } static bool isValid() { return true; }
virtual void Update();
#else #else
public: public: