Commit 894cf6db authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Alexandre Julliard

winealsa: Add a timer check to capture to see if play notifications have been triggered.

parent a8da3e7f
......@@ -56,6 +56,10 @@
#ifdef HAVE_ALSA
/* Notify timer checks every 10 ms with a resolution of 2 ms */
#define DS_TIME_DEL 10
#define DS_TIME_RES 2
WINE_DEFAULT_DEBUG_CHANNEL(dsalsa);
typedef struct IDsCaptureDriverBufferImpl IDsCaptureDriverBufferImpl;
......@@ -74,7 +78,8 @@ typedef struct IDsCaptureDriverNotifyImpl
LONG ref;
IDsCaptureDriverBufferImpl *buffer;
DSBPOSITIONNOTIFY *notifies;
DWORD nrofnotifies;
DWORD nrofnotifies, playpos;
UINT timerID;
} IDsCaptureDriverNotifyImpl;
struct IDsCaptureDriverBufferImpl
......@@ -122,6 +127,35 @@ static void Capture_CheckNotify(IDsCaptureDriverNotifyImpl *This, DWORD from, DW
}
}
static void CALLBACK Capture_Notify(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
{
IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)dwUser;
DWORD last_playpos, playpos;
PIDSCDRIVERBUFFER iface = (PIDSCDRIVERBUFFER)This;
/* **** */
EnterCriticalSection(&This->pcm_crst);
IDsDriverBuffer_GetPosition(iface, &playpos, NULL);
last_playpos = This->notify->playpos;
This->notify->playpos = playpos;
if (snd_pcm_state(This->pcm) != SND_PCM_STATE_RUNNING || last_playpos == playpos || !This->notify->nrofnotifies || !This->notify->notifies)
goto done;
if (playpos < last_playpos)
{
Capture_CheckNotify(This->notify, last_playpos, This->mmap_buflen_bytes);
if (playpos)
Capture_CheckNotify(This->notify, 0, playpos);
}
else Capture_CheckNotify(This->notify, last_playpos, playpos - last_playpos);
done:
LeaveCriticalSection(&This->pcm_crst);
/* **** */
}
static HRESULT WINAPI IDsCaptureDriverNotifyImpl_QueryInterface(PIDSDRIVERNOTIFY iface, REFIID riid, LPVOID *ppobj)
{
IDsCaptureDriverNotifyImpl *This = (IDsCaptureDriverNotifyImpl *)iface;
......@@ -159,6 +193,11 @@ static ULONG WINAPI IDsCaptureDriverNotifyImpl_Release(PIDSDRIVERNOTIFY iface)
if (!refCount) {
This->buffer->notify = NULL;
if (This->timerID)
{
timeKillEvent(This->timerID);
timeEndPeriod(DS_TIME_RES);
}
HeapFree(GetProcessHeap(), 0, This->notifies);
HeapFree(GetProcessHeap(), 0, This);
TRACE("(%p) released\n", This);
......@@ -204,6 +243,12 @@ static HRESULT WINAPI IDsCaptureDriverNotifyImpl_SetNotificationPositions(PIDSDR
This->nrofnotifies = howmuch;
IDsDriverBuffer_GetPosition((PIDSCDRIVERBUFFER)This->buffer, &This->playpos, NULL);
if (!This->timerID)
{
timeBeginPeriod(DS_TIME_RES);
This->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, Capture_Notify, (DWORD_PTR)This->buffer, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
}
LeaveCriticalSection(&This->buffer->pcm_crst);
/* **** */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment