Module: wine Branch: master Commit: 18024afd9702b28d3195c5ff39056a2c98ac8c63 URL: http://source.winehq.org/git/wine.git/?a=commit;h=18024afd9702b28d3195c5ff39...
Author: Jörg Höhle hoehle@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 =