mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 22:47:19 +00:00
wineoss: Move get_mix_format to the unixlib.
Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
12c7f79afd
commit
d4a2f4d44b
|
@ -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;
|
||||
}
|
||||
OSS_CALL(get_mix_format, ¶ms);
|
||||
|
||||
/* 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;
|
||||
if(SUCCEEDED(params.result)){
|
||||
*pwfx = ¶ms.fmt->Format;
|
||||
dump_fmt(*pwfx);
|
||||
} else
|
||||
CoTaskMemFree(params.fmt);
|
||||
|
||||
/* 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);
|
||||
|
||||
*pwfx = (WAVEFORMATEX*)fmt;
|
||||
dump_fmt(*pwfx);
|
||||
|
||||
return S_OK;
|
||||
return params.result;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI AudioClient_GetDevicePeriod(IAudioClient3 *iface,
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue