[PATCH 8/8] wineoss: Move get_mix_format to the unixlib.
Andrew Eikum
aeikum at codeweavers.com
Mon Apr 11 09:00:41 CDT 2022
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
On Wed, Apr 06, 2022 at 07:55:58AM +0100, Huw Davies wrote:
> Signed-off-by: Huw Davies <huw at codeweavers.com>
> ---
> dlls/wineoss.drv/mmdevdrv.c | 104 +++++-------------------------------
> dlls/wineoss.drv/oss.c | 101 ++++++++++++++++++++++++++++++++++
> dlls/wineoss.drv/unixlib.h | 9 ++++
> 3 files changed, 122 insertions(+), 92 deletions(-)
>
> diff --git a/dlls/wineoss.drv/mmdevdrv.c b/dlls/wineoss.drv/mmdevdrv.c
> index 6ab7b3e551d..f7c7864e2af 100644
> --- a/dlls/wineoss.drv/mmdevdrv.c
> +++ b/dlls/wineoss.drv/mmdevdrv.c
> @@ -1111,9 +1111,7 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
> WAVEFORMATEX **pwfx)
> {
> ACImpl *This = impl_from_IAudioClient3(iface);
> - WAVEFORMATEXTENSIBLE *fmt;
> - oss_audioinfo ai;
> - int formats, fd;
> + struct get_mix_format_params params;
>
> TRACE("(%p)->(%p)\n", This, pwfx);
>
> @@ -1121,99 +1119,21 @@ static HRESULT WINAPI AudioClient_GetMixFormat(IAudioClient3 *iface,
> return E_POINTER;
> *pwfx = NULL;
>
> - fd = open_device(This->devnode, This->dataflow);
> - if(fd < 0){
> - WARN("Unable to open device %s: %d (%s)\n", This->devnode, errno, strerror(errno));
> - return AUDCLNT_E_DEVICE_INVALIDATED;
> - }
> -
> - ai.dev = -1;
> - if(ioctl(fd, SNDCTL_ENGINEINFO, &ai) < 0){
> - WARN("Unable to get audio info for device %s: %d (%s)\n", This->devnode,
> - errno, strerror(errno));
> - close(fd);
> - return E_FAIL;
> - }
> - close(fd);
> -
> - if(This->dataflow == eRender)
> - formats = ai.oformats;
> - else if(This->dataflow == eCapture)
> - formats = ai.iformats;
> - else
> - return E_UNEXPECTED;
> -
> - fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
> - if(!fmt)
> + params.device = This->devnode;
> + params.flow = This->dataflow;
> + params.fmt = CoTaskMemAlloc(sizeof(WAVEFORMATEXTENSIBLE));
> + if(!params.fmt)
> return E_OUTOFMEMORY;
>
> - fmt->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
> - if(formats & AFMT_S16_LE){
> - fmt->Format.wBitsPerSample = 16;
> - fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
> -#ifdef AFMT_FLOAT
> - }else if(formats & AFMT_FLOAT){
> - fmt->Format.wBitsPerSample = 32;
> - fmt->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
> -#endif
> - }else if(formats & AFMT_U8){
> - fmt->Format.wBitsPerSample = 8;
> - fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
> - }else if(formats & AFMT_S32_LE){
> - fmt->Format.wBitsPerSample = 32;
> - fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
> - }else if(formats & AFMT_S24_LE){
> - fmt->Format.wBitsPerSample = 24;
> - fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
> - }else{
> - WARN("Didn't recognize any available OSS formats: %x\n", formats);
> - CoTaskMemFree(fmt);
> - return E_FAIL;
> - }
> -
> - /* some OSS drivers are buggy, so set reasonable defaults if
> - * the reported values seem wacky */
> - fmt->Format.nChannels = max(ai.max_channels, ai.min_channels);
> - if(fmt->Format.nChannels == 0 || fmt->Format.nChannels > 8)
> - fmt->Format.nChannels = 2;
> -
> - /* For most hardware on Windows, users must choose a configuration with an even
> - * number of channels (stereo, quad, 5.1, 7.1). Users can then disable
> - * channels, but those channels are still reported to applications from
> - * GetMixFormat! Some applications behave badly if given an odd number of
> - * channels (e.g. 2.1). */
> - if(fmt->Format.nChannels > 1 && (fmt->Format.nChannels & 0x1))
> - {
> - if(fmt->Format.nChannels < ai.max_channels)
> - fmt->Format.nChannels += 1;
> - else
> - /* We could "fake" more channels and downmix the emulated channels,
> - * but at that point you really ought to tweak your OSS setup or
> - * just use PulseAudio. */
> - WARN("Some Windows applications behave badly with an odd number of channels (%u)!\n", fmt->Format.nChannels);
> - }
> -
> - if(ai.max_rate == 0)
> - fmt->Format.nSamplesPerSec = 44100;
> - else
> - fmt->Format.nSamplesPerSec = min(ai.max_rate, 44100);
> - if(fmt->Format.nSamplesPerSec < ai.min_rate)
> - fmt->Format.nSamplesPerSec = ai.min_rate;
> -
> - fmt->dwChannelMask = get_channel_mask(fmt->Format.nChannels);
> -
> - fmt->Format.nBlockAlign = (fmt->Format.wBitsPerSample *
> - fmt->Format.nChannels) / 8;
> - fmt->Format.nAvgBytesPerSec = fmt->Format.nSamplesPerSec *
> - fmt->Format.nBlockAlign;
> + OSS_CALL(get_mix_format, ¶ms);
>
> - fmt->Samples.wValidBitsPerSample = fmt->Format.wBitsPerSample;
> - fmt->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
> -
> - *pwfx = (WAVEFORMATEX*)fmt;
> - dump_fmt(*pwfx);
> + if(SUCCEEDED(params.result)){
> + *pwfx = ¶ms.fmt->Format;
> + dump_fmt(*pwfx);
> + } else
> + CoTaskMemFree(params.fmt);
>
> - return S_OK;
> + return params.result;
> }
>
> static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface,
> diff --git a/dlls/wineoss.drv/oss.c b/dlls/wineoss.drv/oss.c
> index 49173ec6b6b..389ec73ee10 100644
> --- a/dlls/wineoss.drv/oss.c
> +++ b/dlls/wineoss.drv/oss.c
> @@ -495,9 +495,110 @@ static NTSTATUS is_format_supported(void *args)
> return STATUS_SUCCESS;
> }
>
> +static NTSTATUS get_mix_format(void *args)
> +{
> + struct get_mix_format_params *params = args;
> + WAVEFORMATEXTENSIBLE *fmt = params->fmt;
> + oss_audioinfo ai;
> + int formats, fd;
> +
> + if(params->flow != eRender && params->flow != eCapture){
> + params->result = E_UNEXPECTED;
> + return STATUS_SUCCESS;
> + }
> +
> + fd = open_device(params->device, params->flow);
> + if(fd < 0){
> + WARN("Unable to open device %s: %d (%s)\n", params->device, errno, strerror(errno));
> + params->result = AUDCLNT_E_DEVICE_INVALIDATED;
> + return STATUS_SUCCESS;
> + }
> +
> + ai.dev = -1;
> + if(ioctl(fd, SNDCTL_ENGINEINFO, &ai) < 0){
> + WARN("Unable to get audio info for device %s: %d (%s)\n", params->device, errno, strerror(errno));
> + close(fd);
> + params->result = E_FAIL;
> + return STATUS_SUCCESS;
> + }
> + close(fd);
> +
> + if(params->flow == eRender)
> + formats = ai.oformats;
> + else
> + formats = ai.iformats;
> +
> + fmt->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
> + if(formats & AFMT_S16_LE){
> + fmt->Format.wBitsPerSample = 16;
> + fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
> +#ifdef AFMT_FLOAT
> + }else if(formats & AFMT_FLOAT){
> + fmt->Format.wBitsPerSample = 32;
> + fmt->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
> +#endif
> + }else if(formats & AFMT_U8){
> + fmt->Format.wBitsPerSample = 8;
> + fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
> + }else if(formats & AFMT_S32_LE){
> + fmt->Format.wBitsPerSample = 32;
> + fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
> + }else if(formats & AFMT_S24_LE){
> + fmt->Format.wBitsPerSample = 24;
> + fmt->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
> + }else{
> + WARN("Didn't recognize any available OSS formats: %x\n", formats);
> + params->result = E_FAIL;
> + return STATUS_SUCCESS;
> + }
> +
> + /* some OSS drivers are buggy, so set reasonable defaults if
> + * the reported values seem wacky */
> + fmt->Format.nChannels = max(ai.max_channels, ai.min_channels);
> + if(fmt->Format.nChannels == 0 || fmt->Format.nChannels > 8)
> + fmt->Format.nChannels = 2;
> +
> + /* For most hardware on Windows, users must choose a configuration with an even
> + * number of channels (stereo, quad, 5.1, 7.1). Users can then disable
> + * channels, but those channels are still reported to applications from
> + * GetMixFormat! Some applications behave badly if given an odd number of
> + * channels (e.g. 2.1). */
> + if(fmt->Format.nChannels > 1 && (fmt->Format.nChannels & 0x1))
> + {
> + if(fmt->Format.nChannels < ai.max_channels)
> + fmt->Format.nChannels += 1;
> + else
> + /* We could "fake" more channels and downmix the emulated channels,
> + * but at that point you really ought to tweak your OSS setup or
> + * just use PulseAudio. */
> + WARN("Some Windows applications behave badly with an odd number of channels (%u)!\n", fmt->Format.nChannels);
> + }
> +
> + if(ai.max_rate == 0)
> + fmt->Format.nSamplesPerSec = 44100;
> + else
> + fmt->Format.nSamplesPerSec = min(ai.max_rate, 44100);
> + if(fmt->Format.nSamplesPerSec < ai.min_rate)
> + fmt->Format.nSamplesPerSec = ai.min_rate;
> +
> + fmt->dwChannelMask = get_channel_mask(fmt->Format.nChannels);
> +
> + fmt->Format.nBlockAlign = (fmt->Format.wBitsPerSample *
> + fmt->Format.nChannels) / 8;
> + fmt->Format.nAvgBytesPerSec = fmt->Format.nSamplesPerSec *
> + fmt->Format.nBlockAlign;
> +
> + fmt->Samples.wValidBitsPerSample = fmt->Format.wBitsPerSample;
> + fmt->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
> +
> + params->result = S_OK;
> + return STATUS_SUCCESS;
> +}
> +
> unixlib_entry_t __wine_unix_call_funcs[] =
> {
> test_connect,
> get_endpoint_ids,
> is_format_supported,
> + get_mix_format,
> };
> diff --git a/dlls/wineoss.drv/unixlib.h b/dlls/wineoss.drv/unixlib.h
> index b89e2142d93..e0817cbc9c1 100644
> --- a/dlls/wineoss.drv/unixlib.h
> +++ b/dlls/wineoss.drv/unixlib.h
> @@ -77,11 +77,20 @@ struct is_format_supported_params
> HRESULT result;
> };
>
> +struct get_mix_format_params
> +{
> + const char *device;
> + EDataFlow flow;
> + WAVEFORMATEXTENSIBLE *fmt;
> + HRESULT result;
> +};
> +
> enum oss_funcs
> {
> oss_test_connect,
> oss_get_endpoint_ids,
> oss_is_format_supported,
> + oss_get_mix_format,
> };
>
> extern unixlib_handle_t oss_handle;
> --
> 2.25.1
>
>
More information about the wine-devel
mailing list