Signed-off-by: Andrew Eikum aeikum@codeweavers.com
On Wed, Apr 06, 2022 at 07:55:58AM +0100, Huw Davies wrote:
Signed-off-by: Huw Davies huw@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