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