Huw Davies : wineoss: Move get_mix_format to the unixlib.

Alexandre Julliard julliard at winehq.org
Mon Apr 11 15:55:00 CDT 2022


Module: wine
Branch: master
Commit: d4a2f4d44bdfa93231b9cf91e851b765c115755c
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=d4a2f4d44bdfa93231b9cf91e851b765c115755c

Author: Huw Davies <huw at codeweavers.com>
Date:   Wed Apr  6 07:55:58 2022 +0100

wineoss: Move get_mix_format to the unixlib.

Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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, &params);
 
-    fmt->Samples.wValidBitsPerSample = fmt->Format.wBitsPerSample;
-    fmt->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
-
-    *pwfx = (WAVEFORMATEX*)fmt;
-    dump_fmt(*pwfx);
+    if(SUCCEEDED(params.result)){
+        *pwfx = &params.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;




More information about the wine-cvs mailing list