Commit 2b51d38d authored by Jörg Höhle's avatar Jörg Höhle Committed by Alexandre Julliard

winealsa: Fix AudioRenderClient Get/ReleaseBuffer protocol.

parent 7f7bc520
...@@ -116,6 +116,7 @@ struct ACImpl { ...@@ -116,6 +116,7 @@ struct ACImpl {
HANDLE timer; HANDLE timer;
BYTE *local_buffer, *tmp_buffer; BYTE *local_buffer, *tmp_buffer;
int buf_state; int buf_state;
long getbuf_last; /* <0 when using tmp_buffer */
CRITICAL_SECTION lock; CRITICAL_SECTION lock;
...@@ -1763,7 +1764,7 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient *iface) ...@@ -1763,7 +1764,7 @@ static HRESULT WINAPI AudioClient_Reset(IAudioClient *iface)
return AUDCLNT_E_NOT_STOPPED; return AUDCLNT_E_NOT_STOPPED;
} }
if(This->buf_state != NOT_LOCKED){ if(This->buf_state != NOT_LOCKED || This->getbuf_last){
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
return AUDCLNT_E_BUFFER_OPERATION_PENDING; return AUDCLNT_E_BUFFER_OPERATION_PENDING;
} }
...@@ -1964,16 +1965,16 @@ static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface, ...@@ -1964,16 +1965,16 @@ static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface,
if(!data) if(!data)
return E_POINTER; return E_POINTER;
*data = NULL;
EnterCriticalSection(&This->lock); EnterCriticalSection(&This->lock);
if(This->buf_state != NOT_LOCKED){ if(This->getbuf_last){
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
return AUDCLNT_E_OUT_OF_ORDER; return AUDCLNT_E_OUT_OF_ORDER;
} }
if(!frames){ if(!frames){
This->buf_state = LOCKED_NORMAL;
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
return S_OK; return S_OK;
} }
...@@ -2003,10 +2004,10 @@ static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface, ...@@ -2003,10 +2004,10 @@ static HRESULT WINAPI AudioRenderClient_GetBuffer(IAudioRenderClient *iface,
This->tmp_buffer_frames = frames; This->tmp_buffer_frames = frames;
} }
*data = This->tmp_buffer; *data = This->tmp_buffer;
This->buf_state = LOCKED_WRAPPED; This->getbuf_last = -frames;
}else{ }else{
*data = This->local_buffer + write_pos * This->fmt->nBlockAlign; *data = This->local_buffer + write_pos * This->fmt->nBlockAlign;
This->buf_state = LOCKED_NORMAL; This->getbuf_last = frames;
} }
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
...@@ -2042,13 +2043,23 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer( ...@@ -2042,13 +2043,23 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer(
EnterCriticalSection(&This->lock); EnterCriticalSection(&This->lock);
if(This->buf_state == NOT_LOCKED || !written_frames){ if(!written_frames){
This->buf_state = NOT_LOCKED; This->getbuf_last = 0;
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
return written_frames ? AUDCLNT_E_OUT_OF_ORDER : S_OK; return S_OK;
} }
if(This->buf_state == LOCKED_NORMAL) if(!This->getbuf_last){
LeaveCriticalSection(&This->lock);
return AUDCLNT_E_OUT_OF_ORDER;
}
if(written_frames > (This->getbuf_last >= 0 ? This->getbuf_last : -This->getbuf_last)){
LeaveCriticalSection(&This->lock);
return AUDCLNT_E_INVALID_SIZE;
}
if(This->getbuf_last >= 0)
buffer = This->local_buffer + This->fmt->nBlockAlign * buffer = This->local_buffer + This->fmt->nBlockAlign *
((This->lcl_offs_frames + This->held_frames) % This->bufsize_frames); ((This->lcl_offs_frames + This->held_frames) % This->bufsize_frames);
else else
...@@ -2061,12 +2072,12 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer( ...@@ -2061,12 +2072,12 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer(
memset(buffer, 0, written_frames * This->fmt->nBlockAlign); memset(buffer, 0, written_frames * This->fmt->nBlockAlign);
} }
if(This->buf_state == LOCKED_WRAPPED) if(This->getbuf_last < 0)
alsa_wrap_buffer(This, buffer, written_frames); alsa_wrap_buffer(This, buffer, written_frames);
This->held_frames += written_frames; This->held_frames += written_frames;
This->written_frames += written_frames; This->written_frames += written_frames;
This->buf_state = NOT_LOCKED; This->getbuf_last = 0;
LeaveCriticalSection(&This->lock); LeaveCriticalSection(&This->lock);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment