[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, &params);
> +    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