From: Davide Beatrici git@davidebeatrici.dev
--- dlls/mmdevapi/client.c | 174 ++++++++++++++++++++++++++++++++++ dlls/winepulse.drv/mmdevdrv.c | 135 +++----------------------- 2 files changed, 189 insertions(+), 120 deletions(-)
diff --git a/dlls/mmdevapi/client.c b/dlls/mmdevapi/client.c index 219d4753afa..8b567571b90 100644 --- a/dlls/mmdevapi/client.c +++ b/dlls/mmdevapi/client.c @@ -80,6 +80,40 @@ static inline struct audio_client *impl_from_IAudioStreamVolume(IAudioStreamVolu return CONTAINING_RECORD(iface, struct audio_client, IAudioStreamVolume_iface); }
+static void dump_fmt(const WAVEFORMATEX *fmt) +{ + TRACE("wFormatTag: 0x%x (", fmt->wFormatTag); + switch (fmt->wFormatTag) { + case WAVE_FORMAT_PCM: + TRACE("WAVE_FORMAT_PCM"); + break; + case WAVE_FORMAT_IEEE_FLOAT: + TRACE("WAVE_FORMAT_IEEE_FLOAT"); + break; + case WAVE_FORMAT_EXTENSIBLE: + TRACE("WAVE_FORMAT_EXTENSIBLE"); + break; + default: + TRACE("Unknown"); + break; + } + TRACE(")\n"); + + TRACE("nChannels: %u\n", fmt->nChannels); + TRACE("nSamplesPerSec: %lu\n", fmt->nSamplesPerSec); + TRACE("nAvgBytesPerSec: %lu\n", fmt->nAvgBytesPerSec); + TRACE("nBlockAlign: %u\n", fmt->nBlockAlign); + TRACE("wBitsPerSample: %u\n", fmt->wBitsPerSample); + TRACE("cbSize: %u\n", fmt->cbSize); + + if (fmt->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { + WAVEFORMATEXTENSIBLE *fmtex = (void *)fmt; + TRACE("dwChannelMask: %08lx\n", fmtex->dwChannelMask); + TRACE("Samples: %04x\n", fmtex->Samples.wReserved); + TRACE("SubFormat: %s\n", wine_dbgstr_guid(&fmtex->SubFormat)); + } +} + static DWORD CALLBACK timer_loop_func(void *user) { struct timer_loop_params params; @@ -362,6 +396,146 @@ const IAudioClock2Vtbl AudioClock2_Vtbl = clock2_GetDevicePosition };
+HRESULT WINAPI client_GetBufferSize(IAudioClient3 *iface, UINT32 *out) +{ + struct audio_client *This = impl_from_IAudioClient3(iface); + struct get_buffer_size_params params; + + TRACE("(%p)->(%p)\n", This, out); + + if (!out) + return E_POINTER; + + if (!This->stream) + return AUDCLNT_E_NOT_INITIALIZED; + + params.stream = This->stream; + params.frames = out; + + WINE_UNIX_CALL(get_buffer_size, ¶ms); + + return params.result; +} + +HRESULT WINAPI client_GetStreamLatency(IAudioClient3 *iface, REFERENCE_TIME *latency) +{ + struct audio_client *This = impl_from_IAudioClient3(iface); + struct get_latency_params params; + + TRACE("(%p)->(%p)\n", This, latency); + + if (!latency) + return E_POINTER; + + if (!This->stream) + return AUDCLNT_E_NOT_INITIALIZED; + + params.stream = This->stream; + params.latency = latency; + + WINE_UNIX_CALL(get_latency, ¶ms); + + return params.result; +} + +HRESULT WINAPI client_GetCurrentPadding(IAudioClient3 *iface, UINT32 *out) +{ + struct audio_client *This = impl_from_IAudioClient3(iface); + struct get_current_padding_params params; + + TRACE("(%p)->(%p)\n", This, out); + + if (!out) + return E_POINTER; + + if (!This->stream) + return AUDCLNT_E_NOT_INITIALIZED; + + params.stream = This->stream; + params.padding = out; + + WINE_UNIX_CALL(get_current_padding, ¶ms); + + return params.result; +} + +HRESULT WINAPI client_IsFormatSupported(IAudioClient3 *iface, AUDCLNT_SHAREMODE mode, + const WAVEFORMATEX *fmt, WAVEFORMATEX **out) +{ + struct audio_client *This = impl_from_IAudioClient3(iface); + struct is_format_supported_params params; + + TRACE("(%p)->(%x, %p, %p)\n", This, mode, fmt, out); + + if (!fmt) + return E_POINTER; + + dump_fmt(fmt); + + switch (mode) { + case AUDCLNT_SHAREMODE_SHARED: + if (!out) + return E_POINTER; + + params.fmt_out = CoTaskMemAlloc(sizeof(*params.fmt_out)); + break; + case AUDCLNT_SHAREMODE_EXCLUSIVE: + params.fmt_out = NULL; + break; + default: + return E_INVALIDARG; + } + + params.device = This->device_name; + params.flow = This->dataflow; + params.share = mode; + params.fmt_in = fmt; + + WINE_UNIX_CALL(is_format_supported, ¶ms); + + if (params.result == S_FALSE) { + *out = ¶ms.fmt_out->Format; + TRACE("Suggesting the following format:\n"); + dump_fmt(*out); + } else { + if (out) + *out = NULL; + + CoTaskMemFree(params.fmt_out); + } + + return params.result; +} + +HRESULT WINAPI client_GetMixFormat(IAudioClient3 *iface, WAVEFORMATEX **pwfx) +{ + struct audio_client *This = impl_from_IAudioClient3(iface); + struct get_mix_format_params params; + + TRACE("(%p)->(%p)\n", This, pwfx); + + if (!pwfx) + return E_POINTER; + + *pwfx = NULL; + + params.device = This->device_name; + params.flow = This->dataflow; + params.fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE)); + if (!params.fmt) + return E_OUTOFMEMORY; + + WINE_UNIX_CALL(get_mix_format, ¶ms); + + if (SUCCEEDED(params.result)) { + *pwfx = ¶ms.fmt->Format; + dump_fmt(*pwfx); + } else + CoTaskMemFree(params.fmt); + + return params.result; +} + HRESULT WINAPI client_GetDevicePeriod(IAudioClient3 *iface, REFERENCE_TIME *defperiod, REFERENCE_TIME *minperiod) { diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 417d6653d30..64e1d3675df 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -795,126 +795,21 @@ static HRESULT WINAPI AudioClient_Initialize(IAudioClient3 *iface, return S_OK; }
-static HRESULT WINAPI AudioClient_GetBufferSize(IAudioClient3 *iface, - UINT32 *out) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct get_buffer_size_params params; - - TRACE("(%p)->(%p)\n", This, out); - - if (!out) - return E_POINTER; - if (!This->stream) - return AUDCLNT_E_NOT_INITIALIZED; - - params.stream = This->stream; - params.frames = out; - pulse_call(get_buffer_size, ¶ms); - return params.result; -} - -static HRESULT WINAPI AudioClient_GetStreamLatency(IAudioClient3 *iface, - REFERENCE_TIME *latency) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct get_latency_params params; - - TRACE("(%p)->(%p)\n", This, latency); - - if (!latency) - return E_POINTER; - if (!This->stream) - return AUDCLNT_E_NOT_INITIALIZED; +extern HRESULT WINAPI client_GetBufferSize(IAudioClient3 *iface, + UINT32 *out);
- params.stream = This->stream; - params.latency = latency; - pulse_call(get_latency, ¶ms); - return params.result; -} +extern HRESULT WINAPI client_GetStreamLatency(IAudioClient3 *iface, + REFERENCE_TIME *latency);
-static HRESULT WINAPI AudioClient_GetCurrentPadding(IAudioClient3 *iface, - UINT32 *out) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct get_current_padding_params params; - - TRACE("(%p)->(%p)\n", This, out); +extern HRESULT WINAPI client_GetCurrentPadding(IAudioClient3 *iface, + UINT32 *out);
- if (!out) - return E_POINTER; - if (!This->stream) - return AUDCLNT_E_NOT_INITIALIZED; - - params.stream = This->stream; - params.padding = out; - pulse_call(get_current_padding, ¶ms); - return params.result; -} - -static HRESULT WINAPI AudioClient_IsFormatSupported(IAudioClient3 *iface, +extern HRESULT WINAPI client_IsFormatSupported(IAudioClient3 *iface, AUDCLNT_SHAREMODE mode, const WAVEFORMATEX *fmt, - WAVEFORMATEX **out) -{ - ACImpl *This = impl_from_IAudioClient3(iface); - struct is_format_supported_params params; + WAVEFORMATEX **out);
- TRACE("(%p)->(%x, %p, %p)\n", This, mode, fmt, out); - - if (fmt) - dump_fmt(fmt); - - params.device = This->device_name; - params.flow = This->dataflow; - params.share = mode; - params.fmt_in = fmt; - params.fmt_out = NULL; - - if (out) { - *out = NULL; - if (mode == AUDCLNT_SHAREMODE_SHARED) - params.fmt_out = CoTaskMemAlloc(sizeof(*params.fmt_out)); - } - - pulse_call(is_format_supported, ¶ms); - - if (params.result == S_FALSE) - *out = ¶ms.fmt_out->Format; - else - CoTaskMemFree(params.fmt_out); - - return params.result; -} - -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; - - params.device = This->device_name; - params.flow = This->dataflow; - params.fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE)); - if (!params.fmt) - return E_OUTOFMEMORY; - - pulse_call(get_mix_format, ¶ms); - - if (SUCCEEDED(params.result)) { - *pwfx = ¶ms.fmt->Format; - dump_fmt(*pwfx); - } else { - CoTaskMemFree(params.fmt); - } - - return params.result; -} +extern HRESULT WINAPI client_GetMixFormat(IAudioClient3 *iface, + WAVEFORMATEX **pwfx);
extern HRESULT WINAPI client_GetDevicePeriod(IAudioClient3 *iface, REFERENCE_TIME *defperiod, REFERENCE_TIME *minperiod); @@ -958,11 +853,11 @@ static const IAudioClient3Vtbl AudioClient3_Vtbl = AudioClient_AddRef, AudioClient_Release, AudioClient_Initialize, - AudioClient_GetBufferSize, - AudioClient_GetStreamLatency, - AudioClient_GetCurrentPadding, - AudioClient_IsFormatSupported, - AudioClient_GetMixFormat, + client_GetBufferSize, + client_GetStreamLatency, + client_GetCurrentPadding, + client_IsFormatSupported, + client_GetMixFormat, client_GetDevicePeriod, client_Start, client_Stop,