[PATCH 04/12] winecoreaudio: Move get_latency to the unixlib.
Andrew Eikum
aeikum at codeweavers.com
Tue Nov 23 09:22:32 CST 2021
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
On Tue, Nov 23, 2021 at 07:55:01AM +0000, Huw Davies wrote:
> Signed-off-by: Huw Davies <huw at codeweavers.com>
> ---
> dlls/winecoreaudio.drv/coreaudio.c | 93 ++++++++++++++++++++++
> dlls/winecoreaudio.drv/mmdevdrv.c | 119 ++---------------------------
> dlls/winecoreaudio.drv/unixlib.h | 8 ++
> 3 files changed, 109 insertions(+), 111 deletions(-)
>
> diff --git a/dlls/winecoreaudio.drv/coreaudio.c b/dlls/winecoreaudio.drv/coreaudio.c
> index 56504a8b7b0..2d5aa29555a 100644
> --- a/dlls/winecoreaudio.drv/coreaudio.c
> +++ b/dlls/winecoreaudio.drv/coreaudio.c
> @@ -1127,6 +1127,98 @@ static NTSTATUS get_buffer_size(void *args)
> return STATUS_SUCCESS;
> }
>
> +static HRESULT ca_get_max_stream_latency(struct coreaudio_stream *stream, UInt32 *max)
> +{
> + AudioObjectPropertyAddress addr;
> + AudioStreamID *ids;
> + UInt32 size;
> + OSStatus sc;
> + int nstreams, i;
> +
> + addr.mScope = get_scope(stream->flow);
> + addr.mElement = 0;
> + addr.mSelector = kAudioDevicePropertyStreams;
> +
> + sc = AudioObjectGetPropertyDataSize(stream->dev_id, &addr, 0, NULL, &size);
> + if(sc != noErr){
> + WARN("Unable to get size for _Streams property: %x\n", (int)sc);
> + return osstatus_to_hresult(sc);
> + }
> +
> + ids = malloc(size);
> + if(!ids)
> + return E_OUTOFMEMORY;
> +
> + sc = AudioObjectGetPropertyData(stream->dev_id, &addr, 0, NULL, &size, ids);
> + if(sc != noErr){
> + WARN("Unable to get _Streams property: %x\n", (int)sc);
> + free(ids);
> + return osstatus_to_hresult(sc);
> + }
> +
> + nstreams = size / sizeof(AudioStreamID);
> + *max = 0;
> +
> + addr.mSelector = kAudioStreamPropertyLatency;
> + for(i = 0; i < nstreams; ++i){
> + UInt32 latency;
> +
> + size = sizeof(latency);
> + sc = AudioObjectGetPropertyData(ids[i], &addr, 0, NULL, &size, &latency);
> + if(sc != noErr){
> + WARN("Unable to get _Latency property: %x\n", (int)sc);
> + continue;
> + }
> +
> + if(latency > *max)
> + *max = latency;
> + }
> +
> + free(ids);
> +
> + return S_OK;
> +}
> +
> +static NTSTATUS get_latency(void *args)
> +{
> + struct get_latency_params *params = args;
> + struct coreaudio_stream *stream = params->stream;
> + UInt32 latency, stream_latency, size;
> + AudioObjectPropertyAddress addr;
> + OSStatus sc;
> +
> + OSSpinLockLock(&stream->lock);
> +
> + addr.mScope = get_scope(stream->flow);
> + addr.mSelector = kAudioDevicePropertyLatency;
> + addr.mElement = 0;
> +
> + size = sizeof(latency);
> + sc = AudioObjectGetPropertyData(stream->dev_id, &addr, 0, NULL, &size, &latency);
> + if(sc != noErr){
> + WARN("Couldn't get _Latency property: %x\n", (int)sc);
> + OSSpinLockUnlock(&stream->lock);
> + params->result = osstatus_to_hresult(sc);
> + return STATUS_SUCCESS;
> + }
> +
> + params->result = ca_get_max_stream_latency(stream, &stream_latency);
> + if(FAILED(params->result)){
> + OSSpinLockUnlock(&stream->lock);
> + return STATUS_SUCCESS;
> + }
> +
> + latency += stream_latency;
> + /* pretend we process audio in Period chunks, so max latency includes
> + * the period time */
> + *params->latency = muldiv(latency, 10000000, stream->fmt->nSamplesPerSec)
> + + stream->period_ms * 10000;
> +
> + OSSpinLockUnlock(&stream->lock);
> + params->result = S_OK;
> + return STATUS_SUCCESS;
> +}
> +
> unixlib_entry_t __wine_unix_call_funcs[] =
> {
> get_endpoint_ids,
> @@ -1135,6 +1227,7 @@ unixlib_entry_t __wine_unix_call_funcs[] =
> get_mix_format,
> is_format_supported,
> get_buffer_size,
> + get_latency,
>
> capture_resample /* temporary */
> };
> diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
> index cd33cababd1..63deb458f1a 100644
> --- a/dlls/winecoreaudio.drv/mmdevdrv.c
> +++ b/dlls/winecoreaudio.drv/mmdevdrv.c
> @@ -130,7 +130,6 @@ struct ACImpl {
> float *vols;
>
> AudioDeviceID adevid;
> - AudioObjectPropertyScope scope;
> HANDLE timer;
>
> AudioSession *session;
> @@ -263,19 +262,6 @@ int WINAPI AUDDRV_GetPriority(void)
> return Priority_Neutral;
> }
>
> -static HRESULT osstatus_to_hresult(OSStatus sc)
> -{
> - switch(sc){
> - case kAudioFormatUnsupportedDataFormatError:
> - case kAudioFormatUnknownFormatError:
> - case kAudioDeviceUnsupportedFormatError:
> - return AUDCLNT_E_UNSUPPORTED_FORMAT;
> - case kAudioHardwareBadDeviceError:
> - return AUDCLNT_E_DEVICE_INVALIDATED;
> - }
> - return E_FAIL;
> -}
> -
> static void set_device_guid(EDataFlow flow, HKEY drv_key, const WCHAR *key_name,
> GUID *guid)
> {
> @@ -481,6 +467,9 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
> if(!get_deviceid_by_guid(guid, &adevid, &dataflow))
> return AUDCLNT_E_DEVICE_INVALIDATED;
>
> + if(dataflow != eRender && dataflow != eCapture)
> + return E_INVALIDARG;
> +
> This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACImpl));
> if(!This)
> return E_OUTOFMEMORY;
> @@ -494,15 +483,6 @@ HRESULT WINAPI AUDDRV_GetAudioEndpoint(GUID *guid, IMMDevice *dev, IAudioClient
>
> This->dataflow = dataflow;
>
> - if(dataflow == eRender)
> - This->scope = kAudioDevicePropertyScopeOutput;
> - else if(dataflow == eCapture)
> - This->scope = kAudioDevicePropertyScopeInput;
> - else{
> - HeapFree(GetProcessHeap(), 0, This);
> - return E_INVALIDARG;
> - }
> -
> hr = CoCreateFreeThreadedMarshaler((IUnknown *)&This->IAudioClient3_iface, &This->pUnkFTMarshal);
> if (FAILED(hr)) {
> HeapFree(GetProcessHeap(), 0, This);
> @@ -871,68 +851,11 @@ static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface,
> return params.result;
> }
>
> -static HRESULT ca_get_max_stream_latency(ACImpl *This, UInt32 *max)
> -{
> - AudioObjectPropertyAddress addr;
> - AudioStreamID *ids;
> - UInt32 size;
> - OSStatus sc;
> - int nstreams, i;
> -
> - addr.mScope = This->scope;
> - addr.mElement = 0;
> - addr.mSelector = kAudioDevicePropertyStreams;
> -
> - sc = AudioObjectGetPropertyDataSize(This->adevid, &addr, 0, NULL,
> - &size);
> - if(sc != noErr){
> - WARN("Unable to get size for _Streams property: %x\n", (int)sc);
> - return osstatus_to_hresult(sc);
> - }
> -
> - ids = HeapAlloc(GetProcessHeap(), 0, size);
> - if(!ids)
> - return E_OUTOFMEMORY;
> -
> - sc = AudioObjectGetPropertyData(This->adevid, &addr, 0, NULL, &size, ids);
> - if(sc != noErr){
> - WARN("Unable to get _Streams property: %x\n", (int)sc);
> - HeapFree(GetProcessHeap(), 0, ids);
> - return osstatus_to_hresult(sc);
> - }
> -
> - nstreams = size / sizeof(AudioStreamID);
> - *max = 0;
> -
> - addr.mSelector = kAudioStreamPropertyLatency;
> - for(i = 0; i < nstreams; ++i){
> - UInt32 latency;
> -
> - size = sizeof(latency);
> - sc = AudioObjectGetPropertyData(ids[i], &addr, 0, NULL,
> - &size, &latency);
> - if(sc != noErr){
> - WARN("Unable to get _Latency property: %x\n", (int)sc);
> - continue;
> - }
> -
> - if(latency > *max)
> - *max = latency;
> - }
> -
> - HeapFree(GetProcessHeap(), 0, ids);
> -
> - return S_OK;
> -}
> -
> static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
> REFERENCE_TIME *out)
> {
> ACImpl *This = impl_from_IAudioClient3(iface);
> - UInt32 latency, stream_latency, size;
> - AudioObjectPropertyAddress addr;
> - OSStatus sc;
> - HRESULT hr;
> + struct get_latency_params params;
>
> TRACE("(%p)->(%p)\n", This, out);
>
> @@ -942,36 +865,10 @@ static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface,
> if(!This->stream)
> return AUDCLNT_E_NOT_INITIALIZED;
>
> - OSSpinLockLock(&This->stream->lock);
> -
> - addr.mScope = This->scope;
> - addr.mSelector = kAudioDevicePropertyLatency;
> - addr.mElement = 0;
> -
> - size = sizeof(latency);
> - sc = AudioObjectGetPropertyData(This->adevid, &addr, 0, NULL,
> - &size, &latency);
> - if(sc != noErr){
> - WARN("Couldn't get _Latency property: %x\n", (int)sc);
> - OSSpinLockUnlock(&This->stream->lock);
> - return osstatus_to_hresult(sc);
> - }
> -
> - hr = ca_get_max_stream_latency(This, &stream_latency);
> - if(FAILED(hr)){
> - OSSpinLockUnlock(&This->stream->lock);
> - return hr;
> - }
> -
> - latency += stream_latency;
> - /* pretend we process audio in Period chunks, so max latency includes
> - * the period time */
> - *out = MulDiv(latency, 10000000, This->stream->fmt->nSamplesPerSec)
> - + This->stream->period_ms * 10000;
> -
> - OSSpinLockUnlock(&This->stream->lock);
> -
> - return S_OK;
> + params.stream = This->stream;
> + params.latency = out;
> + UNIX_CALL(get_latency, ¶ms);
> + return params.result;
> }
>
> static HRESULT AudioClient_GetCurrentPadding_nolock(ACImpl *This,
> diff --git a/dlls/winecoreaudio.drv/unixlib.h b/dlls/winecoreaudio.drv/unixlib.h
> index 7e08b347b02..dd86cd81973 100644
> --- a/dlls/winecoreaudio.drv/unixlib.h
> +++ b/dlls/winecoreaudio.drv/unixlib.h
> @@ -100,6 +100,13 @@ struct get_buffer_size_params
> UINT32 *frames;
> };
>
> +struct get_latency_params
> +{
> + struct coreaudio_stream *stream;
> + HRESULT result;
> + REFERENCE_TIME *latency;
> +};
> +
> enum unix_funcs
> {
> unix_get_endpoint_ids,
> @@ -108,6 +115,7 @@ enum unix_funcs
> unix_get_mix_format,
> unix_is_format_supported,
> unix_get_buffer_size,
> + unix_get_latency,
>
> unix_capture_resample /* temporary */
> };
> --
> 2.23.0
>
>
More information about the wine-devel
mailing list