[PATCH 0/10] MR8653: mmdevapi/tests: Add a lot of rendering tests.
!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. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8653
From: Giovanni Mascellani <gmascellani(a)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", -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8653
From: Giovanni Mascellani <gmascellani(a)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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8653
From: Giovanni Mascellani <gmascellani(a)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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8653
From: Giovanni Mascellani <gmascellani(a)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); } } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8653
From: Giovanni Mascellani <gmascellani(a)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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8653
From: Giovanni Mascellani <gmascellani(a)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 && -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8653
From: Giovanni Mascellani <gmascellani(a)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", -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8653
From: Giovanni Mascellani <gmascellani(a)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 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8653
From: Giovanni Mascellani <gmascellani(a)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 -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8653
From: Giovanni Mascellani <gmascellani(a)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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8653
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). -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8653#note_111195
participants (2)
-
Giovanni Mascellani -
Giovanni Mascellani (@giomasce)