Commit 06c95af4 authored by Andrew Eikum's avatar Andrew Eikum Committed by Alexandre Julliard

winmm: Also try MSACM conversions with WAVE_FORMAT_QUERY.

parent 6ceb5644
...@@ -1178,10 +1178,23 @@ static void wave_out_test_device(UINT_PTR device) ...@@ -1178,10 +1178,23 @@ static void wave_out_test_device(UINT_PTR device)
&capsA,winetest_interactive,TRUE,FALSE); &capsA,winetest_interactive,TRUE,FALSE);
wave_out_test_deviceOut(device,1.0,5,1,&format,0,CALLBACK_EVENT, wave_out_test_deviceOut(device,1.0,5,1,&format,0,CALLBACK_EVENT,
&capsA,winetest_interactive,TRUE,FALSE); &capsA,winetest_interactive,TRUE,FALSE);
} else } else {
MMRESULT query_rc;
trace("waveOutOpen(%s): WAVE_FORMAT_MULAW not supported\n", trace("waveOutOpen(%s): WAVE_FORMAT_MULAW not supported\n",
dev_name(device)); dev_name(device));
query_rc = waveOutOpen(NULL, device, &format, 0, 0, CALLBACK_NULL | WAVE_FORMAT_QUERY);
ok(query_rc==MMSYSERR_NOERROR || query_rc==WAVERR_BADFORMAT || query_rc==MMSYSERR_INVALPARAM,
"waveOutOpen(%s): returned %s\n",dev_name(device),wave_out_error(rc));
rc = waveOutOpen(&wout, device, &format, 0, 0, CALLBACK_NULL);
ok(rc == query_rc,
"waveOutOpen(%s): returned different from query: %s\n",dev_name(device),wave_out_error(rc));
if(rc == MMSYSERR_NOERROR)
waveOutClose(wout);
}
wfa.wfx.wFormatTag=WAVE_FORMAT_IMA_ADPCM; wfa.wfx.wFormatTag=WAVE_FORMAT_IMA_ADPCM;
wfa.wfx.nChannels=1; wfa.wfx.nChannels=1;
wfa.wfx.nSamplesPerSec=11025; wfa.wfx.nSamplesPerSec=11025;
......
...@@ -879,7 +879,7 @@ static inline BOOL WINMM_IsMapper(UINT device) ...@@ -879,7 +879,7 @@ static inline BOOL WINMM_IsMapper(UINT device)
} }
static MMRESULT WINMM_TryDeviceMapping(WINMM_Device *device, WAVEFORMATEX *fmt, static MMRESULT WINMM_TryDeviceMapping(WINMM_Device *device, WAVEFORMATEX *fmt,
WORD channels, DWORD freq, DWORD bits_per_samp, BOOL is_out) WORD channels, DWORD freq, DWORD bits_per_samp, BOOL is_query, BOOL is_out)
{ {
WAVEFORMATEX target, *closer_fmt = NULL; WAVEFORMATEX target, *closer_fmt = NULL;
HRESULT hr; HRESULT hr;
...@@ -915,6 +915,9 @@ static MMRESULT WINMM_TryDeviceMapping(WINMM_Device *device, WAVEFORMATEX *fmt, ...@@ -915,6 +915,9 @@ static MMRESULT WINMM_TryDeviceMapping(WINMM_Device *device, WAVEFORMATEX *fmt,
return mr; return mr;
/* yes it can. initialize the audioclient and return success */ /* yes it can. initialize the audioclient and return success */
if(is_query)
return MMSYSERR_NOERROR;
hr = IAudioClient_Initialize(device->client, AUDCLNT_SHAREMODE_SHARED, hr = IAudioClient_Initialize(device->client, AUDCLNT_SHAREMODE_SHARED,
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST, AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
AC_BUFLEN, 0, &target, &device->parent->session); AC_BUFLEN, 0, &target, &device->parent->session);
...@@ -933,7 +936,7 @@ static MMRESULT WINMM_TryDeviceMapping(WINMM_Device *device, WAVEFORMATEX *fmt, ...@@ -933,7 +936,7 @@ static MMRESULT WINMM_TryDeviceMapping(WINMM_Device *device, WAVEFORMATEX *fmt,
return MMSYSERR_NOERROR; return MMSYSERR_NOERROR;
} }
static MMRESULT WINMM_MapDevice(WINMM_Device *device, BOOL is_out) static MMRESULT WINMM_MapDevice(WINMM_Device *device, BOOL is_query, BOOL is_out)
{ {
MMRESULT mr; MMRESULT mr;
WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)device->orig_fmt; WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)device->orig_fmt;
...@@ -947,13 +950,13 @@ static MMRESULT WINMM_MapDevice(WINMM_Device *device, BOOL is_out) ...@@ -947,13 +950,13 @@ static MMRESULT WINMM_MapDevice(WINMM_Device *device, BOOL is_out)
/* convert to PCM format if it's not already */ /* convert to PCM format if it's not already */
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, mr = WINMM_TryDeviceMapping(device, device->orig_fmt,
device->orig_fmt->nChannels, device->orig_fmt->nSamplesPerSec, device->orig_fmt->nChannels, device->orig_fmt->nSamplesPerSec,
16, is_out); 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, mr = WINMM_TryDeviceMapping(device, device->orig_fmt,
device->orig_fmt->nChannels, device->orig_fmt->nSamplesPerSec, device->orig_fmt->nChannels, device->orig_fmt->nSamplesPerSec,
8, is_out); 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
}else{ }else{
...@@ -962,90 +965,90 @@ static MMRESULT WINMM_MapDevice(WINMM_Device *device, BOOL is_out) ...@@ -962,90 +965,90 @@ static MMRESULT WINMM_MapDevice(WINMM_Device *device, BOOL is_out)
/* first try just changing bit depth and channels */ /* first try just changing bit depth and channels */
channels = device->orig_fmt->nChannels; channels = device->orig_fmt->nChannels;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels,
device->orig_fmt->nSamplesPerSec, 16, is_out); device->orig_fmt->nSamplesPerSec, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels,
device->orig_fmt->nSamplesPerSec, 8, is_out); device->orig_fmt->nSamplesPerSec, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
channels = (channels == 2) ? 1 : 2; channels = (channels == 2) ? 1 : 2;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels,
device->orig_fmt->nSamplesPerSec, 16, is_out); device->orig_fmt->nSamplesPerSec, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels,
device->orig_fmt->nSamplesPerSec, 8, is_out); device->orig_fmt->nSamplesPerSec, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
/* that didn't work, so now try different sample rates */ /* that didn't work, so now try different sample rates */
channels = device->orig_fmt->nChannels; channels = device->orig_fmt->nChannels;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 16, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 16, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 16, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 16, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 16, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
channels = (channels == 2) ? 1 : 2; channels = (channels == 2) ? 1 : 2;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 16, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 16, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 16, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 16, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 16, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 16, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
channels = device->orig_fmt->nChannels; channels = device->orig_fmt->nChannels;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 8, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 8, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 8, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 8, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 8, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
channels = (channels == 2) ? 1 : 2; channels = (channels == 2) ? 1 : 2;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 8, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 96000, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 8, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 48000, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 8, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 44100, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 8, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 22050, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 8, is_out); mr = WINMM_TryDeviceMapping(device, device->orig_fmt, channels, 11025, 8, is_query, is_out);
if(mr == MMSYSERR_NOERROR) if(mr == MMSYSERR_NOERROR)
return mr; return mr;
} }
...@@ -1114,7 +1117,10 @@ static LRESULT WINMM_OpenDevice(WINMM_Device *device, WINMM_OpenInfo *info, ...@@ -1114,7 +1117,10 @@ static LRESULT WINMM_OpenDevice(WINMM_Device *device, WINMM_OpenInfo *info,
AUDCLNT_SHAREMODE_SHARED, device->orig_fmt, &closer_fmt); AUDCLNT_SHAREMODE_SHARED, device->orig_fmt, &closer_fmt);
if(closer_fmt) if(closer_fmt)
CoTaskMemFree(closer_fmt); CoTaskMemFree(closer_fmt);
ret = hr == S_FALSE ? WAVERR_BADFORMAT : hr2mmr(hr); if((hr == S_FALSE || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && !(info->flags & WAVE_FORMAT_DIRECT))
ret = WINMM_MapDevice(device, TRUE, is_out);
else
ret = hr == S_FALSE ? WAVERR_BADFORMAT : hr2mmr(hr);
goto error; goto error;
} }
...@@ -1123,7 +1129,7 @@ static LRESULT WINMM_OpenDevice(WINMM_Device *device, WINMM_OpenInfo *info, ...@@ -1123,7 +1129,7 @@ static LRESULT WINMM_OpenDevice(WINMM_Device *device, WINMM_OpenInfo *info,
AC_BUFLEN, 0, device->orig_fmt, &device->parent->session); AC_BUFLEN, 0, device->orig_fmt, &device->parent->session);
if(FAILED(hr)){ if(FAILED(hr)){
if(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && !(info->flags & WAVE_FORMAT_DIRECT)){ if(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && !(info->flags & WAVE_FORMAT_DIRECT)){
ret = WINMM_MapDevice(device, is_out); ret = WINMM_MapDevice(device, FALSE, is_out);
if(ret != MMSYSERR_NOERROR || info->flags & WAVE_FORMAT_QUERY) if(ret != MMSYSERR_NOERROR || info->flags & WAVE_FORMAT_QUERY)
goto error; goto error;
}else{ }else{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment