From: Claire Girka claire@sitedethib.com
--- dlls/winepulse.drv/mmdevdrv.c | 13 +++++--- dlls/winepulse.drv/pulse.c | 57 +++++++++++++++++++++++++++++++++++ dlls/winepulse.drv/unixlib.h | 10 ++++++ 3 files changed, 75 insertions(+), 5 deletions(-)
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 61875b7352d..6b78a56388b 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -1165,6 +1165,7 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface, static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface, REFERENCE_TIME *defperiod, REFERENCE_TIME *minperiod) { + struct get_device_period_params params; ACImpl *This = impl_from_IAudioClient3(iface);
TRACE("(%p)->(%p, %p)\n", This, defperiod, minperiod); @@ -1172,12 +1173,14 @@ static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface, if (!defperiod && !minperiod) return E_POINTER;
- if (defperiod) - *defperiod = pulse_config.modes[This->dataflow == eCapture].def_period; - if (minperiod) - *minperiod = pulse_config.modes[This->dataflow == eCapture].min_period; + params.flow = This->dataflow; + params.pulse_name = This->pulse_name; + params.def_period = defperiod; + params.min_period = minperiod;
- return S_OK; + pulse_call(get_device_period, ¶ms); + + return params.result; }
static HRESULT WINAPI AudioClient_Start(IAudioClient3 *iface) diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index 552fb205627..b5b9231bdb4 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -764,6 +764,39 @@ static NTSTATUS pulse_get_mix_format(void *args) return STATUS_SUCCESS; }
+static NTSTATUS pulse_get_device_period(void *args) +{ + struct get_device_period_params *params = args; + struct list *list = (params->flow == eRender) ? &g_phys_speakers : &g_phys_sources; + PhysDevice *dev; + + if (!params->def_period && !params->min_period) { + params->result = E_POINTER; + return STATUS_SUCCESS; + } + + LIST_FOR_EACH_ENTRY(dev, list, PhysDevice, entry) { + if (strcmp(params->pulse_name, dev->pulse_name)) + continue; + + if (params->def_period) + *params->def_period = dev->def_period; + if (params->min_period) + *params->min_period = dev->min_period; + params->result = S_OK; + + return STATUS_SUCCESS; + } + + if (params->def_period) + *params->def_period = pulse_def_period[params->flow == eCapture]; + if (params->min_period) + *params->min_period = pulse_min_period[params->flow == eCapture]; + params->result = S_OK; + + return STATUS_SUCCESS; +} + /* some poorly-behaved applications call audio functions during DllMain, so we * have to do as much as possible without creating a new thread. this function * sets up a synchronous connection to verify the server is running and query @@ -2342,6 +2375,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = pulse_is_started, pulse_get_prop_value, pulse_get_mix_format, + pulse_get_device_period, };
#ifdef _WIN64 @@ -2716,6 +2750,28 @@ static NTSTATUS pulse_wow64_get_mix_format(void *args) return STATUS_SUCCESS; }
+static NTSTATUS pulse_wow64_get_device_period(void *args) +{ + struct + { + PTR32 pulse_name; + EDataFlow flow; + HRESULT result; + PTR32 def_period; + PTR32 min_period; + } *params32 = args; + struct get_device_period_params params = + { + .pulse_name = ULongToPtr(params32->pulse_name), + .flow = params32->flow, + .def_period = ULongToPtr(params32->def_period), + .min_period = ULongToPtr(params32->min_period), + }; + pulse_get_device_period(¶ms); + params32->result = params.result; + return STATUS_SUCCESS; +} + const unixlib_entry_t __wine_unix_call_wow64_funcs[] = { pulse_process_attach, @@ -2744,6 +2800,7 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = pulse_is_started, pulse_wow64_get_prop_value, pulse_wow64_get_mix_format, + pulse_wow64_get_device_period, };
#endif /* _WIN64 */ diff --git a/dlls/winepulse.drv/unixlib.h b/dlls/winepulse.drv/unixlib.h index 95e9dac65b8..51d6baf500a 100644 --- a/dlls/winepulse.drv/unixlib.h +++ b/dlls/winepulse.drv/unixlib.h @@ -167,6 +167,15 @@ struct get_mix_format_params WAVEFORMATEXTENSIBLE *fmt; };
+struct get_device_period_params +{ + const char *pulse_name; + EDataFlow flow; + HRESULT result; + REFERENCE_TIME *def_period; + REFERENCE_TIME *min_period; +}; + struct get_next_packet_size_params { stream_handle stream; @@ -261,4 +270,5 @@ enum unix_funcs is_started, get_prop_value, get_mix_format, + get_device_period, };