Module: wine Branch: master Commit: 894cf6dbafadca570080a04dfe1dfb0d41427b3e URL: http://source.winehq.org/git/wine.git/?a=commit;h=894cf6dbafadca570080a04dfe...
Author: Maarten Lankhorst m.b.lankhorst@gmail.com Date: Tue Sep 11 18:19:53 2007 +0200
winealsa: Add a timer check to capture to see if play notifications have been triggered.
---
dlls/winealsa.drv/dscapture.c | 47 ++++++++++++++++++++++++++++++++++++++++- 1 files changed, 46 insertions(+), 1 deletions(-)
diff --git a/dlls/winealsa.drv/dscapture.c b/dlls/winealsa.drv/dscapture.c index 8e409d7..8c2d9f5 100644 --- a/dlls/winealsa.drv/dscapture.c +++ b/dlls/winealsa.drv/dscapture.c @@ -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); /* **** */