Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/winecoreaudio.drv/coreaudio.c | 45 ++++++++++++++++++ dlls/winecoreaudio.drv/mmdevdrv.c | 73 +++--------------------------- dlls/winecoreaudio.drv/unixlib.h | 9 ++++ 3 files changed, 60 insertions(+), 67 deletions(-)
diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c index 0bf21cd6c7d..2519a6bcfaa 100644 --- a/dlls/winecoreaudio.drv/coreaudio.c +++ b/dlls/winecoreaudio.drv/coreaudio.c @@ -1358,6 +1358,50 @@ end: return STATUS_SUCCESS; }
+static NTSTATUS release_render_buffer(void *args) +{ + struct release_render_buffer_params *params = args; + struct coreaudio_stream *stream = params->stream; + BYTE *buffer; + + OSSpinLockLock(&stream->lock); + + if(!params->frames){ + stream->getbuf_last = 0; + params->result = S_OK; + }else if(!stream->getbuf_last) + params->result = AUDCLNT_E_OUT_OF_ORDER; + else if(params->frames > (stream->getbuf_last >= 0 ? stream->getbuf_last : -stream->getbuf_last)) + params->result = AUDCLNT_E_INVALID_SIZE; + else{ + if(stream->getbuf_last >= 0) + buffer = stream->local_buffer + stream->wri_offs_frames * stream->fmt->nBlockAlign; + else + buffer = stream->tmp_buffer; + + if(params->flags & AUDCLNT_BUFFERFLAGS_SILENT) + silence_buffer(stream, buffer, params->frames); + + if(stream->getbuf_last < 0) + ca_wrap_buffer(stream->local_buffer, + stream->wri_offs_frames * stream->fmt->nBlockAlign, + stream->bufsize_frames * stream->fmt->nBlockAlign, + buffer, params->frames * stream->fmt->nBlockAlign); + + stream->wri_offs_frames += params->frames; + stream->wri_offs_frames %= stream->bufsize_frames; + stream->held_frames += params->frames; + stream->written_frames += params->frames; + stream->getbuf_last = 0; + + params->result = S_OK; + } + + OSSpinLockUnlock(&stream->lock); + + return STATUS_SUCCESS; +} + unixlib_entry_t __wine_unix_call_funcs[] = { get_endpoint_ids, @@ -1367,6 +1411,7 @@ unixlib_entry_t __wine_unix_call_funcs[] = stop, reset, get_render_buffer, + release_render_buffer, get_mix_format, is_format_supported, get_buffer_size, diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c index 5dca497594a..1874382304b 100644 --- a/dlls/winecoreaudio.drv/mmdevdrv.c +++ b/dlls/winecoreaudio.drv/mmdevdrv.c @@ -683,30 +683,6 @@ static HRESULT get_audio_session(const GUID *sessionguid, return S_OK; }
-static void ca_wrap_buffer(BYTE *dst, UINT32 dst_offs, UINT32 dst_bytes, - BYTE *src, UINT32 src_bytes) -{ - UINT32 chunk_bytes = dst_bytes - dst_offs; - - if(chunk_bytes < src_bytes){ - memcpy(dst + dst_offs, src, chunk_bytes); - memcpy(dst, src + chunk_bytes, src_bytes - chunk_bytes); - }else - memcpy(dst + dst_offs, src, src_bytes); -} - -static void silence_buffer(struct coreaudio_stream *stream, BYTE *buffer, UINT32 frames) -{ - WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)stream->fmt; - if((stream->fmt->wFormatTag == WAVE_FORMAT_PCM || - (stream->fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE && - IsEqualGUID(&fmtex->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM))) && - stream->fmt->wBitsPerSample == 8) - memset(buffer, 128, frames * stream->fmt->nBlockAlign); - else - memset(buffer, 0, frames * stream->fmt->nBlockAlign); -} - static void capture_resample(ACImpl *This) { UNIX_CALL(capture_resample, This->stream); @@ -1322,52 +1298,15 @@ static HRESULT WINAPI AudioRenderClient_ReleaseBuffer( IAudioRenderClient *iface, UINT32 frames, DWORD flags) { ACImpl *This = impl_from_IAudioRenderClient(iface); - BYTE *buffer; + struct release_render_buffer_params params;
TRACE("(%p)->(%u, %x)\n", This, frames, flags);
- OSSpinLockLock(&This->stream->lock); - - if(!frames){ - This->stream->getbuf_last = 0; - OSSpinLockUnlock(&This->stream->lock); - return S_OK; - } - - if(!This->stream->getbuf_last){ - OSSpinLockUnlock(&This->stream->lock); - return AUDCLNT_E_OUT_OF_ORDER; - } - - if(frames > (This->stream->getbuf_last >= 0 ? This->stream->getbuf_last : -This->stream->getbuf_last)){ - OSSpinLockUnlock(&This->stream->lock); - return AUDCLNT_E_INVALID_SIZE; - } - - if(This->stream->getbuf_last >= 0) - buffer = This->stream->local_buffer + This->stream->wri_offs_frames * This->stream->fmt->nBlockAlign; - else - buffer = This->stream->tmp_buffer; - - if(flags & AUDCLNT_BUFFERFLAGS_SILENT) - silence_buffer(This->stream, buffer, frames); - - if(This->stream->getbuf_last < 0) - ca_wrap_buffer(This->stream->local_buffer, - This->stream->wri_offs_frames * This->stream->fmt->nBlockAlign, - This->stream->bufsize_frames * This->stream->fmt->nBlockAlign, - buffer, frames * This->stream->fmt->nBlockAlign); - - - This->stream->wri_offs_frames += frames; - This->stream->wri_offs_frames %= This->stream->bufsize_frames; - This->stream->held_frames += frames; - This->stream->written_frames += frames; - This->stream->getbuf_last = 0; - - OSSpinLockUnlock(&This->stream->lock); - - return S_OK; + params.stream = This->stream; + params.frames = frames; + params.flags = flags; + UNIX_CALL(release_render_buffer, ¶ms); + return params.result; }
static const IAudioRenderClientVtbl AudioRenderClient_Vtbl = { diff --git a/dlls/winecoreaudio.drv/unixlib.h b/dlls/winecoreaudio.drv/unixlib.h index e2ae457e705..80f42741e34 100644 --- a/dlls/winecoreaudio.drv/unixlib.h +++ b/dlls/winecoreaudio.drv/unixlib.h @@ -101,6 +101,14 @@ struct get_render_buffer_params BYTE **data; };
+struct release_render_buffer_params +{ + struct coreaudio_stream *stream; + UINT32 frames; + DWORD flags; + HRESULT result; +}; + struct get_mix_format_params { EDataFlow flow; @@ -149,6 +157,7 @@ enum unix_funcs unix_stop, unix_reset, unix_get_render_buffer, + unix_release_render_buffer, unix_get_mix_format, unix_is_format_supported, unix_get_buffer_size,