Module: wine Branch: master Commit: 9ef54e4ebee50a6cdef70138ba22db6b3167e2c3 URL: http://source.winehq.org/git/wine.git/?a=commit;h=9ef54e4ebee50a6cdef70138ba...
Author: Ken Thomases ken@codeweavers.com Date: Thu Dec 28 11:06:43 2006 -0600
winecoreaudio: Add widHelper_NotifyCompletions.
It scans for completed input wavehdrs, removes them from the queue, and notifies the application that they're done.
---
dlls/winmm/winecoreaudio/audio.c | 50 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/dlls/winmm/winecoreaudio/audio.c b/dlls/winmm/winecoreaudio/audio.c index 2a13f8d..607b711 100644 --- a/dlls/winmm/winecoreaudio/audio.c +++ b/dlls/winmm/winecoreaudio/audio.c @@ -202,6 +202,7 @@ static CFMessagePortRef Port_SendToMessa
static void wodHelper_PlayPtrNext(WINE_WAVEOUT* wwo); static void wodHelper_NotifyCompletions(WINE_WAVEOUT* wwo, BOOL force); +static void widHelper_NotifyCompletions(WINE_WAVEIN* wwi);
extern int AudioUnit_CreateDefaultAudioUnit(void *wwo, AudioUnit *au); extern int AudioUnit_CloseAudioUnit(AudioUnit au); @@ -1504,6 +1505,55 @@ static DWORD widNotifyClient(WINE_WAVEIN
/************************************************************************** + * widHelper_NotifyCompletions [internal] + */ +static void widHelper_NotifyCompletions(WINE_WAVEIN* wwi) +{ + LPWAVEHDR lpWaveHdr; + LPWAVEHDR lpFirstDoneWaveHdr = NULL; + LPWAVEHDR lpLastDoneWaveHdr = NULL; + + OSSpinLockLock(&wwi->lock); + + /* First, excise all of the done headers from the queue into + * a free-standing list. */ + + /* Start from lpQueuePtr and keep notifying until: + * - we hit an unfilled wavehdr + * - we hit the end of the list + */ + for ( + lpWaveHdr = wwi->lpQueuePtr; + lpWaveHdr && + lpWaveHdr->dwBytesRecorded >= lpWaveHdr->dwBufferLength; + lpWaveHdr = lpWaveHdr->lpNext + ) + { + if (!lpFirstDoneWaveHdr) + lpFirstDoneWaveHdr = lpWaveHdr; + lpLastDoneWaveHdr = lpWaveHdr; + } + + if (lpLastDoneWaveHdr) + { + wwi->lpQueuePtr = lpLastDoneWaveHdr->lpNext; + lpLastDoneWaveHdr->lpNext = NULL; + } + + OSSpinLockUnlock(&wwi->lock); + + /* Now, send the "done" notification for each header in our list. */ + for (lpWaveHdr = lpFirstDoneWaveHdr; lpWaveHdr; lpWaveHdr = lpWaveHdr->lpNext) + { + lpWaveHdr->dwFlags &= ~WHDR_INQUEUE; + lpWaveHdr->dwFlags |= WHDR_DONE; + + widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0); + } +} + + +/************************************************************************** * widGetDevCaps [internal] */ static DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPSW lpCaps, DWORD dwSize)