Signed-off-by: Huw Davies huw@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 */ };
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Tue, Nov 23, 2021 at 07:55:01AM +0000, Huw Davies wrote:
Signed-off-by: Huw Davies huw@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