!8598 will require some more work, so I wrote a number of tests in preparation for it. There will be another MR for capturing tests.
This MR also enable 32-bit PCM samples for PulseAudio, since they're already enabled for other drivers and it's useful to have some uniformity between the drivers in order to avoid making writing todo conditions even more of a nightmare than it already is. 32-bit samples are already enabled to extensible wave formats, so it doesn't seem intentional that they were not enabled for non-extensible formats.
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/mmdevapi/tests/capture.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/mmdevapi/tests/capture.c b/dlls/mmdevapi/tests/capture.c index 678fda5baca..45b4e8e2c8f 100644 --- a/dlls/mmdevapi/tests/capture.c +++ b/dlls/mmdevapi/tests/capture.c @@ -657,6 +657,7 @@ static void test_formats(AUDCLNT_SHAREMODE mode) "Initialize(noexcl., %c%lux%2ux%u) returns %08lx(%08lx)\n", format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr, hrs); else + todo_wine_if(hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) ok(hrs == S_OK ? hr == S_OK : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT, "Initialize(exclus., %c%lux%2ux%u) returns %08lx\n",
From: Giovanni Mascellani gmascellani@codeweavers.com
This segfaults on my Windows 11 system. It's not a particularly useful test anyway. --- dlls/mmdevapi/tests/capture.c | 3 --- dlls/mmdevapi/tests/render.c | 3 --- 2 files changed, 6 deletions(-)
diff --git a/dlls/mmdevapi/tests/capture.c b/dlls/mmdevapi/tests/capture.c index 45b4e8e2c8f..1c1c3a589fb 100644 --- a/dlls/mmdevapi/tests/capture.c +++ b/dlls/mmdevapi/tests/capture.c @@ -435,9 +435,6 @@ static void test_audioclient(void)
handle = CreateEventW(NULL, FALSE, FALSE, NULL);
- hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, NULL); - ok(hr == E_POINTER, "QueryInterface(NULL) returned %08lx\n", hr); - unk = (void*)(LONG_PTR)0x12345678; hr = IAudioClient_QueryInterface(ac, &IID_NULL, (void**)&unk); ok(hr == E_NOINTERFACE, "QueryInterface(IID_NULL) returned %08lx\n", hr); diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index f674935de00..8a3d732a99b 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -196,9 +196,6 @@ static void test_audioclient(void)
handle = CreateEventW(NULL, FALSE, FALSE, NULL);
- hr = IAudioClient_QueryInterface(ac, &IID_IUnknown, NULL); - ok(hr == E_POINTER, "QueryInterface(NULL) returned %08lx\n", hr); - unk = (void*)(LONG_PTR)0x12345678; hr = IAudioClient_QueryInterface(ac, &IID_NULL, (void**)&unk); ok(hr == E_NOINTERFACE, "QueryInterface(IID_NULL) returned %08lx\n", hr);
From: Giovanni Mascellani gmascellani@codeweavers.com
They're already allowed on the ALSA and CoreAudio drivers. --- dlls/winepulse.drv/pulse.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index 4b287578e8b..9a218e75c1b 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -962,6 +962,8 @@ static HRESULT pulse_spec_from_waveformat(struct pulse_stream *stream, const WAV stream->ss.format = PA_SAMPLE_U8; else if (fmt->wBitsPerSample == 16) stream->ss.format = PA_SAMPLE_S16LE; + else if (fmt->wBitsPerSample == 32) + stream->ss.format = PA_SAMPLE_S32LE; else return AUDCLNT_E_UNSUPPORTED_FORMAT; pa_channel_map_init_auto(&stream->map, fmt->nChannels, PA_CHANNEL_MAP_ALSA);
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/mmdevapi/tests/render.c | 216 ++++++++++++++++------------------- 1 file changed, 100 insertions(+), 116 deletions(-)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 8a3d732a99b..06bfd39a233 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -41,30 +41,10 @@ #include "audiopolicy.h" #include "endpointvolume.h"
-#define PCM WAVE_FORMAT_PCM -#define FLOAT WAVE_FORMAT_IEEE_FLOAT - -static const unsigned int win_formats[][4] = { - {PCM, 8000, 8, 1}, {PCM, 8000, 8, 2}, {PCM, 8000, 16, 1}, {PCM, 8000, 16, 2}, - {PCM, 11025, 8, 1}, {PCM, 11025, 8, 2}, {PCM, 11025, 16, 1}, {PCM, 11025, 16, 2}, - {PCM, 12000, 8, 1}, {PCM, 12000, 8, 2}, {PCM, 12000, 16, 1}, {PCM, 12000, 16, 2}, - {PCM, 16000, 8, 1}, {PCM, 16000, 8, 2}, {PCM, 16000, 16, 1}, {PCM, 16000, 16, 2}, - {PCM, 22050, 8, 1}, {PCM, 22050, 8, 2}, {PCM, 22050, 16, 1}, {PCM, 22050, 16, 2}, - {PCM, 44100, 8, 1}, {PCM, 44100, 8, 2}, {PCM, 44100, 16, 1}, {PCM, 44100, 16, 2}, - {PCM, 48000, 8, 1}, {PCM, 48000, 8, 2}, {PCM, 48000, 16, 1}, {PCM, 48000, 16, 2}, - {PCM, 96000, 8, 1}, {PCM, 96000, 8, 2}, {PCM, 96000, 16, 1}, {PCM, 96000, 16, 2}, - {FLOAT, 8000, 32, 1}, {FLOAT, 8000, 32, 2}, - {FLOAT, 11025, 32, 1}, {FLOAT, 11025, 32, 2}, - {FLOAT, 12000, 32, 1}, {FLOAT, 12000, 32, 2}, - {FLOAT, 16000, 32, 1}, {FLOAT, 16000, 32, 2}, - {FLOAT, 22050, 32, 1}, {FLOAT, 22050, 32, 2}, - {FLOAT, 44100, 32, 1}, {FLOAT, 44100, 32, 2}, - {FLOAT, 48000, 32, 1}, {FLOAT, 48000, 32, 2}, - {FLOAT, 96000, 32, 1}, {FLOAT, 96000, 32, 2}, -}; - -#undef PCM -#undef FLOAT +static const unsigned int sampling_rates[] = { 8000, 11025, 12000, 16000, 22050, 44100, 48000, 96000 }; +static const unsigned int channel_counts[] = { 1, 2 }; +static const unsigned int sample_formats[][2] = { {WAVE_FORMAT_PCM, 8}, {WAVE_FORMAT_PCM, 16}, + {WAVE_FORMAT_IEEE_FLOAT, 32} };
#define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
@@ -527,102 +507,106 @@ static void test_formats(AUDCLNT_SHAREMODE mode) IAudioClient *ac; HRESULT hr, hrs; WAVEFORMATEX fmt, *pwfx, *pwfx2; - int i; + int i, j, k;
fmt.cbSize = 0;
- for(i = 0; i < ARRAY_SIZE(win_formats); i++) { - char format_chr; - - hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, - NULL, (void**)&ac); - ok(hr == S_OK, "Activation failed with %08lx\n", hr); - if(hr != S_OK) - continue; - - hr = IAudioClient_GetMixFormat(ac, &pwfx); - ok(hr == S_OK, "GetMixFormat failed: %08lx\n", hr); - - fmt.wFormatTag = win_formats[i][0]; - fmt.nSamplesPerSec = win_formats[i][1]; - fmt.wBitsPerSample = win_formats[i][2]; - fmt.nChannels = win_formats[i][3]; - fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; - fmt.nAvgBytesPerSec= fmt.nBlockAlign * fmt.nSamplesPerSec; - - format_chr = fmt.wFormatTag == WAVE_FORMAT_PCM ? 'P' : 'F'; - - pwfx2 = (WAVEFORMATEX*)0xDEADF00D; - hr = IAudioClient_IsFormatSupported(ac, mode, &fmt, &pwfx2); - hrs = hr; - /* Only shared mode suggests something ... GetMixFormat! */ - ok(hr == S_OK || (mode == AUDCLNT_SHAREMODE_SHARED - ? hr == S_FALSE || broken(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && - /* 5:1 card exception when asked for 1 channel at mixer rate */ - pwfx->nChannels > 2 && fmt.nSamplesPerSec == pwfx->nSamplesPerSec) - : (hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == hexcl)), - "IsFormatSupported(%d, %c%lux%2ux%u) returns %08lx\n", mode, - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); - if (hr == S_OK) - trace("IsSupported(%s, %c%lux%2ux%u)\n", - mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels); - - /* In shared mode you can only change bit width, not sampling rate or channel count. */ - if (mode == AUDCLNT_SHAREMODE_SHARED) - { - BOOL compatible = fmt.nSamplesPerSec == pwfx->nSamplesPerSec && fmt.nChannels == pwfx->nChannels; - HRESULT expected = compatible ? S_OK : S_FALSE; - ok(hr == expected, "Got %lx expected %lx\n", hr, expected); - } - - ok((hr == S_FALSE)^(pwfx2 == NULL), "hr %lx<->suggest %p\n", hr, pwfx2); - if (pwfx2) { - ok(pwfx2->wFormatTag == pwfx->wFormatTag && - pwfx2->nSamplesPerSec == pwfx->nSamplesPerSec && - pwfx2->nChannels == pwfx->nChannels && - pwfx2->wBitsPerSample == pwfx->wBitsPerSample, - "Suggestion %c%lux%2ux%u differs from GetMixFormat\n", - format_chr, pwfx2->nSamplesPerSec, pwfx2->wBitsPerSample, pwfx2->nChannels); + for (i = 0; i < ARRAY_SIZE(sampling_rates); i++) { + for (j = 0; j < ARRAY_SIZE(channel_counts); j++) { + for (k = 0; k < ARRAY_SIZE(sample_formats); k++) { + char format_chr; + + hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, + NULL, (void**)&ac); + ok(hr == S_OK, "Activation failed with %08lx\n", hr); + if(hr != S_OK) + continue; + + hr = IAudioClient_GetMixFormat(ac, &pwfx); + ok(hr == S_OK, "GetMixFormat failed: %08lx\n", hr); + + fmt.wFormatTag = sample_formats[k][0]; + fmt.nSamplesPerSec = sampling_rates[i]; + fmt.wBitsPerSample = sample_formats[k][1]; + fmt.nChannels = channel_counts[j]; + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; + fmt.nAvgBytesPerSec= fmt.nBlockAlign * fmt.nSamplesPerSec; + + format_chr = fmt.wFormatTag == WAVE_FORMAT_PCM ? 'P' : 'F'; + + pwfx2 = (WAVEFORMATEX*)0xDEADF00D; + hr = IAudioClient_IsFormatSupported(ac, mode, &fmt, &pwfx2); + hrs = hr; + /* Only shared mode suggests something ... GetMixFormat! */ + ok(hr == S_OK || (mode == AUDCLNT_SHAREMODE_SHARED + ? hr == S_FALSE || broken(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && + /* 5:1 card exception when asked for 1 channel at mixer rate */ + pwfx->nChannels > 2 && fmt.nSamplesPerSec == pwfx->nSamplesPerSec) + : (hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == hexcl)), + "IsFormatSupported(%d, %c%lux%2ux%u) returns %08lx\n", mode, + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + if (hr == S_OK) + trace("IsSupported(%s, %c%lux%2ux%u)\n", + mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels); + + /* In shared mode you can only change bit width, not sampling rate or channel count. */ + if (mode == AUDCLNT_SHAREMODE_SHARED) + { + BOOL compatible = fmt.nSamplesPerSec == pwfx->nSamplesPerSec && fmt.nChannels == pwfx->nChannels; + HRESULT expected = compatible ? S_OK : S_FALSE; + ok(hr == expected, "Got %lx expected %lx\n", hr, expected); + } + + ok((hr == S_FALSE)^(pwfx2 == NULL), "hr %lx<->suggest %p\n", hr, pwfx2); + if (pwfx2) { + ok(pwfx2->wFormatTag == pwfx->wFormatTag && + pwfx2->nSamplesPerSec == pwfx->nSamplesPerSec && + pwfx2->nChannels == pwfx->nChannels && + pwfx2->wBitsPerSample == pwfx->wBitsPerSample, + "Suggestion %c%lux%2ux%u differs from GetMixFormat\n", + format_chr, pwfx2->nSamplesPerSec, pwfx2->wBitsPerSample, pwfx2->nChannels); + } + + /* Vista returns E_INVALIDARG upon AUDCLNT_STREAMFLAGS_RATEADJUST */ + hr = IAudioClient_Initialize(ac, mode, 0, 5000000, 0, &fmt, NULL); + if ((hrs == S_OK) ^ (hr == S_OK)) + trace("Initialize (%s, %c%lux%2ux%u) returns %08lx unlike IsFormatSupported\n", + mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + if (mode == AUDCLNT_SHAREMODE_SHARED) + ok(hrs == S_OK ? hr == S_OK : hr == AUDCLNT_E_UNSUPPORTED_FORMAT, + "Initialize(shared, %c%lux%2ux%u) returns %08lx\n", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) + /* Unsupported format implies "create failed" and shadows "not allowed" */ + ok(hrs == hexcl && (hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == hrs), + "Initialize(noexcl., %c%lux%2ux%u) returns %08lx(%08lx)\n", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr, hrs); + else + /* On testbot 48000x16x1 claims support, but does not Initialize. + * Some cards Initialize 44100|48000x16x1 yet claim no support; + * F. Gouget's w7 bots do that for 12000|96000x8|16x1|2 */ + ok(hrs == S_OK ? hr == S_OK || broken(hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED) + : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || + broken(hr == S_OK && + ((fmt.nChannels == 1 && fmt.wBitsPerSample == 16) || + (fmt.nSamplesPerSec == 12000 || fmt.nSamplesPerSec == 96000))), + "Initialize(exclus., %c%lux%2ux%u) returns %08lx\n", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + + /* Bug in native (Vista/w2k8/w7): after Initialize failed, better + * Release this ac and Activate a new one. + * A second call (with a known working format) would yield + * ALREADY_INITIALIZED in shared mode yet be unusable, and in exclusive + * mode some entity keeps a lock on the device, causing DEVICE_IN_USE to + * all subsequent calls until the audio engine service is restarted. */ + + CoTaskMemFree(pwfx2); + CoTaskMemFree(pwfx); + IAudioClient_Release(ac); + } } - - /* Vista returns E_INVALIDARG upon AUDCLNT_STREAMFLAGS_RATEADJUST */ - hr = IAudioClient_Initialize(ac, mode, 0, 5000000, 0, &fmt, NULL); - if ((hrs == S_OK) ^ (hr == S_OK)) - trace("Initialize (%s, %c%lux%2ux%u) returns %08lx unlike IsFormatSupported\n", - mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); - if (mode == AUDCLNT_SHAREMODE_SHARED) - ok(hrs == S_OK ? hr == S_OK : hr == AUDCLNT_E_UNSUPPORTED_FORMAT, - "Initialize(shared, %c%lux%2ux%u) returns %08lx\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); - else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) - /* Unsupported format implies "create failed" and shadows "not allowed" */ - ok(hrs == hexcl && (hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == hrs), - "Initialize(noexcl., %c%lux%2ux%u) returns %08lx(%08lx)\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr, hrs); - else - /* On testbot 48000x16x1 claims support, but does not Initialize. - * Some cards Initialize 44100|48000x16x1 yet claim no support; - * F. Gouget's w7 bots do that for 12000|96000x8|16x1|2 */ - ok(hrs == S_OK ? hr == S_OK || broken(hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED) - : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || - broken(hr == S_OK && - ((fmt.nChannels == 1 && fmt.wBitsPerSample == 16) || - (fmt.nSamplesPerSec == 12000 || fmt.nSamplesPerSec == 96000))), - "Initialize(exclus., %c%lux%2ux%u) returns %08lx\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); - - /* Bug in native (Vista/w2k8/w7): after Initialize failed, better - * Release this ac and Activate a new one. - * A second call (with a known working format) would yield - * ALREADY_INITIALIZED in shared mode yet be unusable, and in exclusive - * mode some entity keeps a lock on the device, causing DEVICE_IN_USE to - * all subsequent calls until the audio engine service is restarted. */ - - CoTaskMemFree(pwfx2); - CoTaskMemFree(pwfx); - IAudioClient_Release(ac); } }
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/mmdevapi/tests/render.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 06bfd39a233..de05b267018 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -41,10 +41,10 @@ #include "audiopolicy.h" #include "endpointvolume.h"
-static const unsigned int sampling_rates[] = { 8000, 11025, 12000, 16000, 22050, 44100, 48000, 96000 }; -static const unsigned int channel_counts[] = { 1, 2 }; +static const unsigned int sampling_rates[] = { 8000, 11025, 12000, 16000, 22050, 32000, 44100, 48000, 96000, 192000 }; +static const unsigned int channel_counts[] = { 1, 2, 4, 6, 8 }; static const unsigned int sample_formats[][2] = { {WAVE_FORMAT_PCM, 8}, {WAVE_FORMAT_PCM, 16}, - {WAVE_FORMAT_IEEE_FLOAT, 32} }; + {WAVE_FORMAT_PCM, 32}, {WAVE_FORMAT_IEEE_FLOAT, 32} };
#define NULL_PTR_ERR MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, RPC_X_NULL_REF_POINTER)
@@ -539,9 +539,7 @@ static void test_formats(AUDCLNT_SHAREMODE mode) hrs = hr; /* Only shared mode suggests something ... GetMixFormat! */ ok(hr == S_OK || (mode == AUDCLNT_SHAREMODE_SHARED - ? hr == S_FALSE || broken(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && - /* 5:1 card exception when asked for 1 channel at mixer rate */ - pwfx->nChannels > 2 && fmt.nSamplesPerSec == pwfx->nSamplesPerSec) + ? hr == S_FALSE || (hr == AUDCLNT_E_UNSUPPORTED_FORMAT && fmt.nChannels > 2) : (hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == hexcl)), "IsFormatSupported(%d, %c%lux%2ux%u) returns %08lx\n", mode, format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); @@ -555,7 +553,11 @@ static void test_formats(AUDCLNT_SHAREMODE mode) { BOOL compatible = fmt.nSamplesPerSec == pwfx->nSamplesPerSec && fmt.nChannels == pwfx->nChannels; HRESULT expected = compatible ? S_OK : S_FALSE; - ok(hr == expected, "Got %lx expected %lx\n", hr, expected); + if (fmt.nChannels > 2) + expected = AUDCLNT_E_UNSUPPORTED_FORMAT; + todo_wine_if(fmt.nChannels > 2 && hr != expected) + ok(hr == expected, "IsFormatSupported(shared, %c%lux%2ux%u) returns %08lx, expected %08lx\n", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr, expected); }
ok((hr == S_FALSE)^(pwfx2 == NULL), "hr %lx<->suggest %p\n", hr, pwfx2); @@ -575,7 +577,8 @@ static void test_formats(AUDCLNT_SHAREMODE mode) mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.", format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); if (mode == AUDCLNT_SHAREMODE_SHARED) - ok(hrs == S_OK ? hr == S_OK : hr == AUDCLNT_E_UNSUPPORTED_FORMAT, + ok(hrs == S_OK ? hr == S_OK : hr == AUDCLNT_E_UNSUPPORTED_FORMAT + || (hr == E_INVALIDARG && fmt.nChannels > 2), "Initialize(shared, %c%lux%2ux%u) returns %08lx\n", format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) @@ -587,11 +590,13 @@ static void test_formats(AUDCLNT_SHAREMODE mode) /* On testbot 48000x16x1 claims support, but does not Initialize. * Some cards Initialize 44100|48000x16x1 yet claim no support; * F. Gouget's w7 bots do that for 12000|96000x8|16x1|2 */ + todo_wine_if(fmt.nChannels > 2 && hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) ok(hrs == S_OK ? hr == S_OK || broken(hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED) : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || broken(hr == S_OK && ((fmt.nChannels == 1 && fmt.wBitsPerSample == 16) || - (fmt.nSamplesPerSec == 12000 || fmt.nSamplesPerSec == 96000))), + (fmt.nSamplesPerSec == 12000 || fmt.nSamplesPerSec == 96000))) + || (hr == E_INVALIDARG && fmt.nChannels > 2), "Initialize(exclus., %c%lux%2ux%u) returns %08lx\n", format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr);
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/mmdevapi/tests/render.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index de05b267018..9395434ed97 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -537,20 +537,13 @@ static void test_formats(AUDCLNT_SHAREMODE mode) pwfx2 = (WAVEFORMATEX*)0xDEADF00D; hr = IAudioClient_IsFormatSupported(ac, mode, &fmt, &pwfx2); hrs = hr; - /* Only shared mode suggests something ... GetMixFormat! */ - ok(hr == S_OK || (mode == AUDCLNT_SHAREMODE_SHARED - ? hr == S_FALSE || (hr == AUDCLNT_E_UNSUPPORTED_FORMAT && fmt.nChannels > 2) - : (hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == hexcl)), - "IsFormatSupported(%d, %c%lux%2ux%u) returns %08lx\n", mode, - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); if (hr == S_OK) trace("IsSupported(%s, %c%lux%2ux%u)\n", mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.", format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels);
/* In shared mode you can only change bit width, not sampling rate or channel count. */ - if (mode == AUDCLNT_SHAREMODE_SHARED) - { + if (mode == AUDCLNT_SHAREMODE_SHARED) { BOOL compatible = fmt.nSamplesPerSec == pwfx->nSamplesPerSec && fmt.nChannels == pwfx->nChannels; HRESULT expected = compatible ? S_OK : S_FALSE; if (fmt.nChannels > 2) @@ -558,8 +551,13 @@ static void test_formats(AUDCLNT_SHAREMODE mode) todo_wine_if(fmt.nChannels > 2 && hr != expected) ok(hr == expected, "IsFormatSupported(shared, %c%lux%2ux%u) returns %08lx, expected %08lx\n", format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr, expected); + } else { + ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == hexcl, + "IsFormatSupported(exclusive, %c%lux%2ux%u) returns %08lx\n", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); }
+ /* Only shared mode suggests something ... GetMixFormat! */ ok((hr == S_FALSE)^(pwfx2 == NULL), "hr %lx<->suggest %p\n", hr, pwfx2); if (pwfx2) { ok(pwfx2->wFormatTag == pwfx->wFormatTag &&
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/mmdevapi/tests/render.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 9395434ed97..e1c58a448b9 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -574,12 +574,14 @@ static void test_formats(AUDCLNT_SHAREMODE mode) trace("Initialize (%s, %c%lux%2ux%u) returns %08lx unlike IsFormatSupported\n", mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.", format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); - if (mode == AUDCLNT_SHAREMODE_SHARED) - ok(hrs == S_OK ? hr == S_OK : hr == AUDCLNT_E_UNSUPPORTED_FORMAT - || (hr == E_INVALIDARG && fmt.nChannels > 2), - "Initialize(shared, %c%lux%2ux%u) returns %08lx\n", + if (mode == AUDCLNT_SHAREMODE_SHARED) { + HRESULT expected = hrs == S_OK ? S_OK : AUDCLNT_E_UNSUPPORTED_FORMAT; + if (fmt.nChannels > 2) + expected = E_INVALIDARG; + todo_wine_if(fmt.nChannels > 2) + ok(hr == expected, "Initialize(shared, %c%lux%2ux%u) returns %08lx\n", format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); - else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) + } else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) /* Unsupported format implies "create failed" and shadows "not allowed" */ ok(hrs == hexcl && (hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == hrs), "Initialize(noexcl., %c%lux%2ux%u) returns %08lx(%08lx)\n",
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/mmdevapi/tests/render.c | 47 ++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 5 deletions(-)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index e1c58a448b9..f876fe1edd9 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -505,9 +505,10 @@ cleanup: static void test_formats(AUDCLNT_SHAREMODE mode) { IAudioClient *ac; - HRESULT hr, hrs; + HRESULT hr, hrs, expected; WAVEFORMATEX fmt, *pwfx, *pwfx2; int i, j, k; + BOOL compatible;
fmt.cbSize = 0;
@@ -544,8 +545,8 @@ static void test_formats(AUDCLNT_SHAREMODE mode)
/* In shared mode you can only change bit width, not sampling rate or channel count. */ if (mode == AUDCLNT_SHAREMODE_SHARED) { - BOOL compatible = fmt.nSamplesPerSec == pwfx->nSamplesPerSec && fmt.nChannels == pwfx->nChannels; - HRESULT expected = compatible ? S_OK : S_FALSE; + compatible = fmt.nSamplesPerSec == pwfx->nSamplesPerSec && fmt.nChannels == pwfx->nChannels; + expected = compatible ? S_OK : S_FALSE; if (fmt.nChannels > 2) expected = AUDCLNT_E_UNSUPPORTED_FORMAT; todo_wine_if(fmt.nChannels > 2 && hr != expected) @@ -568,14 +569,13 @@ static void test_formats(AUDCLNT_SHAREMODE mode) format_chr, pwfx2->nSamplesPerSec, pwfx2->wBitsPerSample, pwfx2->nChannels); }
- /* Vista returns E_INVALIDARG upon AUDCLNT_STREAMFLAGS_RATEADJUST */ hr = IAudioClient_Initialize(ac, mode, 0, 5000000, 0, &fmt, NULL); if ((hrs == S_OK) ^ (hr == S_OK)) trace("Initialize (%s, %c%lux%2ux%u) returns %08lx unlike IsFormatSupported\n", mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.", format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); if (mode == AUDCLNT_SHAREMODE_SHARED) { - HRESULT expected = hrs == S_OK ? S_OK : AUDCLNT_E_UNSUPPORTED_FORMAT; + expected = hrs == S_OK ? S_OK : AUDCLNT_E_UNSUPPORTED_FORMAT; if (fmt.nChannels > 2) expected = E_INVALIDARG; todo_wine_if(fmt.nChannels > 2) @@ -600,6 +600,43 @@ static void test_formats(AUDCLNT_SHAREMODE mode) "Initialize(exclus., %c%lux%2ux%u) returns %08lx\n", format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr);
+ IAudioClient_Release(ac); + + hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, + NULL, (void**)&ac); + ok(hr == S_OK, "Activation failed with %08lx\n", hr); + if(hr != S_OK) + continue; + + /* With AUDCLNT_STREAMFLAGS_RATEADJUST channel count must match, but sampling rate doesn't. */ + hr = IAudioClient_Initialize(ac, mode, AUDCLNT_STREAMFLAGS_RATEADJUST, 5000000, 0, &fmt, NULL); + if (mode == AUDCLNT_SHAREMODE_SHARED) { + compatible = fmt.nChannels == pwfx->nChannels; + expected = compatible ? S_OK : AUDCLNT_E_UNSUPPORTED_FORMAT; + if (fmt.nChannels > 2) + expected = E_INVALIDARG; + todo_wine_if(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && hr != expected) + ok(hr == expected, "Initialize(shared, %c%lux%2ux%u, RATEADJUST) returns %08lx\n", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + } else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) + /* Unsupported format implies "create failed" and shadows "not allowed" */ + ok(hrs == hexcl && (hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == hrs), + "Initialize(noexcl., %c%lux%2ux%u, RATEADJUST) returns %08lx(%08lx)\n", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr, hrs); + else + /* On testbot 48000x16x1 claims support, but does not Initialize. + * Some cards Initialize 44100|48000x16x1 yet claim no support; + * F. Gouget's w7 bots do that for 12000|96000x8|16x1|2 */ + todo_wine_if(fmt.nChannels > 2 && hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) + ok(hrs == S_OK ? hr == S_OK || broken(hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED) + : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || + (hr == E_INVALIDARG && fmt.nChannels > 2) || + broken(hr == S_OK && + ((fmt.nChannels == 1 && fmt.wBitsPerSample == 16) || + (fmt.nSamplesPerSec == 12000 || fmt.nSamplesPerSec == 96000))), + "Initialize(exclus., %c%lux%2ux%u, RATEADJUST) returns %08lx\n", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + /* Bug in native (Vista/w2k8/w7): after Initialize failed, better * Release this ac and Activate a new one. * A second call (with a known working format) would yield
From: Giovanni Mascellani gmascellani@codeweavers.com
--- dlls/mmdevapi/tests/render.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index f876fe1edd9..765ac6489f6 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -637,6 +637,27 @@ static void test_formats(AUDCLNT_SHAREMODE mode) "Initialize(exclus., %c%lux%2ux%u, RATEADJUST) returns %08lx\n", format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr);
+ IAudioClient_Release(ac); + + hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, + NULL, (void**)&ac); + ok(hr == S_OK, "Activation failed with %08lx\n", hr); + if(hr != S_OK) + continue; + + /* With AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM it always succeeds. */ + hr = IAudioClient_Initialize(ac, mode, AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM, 5000000, 0, &fmt, NULL); + if (mode == AUDCLNT_SHAREMODE_SHARED) { + expected = fmt.nChannels <= 2 ? S_OK : E_INVALIDARG; + todo_wine_if(hr == AUDCLNT_E_UNSUPPORTED_FORMAT) + ok(hr == expected, "Initialize(shared, %c%lux%2ux%u, AUTOCONVERTPCM) returns %08lx\n", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + } else { + todo_wine_if(hr != E_INVALIDARG) + ok(hr == E_INVALIDARG, "Initialize(exclus., %c%lux%2ux%u, AUTOCONVERTPCM) returns %08lx\n", + format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + } + /* Bug in native (Vista/w2k8/w7): after Initialize failed, better * Release this ac and Activate a new one. * A second call (with a known working format) would yield
From: Giovanni Mascellani gmascellani@codeweavers.com
This adds a few more cases in which initializing in exclusive mode can fail even when IsFormatSupported() returned positively. To avoid making the broken() conditions overly complicated I remove the side conditions, which are probably not very useful and depend on the driver anyway.
Also, testing configurations with more than two channels somehow alters the state of the device in a way that is not restored even after releasing the IMMDevice object and creating it again. Specifically, GetChannelVolume() will return more then two channels, even if the audio client is initialized with just two channels. To avoid those failures the format tests are moved to the end. --- dlls/mmdevapi/tests/render.c | 144 +++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 66 deletions(-)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 765ac6489f6..268abcb2a61 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -502,20 +502,21 @@ cleanup: CoTaskMemFree(pwfx); }
-static void test_formats(AUDCLNT_SHAREMODE mode) +static void test_formats(AUDCLNT_SHAREMODE mode, BOOL extensible) { IAudioClient *ac; HRESULT hr, hrs, expected; - WAVEFORMATEX fmt, *pwfx, *pwfx2; + WAVEFORMATEX *pwfx, *pwfx2; + WAVEFORMATEXTENSIBLE fmt; int i, j, k; BOOL compatible;
- fmt.cbSize = 0; + fmt.Format.cbSize = extensible ? sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX) : 0;
for (i = 0; i < ARRAY_SIZE(sampling_rates); i++) { for (j = 0; j < ARRAY_SIZE(channel_counts); j++) { for (k = 0; k < ARRAY_SIZE(sample_formats); k++) { - char format_chr; + char format_chr[3];
hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (void**)&ac); @@ -526,36 +527,55 @@ static void test_formats(AUDCLNT_SHAREMODE mode) hr = IAudioClient_GetMixFormat(ac, &pwfx); ok(hr == S_OK, "GetMixFormat failed: %08lx\n", hr);
- fmt.wFormatTag = sample_formats[k][0]; - fmt.nSamplesPerSec = sampling_rates[i]; - fmt.wBitsPerSample = sample_formats[k][1]; - fmt.nChannels = channel_counts[j]; - fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; - fmt.nAvgBytesPerSec= fmt.nBlockAlign * fmt.nSamplesPerSec; + fmt.Format.wFormatTag = extensible ? WAVE_FORMAT_EXTENSIBLE : sample_formats[k][0]; + fmt.Format.nSamplesPerSec = sampling_rates[i]; + fmt.Format.wBitsPerSample = sample_formats[k][1]; + fmt.Format.nChannels = channel_counts[j]; + fmt.Format.nBlockAlign = fmt.Format.nChannels * fmt.Format.wBitsPerSample / 8; + fmt.Format.nAvgBytesPerSec= fmt.Format.nBlockAlign * fmt.Format.nSamplesPerSec; + + if (extensible) { + fmt.Samples.wValidBitsPerSample = fmt.Format.wBitsPerSample; + switch (fmt.Format.nChannels) { + case 1: fmt.dwChannelMask = KSAUDIO_SPEAKER_MONO; break; + case 2: fmt.dwChannelMask = KSAUDIO_SPEAKER_STEREO; break; + case 4: fmt.dwChannelMask = KSAUDIO_SPEAKER_SURROUND; break; + case 6: fmt.dwChannelMask = KSAUDIO_SPEAKER_5POINT1; break; + case 8: fmt.dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND; break; + } + /* We don't want to fight with the driver over the speaker configuration, + * so just take whatever they give us. */ + if (fmt.Format.nChannels == pwfx->nChannels && pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) + fmt.dwChannelMask = ((WAVEFORMATEXTENSIBLE*)pwfx)->dwChannelMask; + fmt.SubFormat = sample_formats[k][0] == WAVE_FORMAT_PCM ? + KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; + }
- format_chr = fmt.wFormatTag == WAVE_FORMAT_PCM ? 'P' : 'F'; + format_chr[0] = sample_formats[k][0] == WAVE_FORMAT_PCM ? 'P' : 'F'; + format_chr[1] = extensible ? 'X' : '\0'; + format_chr[2] = '\0';
pwfx2 = (WAVEFORMATEX*)0xDEADF00D; - hr = IAudioClient_IsFormatSupported(ac, mode, &fmt, &pwfx2); + hr = IAudioClient_IsFormatSupported(ac, mode, (WAVEFORMATEX*)&fmt, &pwfx2); hrs = hr; if (hr == S_OK) - trace("IsSupported(%s, %c%lux%2ux%u)\n", + trace("IsSupported(%s, %s%lux%2ux%u)\n", mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels); + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels);
/* In shared mode you can only change bit width, not sampling rate or channel count. */ if (mode == AUDCLNT_SHAREMODE_SHARED) { - compatible = fmt.nSamplesPerSec == pwfx->nSamplesPerSec && fmt.nChannels == pwfx->nChannels; + compatible = fmt.Format.nSamplesPerSec == pwfx->nSamplesPerSec && fmt.Format.nChannels == pwfx->nChannels; expected = compatible ? S_OK : S_FALSE; - if (fmt.nChannels > 2) + if (fmt.Format.nChannels > 2 && !extensible) expected = AUDCLNT_E_UNSUPPORTED_FORMAT; - todo_wine_if(fmt.nChannels > 2 && hr != expected) - ok(hr == expected, "IsFormatSupported(shared, %c%lux%2ux%u) returns %08lx, expected %08lx\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr, expected); + todo_wine_if(fmt.Format.nChannels > 2 && hr != expected) + ok(hr == expected, "IsFormatSupported(shared, %s%lux%2ux%u) returns %08lx, expected %08lx\n", + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels, hr, expected); } else { ok(hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == hexcl, - "IsFormatSupported(exclusive, %c%lux%2ux%u) returns %08lx\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + "IsFormatSupported(exclusive, %s%lux%2ux%u) returns %08lx\n", + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels, hr); }
/* Only shared mode suggests something ... GetMixFormat! */ @@ -565,40 +585,35 @@ static void test_formats(AUDCLNT_SHAREMODE mode) pwfx2->nSamplesPerSec == pwfx->nSamplesPerSec && pwfx2->nChannels == pwfx->nChannels && pwfx2->wBitsPerSample == pwfx->wBitsPerSample, - "Suggestion %c%lux%2ux%u differs from GetMixFormat\n", + "Suggestion %s%lux%2ux%u differs from GetMixFormat\n", format_chr, pwfx2->nSamplesPerSec, pwfx2->wBitsPerSample, pwfx2->nChannels); }
- hr = IAudioClient_Initialize(ac, mode, 0, 5000000, 0, &fmt, NULL); + hr = IAudioClient_Initialize(ac, mode, 0, 5000000, 0, (WAVEFORMATEX*)&fmt, NULL); if ((hrs == S_OK) ^ (hr == S_OK)) - trace("Initialize (%s, %c%lux%2ux%u) returns %08lx unlike IsFormatSupported\n", + trace("Initialize (%s, %s%lux%2ux%u) returns %08lx unlike IsFormatSupported\n", mode == AUDCLNT_SHAREMODE_SHARED ? "shared " : "exclus.", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels, hr); if (mode == AUDCLNT_SHAREMODE_SHARED) { expected = hrs == S_OK ? S_OK : AUDCLNT_E_UNSUPPORTED_FORMAT; - if (fmt.nChannels > 2) + if (fmt.Format.nChannels > 2 && !extensible) expected = E_INVALIDARG; - todo_wine_if(fmt.nChannels > 2) - ok(hr == expected, "Initialize(shared, %c%lux%2ux%u) returns %08lx\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + todo_wine_if(fmt.Format.nChannels > 2 && !extensible) + ok(hr == expected, "Initialize(shared, %s%lux%2ux%u) returns %08lx\n", + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels, hr); } else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) /* Unsupported format implies "create failed" and shadows "not allowed" */ ok(hrs == hexcl && (hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == hrs), - "Initialize(noexcl., %c%lux%2ux%u) returns %08lx(%08lx)\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr, hrs); + "Initialize(noexcl., %s%lux%2ux%u) returns %08lx(%08lx)\n", + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels, hr, hrs); else - /* On testbot 48000x16x1 claims support, but does not Initialize. - * Some cards Initialize 44100|48000x16x1 yet claim no support; - * F. Gouget's w7 bots do that for 12000|96000x8|16x1|2 */ - todo_wine_if(fmt.nChannels > 2 && hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) + /* For some drivers Initialize() doesn't match IsFormatSupported(). */ + todo_wine_if(fmt.Format.nChannels > 2 && hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) ok(hrs == S_OK ? hr == S_OK || broken(hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED) : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || - broken(hr == S_OK && - ((fmt.nChannels == 1 && fmt.wBitsPerSample == 16) || - (fmt.nSamplesPerSec == 12000 || fmt.nSamplesPerSec == 96000))) - || (hr == E_INVALIDARG && fmt.nChannels > 2), - "Initialize(exclus., %c%lux%2ux%u) returns %08lx\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + (hr == E_INVALIDARG && fmt.Format.nChannels > 2 && !extensible) || broken(hr == S_OK), + "Initialize(exclus., %s%lux%2ux%u) returns %08lx\n", + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels, hr);
IAudioClient_Release(ac);
@@ -609,33 +624,28 @@ static void test_formats(AUDCLNT_SHAREMODE mode) continue;
/* With AUDCLNT_STREAMFLAGS_RATEADJUST channel count must match, but sampling rate doesn't. */ - hr = IAudioClient_Initialize(ac, mode, AUDCLNT_STREAMFLAGS_RATEADJUST, 5000000, 0, &fmt, NULL); + hr = IAudioClient_Initialize(ac, mode, AUDCLNT_STREAMFLAGS_RATEADJUST, 5000000, 0, (WAVEFORMATEX*)&fmt, NULL); if (mode == AUDCLNT_SHAREMODE_SHARED) { - compatible = fmt.nChannels == pwfx->nChannels; + compatible = fmt.Format.nChannels == pwfx->nChannels; expected = compatible ? S_OK : AUDCLNT_E_UNSUPPORTED_FORMAT; - if (fmt.nChannels > 2) + if (fmt.Format.nChannels > 2 && !extensible) expected = E_INVALIDARG; todo_wine_if(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && hr != expected) - ok(hr == expected, "Initialize(shared, %c%lux%2ux%u, RATEADJUST) returns %08lx\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + ok(hr == expected, "Initialize(shared, %s%lux%2ux%u, RATEADJUST) returns %08lx\n", + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels, hr); } else if (hrs == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) /* Unsupported format implies "create failed" and shadows "not allowed" */ ok(hrs == hexcl && (hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == hrs), - "Initialize(noexcl., %c%lux%2ux%u, RATEADJUST) returns %08lx(%08lx)\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr, hrs); + "Initialize(noexcl., %s%lux%2ux%u, RATEADJUST) returns %08lx(%08lx)\n", + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels, hr, hrs); else - /* On testbot 48000x16x1 claims support, but does not Initialize. - * Some cards Initialize 44100|48000x16x1 yet claim no support; - * F. Gouget's w7 bots do that for 12000|96000x8|16x1|2 */ - todo_wine_if(fmt.nChannels > 2 && hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) + /* For some drivers Initialize() doesn't match IsFormatSupported(). */ + todo_wine_if(fmt.Format.nChannels > 2 && hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED) ok(hrs == S_OK ? hr == S_OK || broken(hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED) : hr == AUDCLNT_E_ENDPOINT_CREATE_FAILED || hr == AUDCLNT_E_UNSUPPORTED_FORMAT || - (hr == E_INVALIDARG && fmt.nChannels > 2) || - broken(hr == S_OK && - ((fmt.nChannels == 1 && fmt.wBitsPerSample == 16) || - (fmt.nSamplesPerSec == 12000 || fmt.nSamplesPerSec == 96000))), - "Initialize(exclus., %c%lux%2ux%u, RATEADJUST) returns %08lx\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + (hr == E_INVALIDARG && fmt.Format.nChannels > 2 && !extensible) || broken(hr == S_OK), + "Initialize(exclus., %s%lux%2ux%u, RATEADJUST) returns %08lx\n", + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels, hr);
IAudioClient_Release(ac);
@@ -646,16 +656,16 @@ static void test_formats(AUDCLNT_SHAREMODE mode) continue;
/* With AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM it always succeeds. */ - hr = IAudioClient_Initialize(ac, mode, AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM, 5000000, 0, &fmt, NULL); + hr = IAudioClient_Initialize(ac, mode, AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM, 5000000, 0, (WAVEFORMATEX*)&fmt, NULL); if (mode == AUDCLNT_SHAREMODE_SHARED) { - expected = fmt.nChannels <= 2 ? S_OK : E_INVALIDARG; + expected = fmt.Format.nChannels <= 2 || extensible ? S_OK : E_INVALIDARG; todo_wine_if(hr == AUDCLNT_E_UNSUPPORTED_FORMAT) - ok(hr == expected, "Initialize(shared, %c%lux%2ux%u, AUTOCONVERTPCM) returns %08lx\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + ok(hr == expected, "Initialize(shared, %s%lux%2ux%u, AUTOCONVERTPCM) returns %08lx\n", + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels, hr); } else { todo_wine_if(hr != E_INVALIDARG) - ok(hr == E_INVALIDARG, "Initialize(exclus., %c%lux%2ux%u, AUTOCONVERTPCM) returns %08lx\n", - format_chr, fmt.nSamplesPerSec, fmt.wBitsPerSample, fmt.nChannels, hr); + ok(hr == E_INVALIDARG, "Initialize(exclus., %s%lux%2ux%u, AUTOCONVERTPCM) returns %08lx\n", + format_chr, fmt.Format.nSamplesPerSec, fmt.Format.wBitsPerSample, fmt.Format.nChannels, hr); }
/* Bug in native (Vista/w2k8/w7): after Initialize failed, better @@ -2826,8 +2836,6 @@ START_TEST(render) }
test_audioclient(); - test_formats(AUDCLNT_SHAREMODE_EXCLUSIVE); - test_formats(AUDCLNT_SHAREMODE_SHARED); test_references(); test_marshal(); if (GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &mode)) @@ -2848,6 +2856,10 @@ START_TEST(render) test_worst_case(); test_endpointvolume(); test_audio_clock_adjustment(); + test_formats(AUDCLNT_SHAREMODE_EXCLUSIVE, FALSE); + test_formats(AUDCLNT_SHAREMODE_SHARED, FALSE); + test_formats(AUDCLNT_SHAREMODE_EXCLUSIVE, TRUE); + test_formats(AUDCLNT_SHAREMODE_SHARED, TRUE);
IMMDevice_Release(dev);
I should probably note that I tested this MR on Windows (with a few different hardware and virtual sound cards, configured with many different channel counts), on Linux (both PulseAudio and ALSA, again with different hardwares and channel counts; though I'm not sure ALSA was sensitive to configuration with more than two channels) and macOS (I couldn't test more than two channels here, because I don't know how to configure that).