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