[PATCH 04/12] winecoreaudio: Move get_latency to the unixlib.

Huw Davies huw at codeweavers.com
Tue Nov 23 01:55:01 CST 2021


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