From 06c95af45726674847d12440d904568f59f627bc Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Mon, 18 Nov 2013 14:23:02 -0600 Subject: [PATCH] winmm: Also try MSACM conversions with WAVE_FORMAT_QUERY. --- dlls/winmm/tests/wave.c | 15 ++++++++++- dlls/winmm/waveform.c | 66 +++++++++++++++++++++++++++---------------------- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/dlls/winmm/tests/wave.c b/dlls/winmm/tests/wave.c index f277a923928..61f855a52da 100644 --- a/dlls/winmm/tests/wave.c +++ b/dlls/winmm/tests/wave.c @@ -1178,10 +1178,23 @@ static void wave_out_test_device(UINT_PTR device) &capsA,winetest_interactive,TRUE,FALSE); wave_out_test_deviceOut(device,1.0,5,1,&format,0,CALLBACK_EVENT, &capsA,winetest_interactive,TRUE,FALSE); - } else + } else { + MMRESULT query_rc; + trace("waveOutOpen(%s): WAVE_FORMAT_MULAW not supported\n", 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.nChannels=1; wfa.wfx.nSamplesPerSec=11025; diff --git a/dlls/winmm/waveform.c b/dlls/winmm/waveform.c index 8da547c6ab7..01a54b4e39a 100644 --- a/dlls/winmm/waveform.c +++ b/dlls/winmm/waveform.c @@ -879,7 +879,7 @@ static inline BOOL WINMM_IsMapper(UINT device) } 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; HRESULT hr; @@ -915,6 +915,9 @@ static MMRESULT WINMM_TryDeviceMapping(WINMM_Device *device, WAVEFORMATEX *fmt, return mr; /* yes it can. initialize the audioclient and return success */ + if(is_query) + return MMSYSERR_NOERROR; + hr = IAudioClient_Initialize(device->client, AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST, AC_BUFLEN, 0, &target, &device->parent->session); @@ -933,7 +936,7 @@ static MMRESULT WINMM_TryDeviceMapping(WINMM_Device *device, WAVEFORMATEX *fmt, 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; WAVEFORMATEXTENSIBLE *fmtex = (WAVEFORMATEXTENSIBLE*)device->orig_fmt; @@ -947,13 +950,13 @@ static MMRESULT WINMM_MapDevice(WINMM_Device *device, BOOL is_out) /* convert to PCM format if it's not already */ mr = WINMM_TryDeviceMapping(device, device->orig_fmt, device->orig_fmt->nChannels, device->orig_fmt->nSamplesPerSec, - 16, is_out); + 16, is_query, is_out); if(mr == MMSYSERR_NOERROR) return mr; mr = WINMM_TryDeviceMapping(device, device->orig_fmt, device->orig_fmt->nChannels, device->orig_fmt->nSamplesPerSec, - 8, is_out); + 8, is_query, is_out); if(mr == MMSYSERR_NOERROR) return mr; }else{ @@ -962,90 +965,90 @@ static MMRESULT WINMM_MapDevice(WINMM_Device *device, BOOL is_out) /* first try just changing bit depth and channels */ channels = device->orig_fmt->nChannels; 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) return mr; 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) return mr; channels = (channels == 2) ? 1 : 2; 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) return mr; 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) return mr; /* that didn't work, so now try different sample rates */ 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) 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) 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) 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) 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) return mr; 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) 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) 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) 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) 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) return mr; 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) 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) 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) 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) 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) return mr; 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) 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) 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) 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) 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) return mr; } @@ -1114,7 +1117,10 @@ static LRESULT WINMM_OpenDevice(WINMM_Device *device, WINMM_OpenInfo *info, AUDCLNT_SHAREMODE_SHARED, device->orig_fmt, &closer_fmt); if(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; } @@ -1123,7 +1129,7 @@ static LRESULT WINMM_OpenDevice(WINMM_Device *device, WINMM_OpenInfo *info, AC_BUFLEN, 0, device->orig_fmt, &device->parent->session); if(FAILED(hr)){ 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) goto error; }else{ -- 2.11.4.GIT