=?UTF-8?Q?J=C3=B6rg=20H=C3=B6hle=20?=: winealsa: Fix AudioCaptureClient Get /ReleaseBuffer protocol.

Alexandre Julliard julliard at winehq.org
Mon Jan 16 13:01:32 CST 2012


Module: wine
Branch: master
Commit: 18024afd9702b28d3195c5ff39056a2c98ac8c63
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=18024afd9702b28d3195c5ff39056a2c98ac8c63

Author: Jörg Höhle <hoehle at users.sourceforge.net>
Date:   Sun Jan  8 16:35:43 2012 +0100

winealsa: Fix AudioCaptureClient Get/ReleaseBuffer protocol.

---

 dlls/winealsa.drv/mmdevdrv.c |   63 +++++++++++++++++++++++++++--------------
 1 files changed, 41 insertions(+), 22 deletions(-)

diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index 0cb7b9b..bcbe06c 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -115,7 +115,6 @@ struct ACImpl {
 
     HANDLE timer;
     BYTE *local_buffer, *tmp_buffer;
-    int buf_state;
     long getbuf_last; /* <0 when using tmp_buffer */
 
     CRITICAL_SECTION lock;
@@ -126,12 +125,6 @@ struct ACImpl {
     struct list entry;
 };
 
-enum BufferStates {
-    NOT_LOCKED = 0,
-    LOCKED_NORMAL, /* public buffer piece is from local_buffer */
-    LOCKED_WRAPPED /* public buffer piece is wrapped around, in tmp_buffer */
-};
-
 typedef struct _SessionMgr {
     IAudioSessionManager2 IAudioSessionManager2_iface;
 
@@ -1757,7 +1750,7 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient *iface)
         return AUDCLNT_E_NOT_STOPPED;
     }
 
-    if(This->buf_state != NOT_LOCKED || This->getbuf_last){
+    if(This->getbuf_last){
         LeaveCriticalSection(&This->lock);
         return AUDCLNT_E_BUFFER_OPERATION_PENDING;
     }
@@ -2127,7 +2120,6 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
         UINT64 *qpcpos)
 {
     ACImpl *This = impl_from_IAudioCaptureClient(iface);
-    HRESULT hr;
 
     TRACE("(%p)->(%p, %p, %p, %p, %p)\n", This, data, frames, flags,
             devpos, qpcpos);
@@ -2137,18 +2129,18 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
 
     EnterCriticalSection(&This->lock);
 
-    if(This->buf_state != NOT_LOCKED){
+    if(This->getbuf_last){
         LeaveCriticalSection(&This->lock);
         return AUDCLNT_E_OUT_OF_ORDER;
     }
 
-    hr = IAudioCaptureClient_GetNextPacketSize(iface, frames);
-    if(FAILED(hr)){
+    /* hr = GetNextPacketSize(iface, frames); */
+    if(This->held_frames < This->mmdev_period_frames){
+        *frames = 0;
         LeaveCriticalSection(&This->lock);
-        return hr;
+        return AUDCLNT_S_BUFFER_EMPTY;
     }
-
-    *flags = 0;
+    *frames = This->mmdev_period_frames;
 
     if(This->lcl_offs_frames + *frames > This->bufsize_frames){
         UINT32 chunk_bytes, offs_bytes, frames_bytes;
@@ -2175,10 +2167,17 @@ static HRESULT WINAPI AudioCaptureClient_GetBuffer(IAudioCaptureClient *iface,
         *data = This->local_buffer +
             This->lcl_offs_frames * This->fmt->nBlockAlign;
 
-    This->buf_state = LOCKED_NORMAL;
+    This->getbuf_last = *frames;
+    *flags = 0;
 
-    if(devpos || qpcpos)
-        IAudioClock_GetPosition(&This->IAudioClock_iface, devpos, qpcpos);
+    if(devpos)
+      *devpos = This->written_frames;
+    if(qpcpos){ /* fixme: qpc of recording time */
+        LARGE_INTEGER stamp, freq;
+        QueryPerformanceCounter(&stamp);
+        QueryPerformanceFrequency(&freq);
+        *qpcpos = (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
+    }
 
     LeaveCriticalSection(&This->lock);
 
@@ -2194,16 +2193,27 @@ static HRESULT WINAPI AudioCaptureClient_ReleaseBuffer(
 
     EnterCriticalSection(&This->lock);
 
-    if(This->buf_state == NOT_LOCKED){
+    if(!done){
+        This->getbuf_last = 0;
+        LeaveCriticalSection(&This->lock);
+        return S_OK;
+    }
+
+    if(!This->getbuf_last){
         LeaveCriticalSection(&This->lock);
         return AUDCLNT_E_OUT_OF_ORDER;
     }
 
+    if(This->getbuf_last != done){
+        LeaveCriticalSection(&This->lock);
+        return AUDCLNT_E_INVALID_SIZE;
+    }
+
+    This->written_frames += done;
     This->held_frames -= done;
     This->lcl_offs_frames += done;
     This->lcl_offs_frames %= This->bufsize_frames;
-
-    This->buf_state = NOT_LOCKED;
+    This->getbuf_last = 0;
 
     LeaveCriticalSection(&This->lock);
 
@@ -2217,7 +2227,16 @@ static HRESULT WINAPI AudioCaptureClient_GetNextPacketSize(
 
     TRACE("(%p)->(%p)\n", This, frames);
 
-    return AudioClient_GetCurrentPadding(&This->IAudioClient_iface, frames);
+    if(!frames)
+        return E_POINTER;
+
+    EnterCriticalSection(&This->lock);
+
+    *frames = This->held_frames < This->mmdev_period_frames ? 0 : This->mmdev_period_frames;
+
+    LeaveCriticalSection(&This->lock);
+
+    return S_OK;
 }
 
 static const IAudioCaptureClientVtbl AudioCaptureClient_Vtbl =




More information about the wine-cvs mailing list