[PATCH 8/8] wineoss: Move get_mix_format to the unixlib.
Huw Davies
huw at codeweavers.com
Wed Apr 6 01:55:58 CDT 2022
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