From: Claire Girka claire@sitedethib.com
pulse_name should always match a valid device, the default audio device with an empty name is one of them. --- dlls/winepulse.drv/mmdevdrv.c | 21 ++++++++++++++---- dlls/winepulse.drv/pulse.c | 42 +++++++++++++++++++++++++++++++++++ dlls/winepulse.drv/unixlib.h | 9 ++++++++ 3 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 3cbbc1d8115..61875b7352d 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -1136,17 +1136,30 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface, WAVEFORMATEX **pwfx) { ACImpl *This = impl_from_IAudioClient3(iface); + struct get_mix_format_params params;
TRACE("(%p)->(%p)\n", This, pwfx);
if (!pwfx) return E_POINTER; + *pwfx = NULL;
- *pwfx = clone_format(&pulse_config.modes[This->dataflow == eCapture].format.Format); - if (!*pwfx) + params.pulse_name = This->pulse_name; + params.flow = This->dataflow; + params.fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE)); + if (!params.fmt) return E_OUTOFMEMORY; - dump_fmt(*pwfx); - return S_OK; + + pulse_call(get_mix_format, ¶ms); + + if (SUCCEEDED(params.result)) { + *pwfx = ¶ms.fmt->Format; + dump_fmt(*pwfx); + } else { + CoTaskMemFree(params.fmt); + } + + return params.result; }
static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface, diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index 04795854fbc..4e32fa4093d 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -2029,6 +2029,26 @@ static NTSTATUS pulse_release_capture_buffer(void *args) return STATUS_SUCCESS; }
+static NTSTATUS pulse_get_mix_format(void *args) +{ + struct get_mix_format_params *params = args; + struct list *list = (params->flow == eRender) ? &g_phys_speakers : &g_phys_sources; + PhysDevice *dev; + + LIST_FOR_EACH_ENTRY(dev, list, PhysDevice, entry) { + if (strcmp(params->pulse_name, dev->pulse_name)) + continue; + + *params->fmt = dev->fmt; + params->result = S_OK; + + return STATUS_SUCCESS; + } + + params->result = E_FAIL; + return STATUS_SUCCESS; +} + static NTSTATUS pulse_get_buffer_size(void *args) { struct get_buffer_size_params *params = args; @@ -2308,6 +2328,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = pulse_release_render_buffer, pulse_get_capture_buffer, pulse_release_capture_buffer, + pulse_get_mix_format, pulse_get_buffer_size, pulse_get_latency, pulse_get_current_padding, @@ -2463,6 +2484,26 @@ static NTSTATUS pulse_wow64_get_capture_buffer(void *args) return STATUS_SUCCESS; };
+static NTSTATUS pulse_wow64_get_mix_format(void *args) +{ + struct + { + PTR32 pulse_name; + EDataFlow flow; + PTR32 fmt; + HRESULT result; + } *params32 = args; + struct get_mix_format_params params = + { + .pulse_name = ULongToPtr(params32->pulse_name), + .flow = params32->flow, + .fmt = ULongToPtr(params32->fmt), + }; + pulse_get_mix_format(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + static NTSTATUS pulse_wow64_get_buffer_size(void *args) { struct @@ -2689,6 +2730,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = pulse_release_render_buffer, pulse_wow64_get_capture_buffer, pulse_release_capture_buffer, + pulse_wow64_get_mix_format, pulse_wow64_get_buffer_size, pulse_wow64_get_latency, pulse_wow64_get_current_padding, diff --git a/dlls/winepulse.drv/unixlib.h b/dlls/winepulse.drv/unixlib.h index f224f26c909..b6a19ddeb96 100644 --- a/dlls/winepulse.drv/unixlib.h +++ b/dlls/winepulse.drv/unixlib.h @@ -138,6 +138,14 @@ struct release_capture_buffer_params HRESULT result; };
+struct get_mix_format_params +{ + const char *pulse_name; + EDataFlow flow; + WAVEFORMATEXTENSIBLE *fmt; + HRESULT result; +}; + struct get_buffer_size_params { stream_handle stream; @@ -241,6 +249,7 @@ enum unix_funcs release_render_buffer, get_capture_buffer, release_capture_buffer, + get_mix_format, get_buffer_size, get_latency, get_current_padding,