From 18024afd9702b28d3195c5ff39056a2c98ac8c63 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B6rg=20H=C3=B6hle?= Date: Sun, 8 Jan 2012 16:35:43 +0100 Subject: [PATCH] winealsa: Fix AudioCaptureClient Get/ReleaseBuffer protocol. --- dlls/winealsa.drv/mmdevdrv.c | 63 ++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c index 0cb7b9b70aa..bcbe06c65ce 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 = -- 2.11.4.GIT