aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c2
-rw-r--r--Alc/dsound.c62
2 files changed, 57 insertions, 7 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 905fee22..9423ebc3 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -32,6 +32,8 @@
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
+DEFINE_GUID(IID_IDirectSoundNotify, 0xb0210783, 0x89cd, 0x11d0, 0xaf, 0x8, 0x0, 0xa0, 0xc9, 0x25, 0xcd, 0x16);
+
DEFINE_GUID(CLSID_MMDeviceEnumerator, 0xbcde0395, 0xe52f, 0x467c, 0x8e,0x3d, 0xc4,0x57,0x92,0x91,0x69,0x2e);
DEFINE_GUID(IID_IMMDeviceEnumerator, 0xa95664d2, 0x9614, 0x4f35, 0xa7,0x46, 0xde,0x8d,0xb6,0x36,0x17,0xe6);
DEFINE_GUID(IID_IAudioClient, 0x1cb9ad4c, 0xdbfa, 0x4c32, 0xb1,0x78, 0xc2,0xf5,0x68,0xa7,0x03,0xb2);
diff --git a/Alc/dsound.c b/Alc/dsound.c
index 5f3c8e3c..7373584c 100644
--- a/Alc/dsound.c
+++ b/Alc/dsound.c
@@ -61,6 +61,8 @@ typedef struct {
LPDIRECTSOUND lpDS;
LPDIRECTSOUNDBUFFER DSpbuffer;
LPDIRECTSOUNDBUFFER DSsbuffer;
+ LPDIRECTSOUNDNOTIFY DSnotify;
+ HANDLE hNotifyEvent;
volatile int killNow;
ALvoid *thread;
@@ -76,6 +78,7 @@ static const ALCchar dsDevice[] = "DirectSound Default";
static DevMap *DeviceList;
static ALuint NumDevices;
+#define MAX_UPDATES 128
static void *DSoundLoad(void)
{
@@ -196,7 +199,7 @@ static ALuint DSoundProc(ALvoid *ptr)
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &LastCursor, NULL);
while(!pData->killNow)
{
- // Get current play and write cursors
+ // Get current play cursor
IDirectSoundBuffer_GetCurrentPosition(pData->DSsbuffer, &PlayCursor, NULL);
avail = (PlayCursor-LastCursor+DSBCaps.dwBufferBytes) % DSBCaps.dwBufferBytes;
@@ -213,7 +216,10 @@ static ALuint DSoundProc(ALvoid *ptr)
}
Playing = TRUE;
}
- Sleep(1);
+
+ avail = WaitForSingleObjectEx(pData->hNotifyEvent, 2000, FALSE);
+ if(avail != WAIT_OBJECT_0)
+ ERR("WaitForSingleObjectEx error: 0x%lx\n", avail);
continue;
}
avail -= avail%FragSize;
@@ -461,9 +467,16 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device)
if(SUCCEEDED(hr))
{
+ if(device->NumUpdates > MAX_UPDATES)
+ {
+ device->UpdateSize = ((ALuint64)device->UpdateSize*MAX_UPDATES +
+ device->NumUpdates-1) / device->NumUpdates;
+ device->NumUpdates = MAX_UPDATES;
+ }
+
memset(&DSBDescription,0,sizeof(DSBUFFERDESC));
DSBDescription.dwSize=sizeof(DSBUFFERDESC);
- DSBDescription.dwFlags=DSBCAPS_GLOBALFOCUS|DSBCAPS_GETCURRENTPOSITION2;
+ DSBDescription.dwFlags=DSBCAPS_CTRLPOSITIONNOTIFY|DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_GLOBALFOCUS;
DSBDescription.dwBufferBytes=device->UpdateSize * device->NumUpdates *
OutputType.Format.nBlockAlign;
DSBDescription.lpwfxFormat=&OutputType.Format;
@@ -472,18 +485,49 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device)
if(SUCCEEDED(hr))
{
+ hr = IDirectSoundBuffer_QueryInterface(pData->DSsbuffer, &IID_IDirectSoundNotify, (LPVOID *)&pData->DSnotify);
+ if(SUCCEEDED(hr))
+ {
+ pData->hNotifyEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
+ if(pData->hNotifyEvent == NULL)
+ hr = E_FAIL;
+ else
+ {
+ DSBPOSITIONNOTIFY notifies[MAX_UPDATES];
+ ALuint i;
+
+ for(i = 0;i < device->NumUpdates;++i)
+ {
+ notifies[i].dwOffset = i * device->UpdateSize *
+ OutputType.Format.nBlockAlign;
+ notifies[i].hEventNotify = pData->hNotifyEvent;
+ }
+ if(IDirectSoundNotify_SetNotificationPositions(pData->DSnotify, device->NumUpdates, notifies) != DS_OK)
+ hr = E_FAIL;
+ }
+ }
+ }
+
+ if(SUCCEEDED(hr))
+ {
SetDefaultWFXChannelOrder(device);
pData->thread = StartThread(DSoundProc, device);
- if(!pData->thread)
+ if(pData->thread == NULL)
hr = E_FAIL;
}
if(FAILED(hr))
{
- if (pData->DSsbuffer)
+ if(pData->hNotifyEvent != NULL)
+ CloseHandle(pData->hNotifyEvent);
+ pData->hNotifyEvent = NULL;
+ if(pData->DSnotify != NULL)
+ IDirectSoundNotify_Release(pData->DSnotify);
+ pData->DSnotify = NULL;
+ if(pData->DSsbuffer != NULL)
IDirectSoundBuffer_Release(pData->DSsbuffer);
pData->DSsbuffer = NULL;
- if (pData->DSpbuffer)
+ if(pData->DSpbuffer != NULL)
IDirectSoundBuffer_Release(pData->DSpbuffer);
pData->DSpbuffer = NULL;
return ALC_FALSE;
@@ -505,9 +549,13 @@ static void DSoundStopPlayback(ALCdevice *device)
pData->killNow = 0;
+ CloseHandle(pData->hNotifyEvent);
+ pData->hNotifyEvent = NULL;
+ IDirectSoundNotify_Release(pData->DSnotify);
+ pData->DSnotify = NULL;
IDirectSoundBuffer_Release(pData->DSsbuffer);
pData->DSsbuffer = NULL;
- if (pData->DSpbuffer)
+ if(pData->DSpbuffer != NULL)
IDirectSoundBuffer_Release(pData->DSpbuffer);
pData->DSpbuffer = NULL;
}