[MMDEVAPI_WINETEST] Sync with Wine Staging 1.7.37. CORE-9246
[reactos.git] / rostests / winetests / mmdevapi / render.c
index 44472a6..691994c 100644 (file)
@@ -467,6 +467,169 @@ static void test_formats(AUDCLNT_SHAREMODE mode)
     }
 }
 
     }
 }
 
+static void test_formats2(void)
+{
+    IAudioClient *ac;
+    HRESULT hr;
+    WAVEFORMATEX *pwfx, *pwfx2;
+    WAVEFORMATEXTENSIBLE *pwfe, wfe, *pwfe2;
+
+    hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER,
+                            NULL, (void**)&ac);
+
+    ok(hr == S_OK, "Activation failed with %08x\n", hr);
+    if (hr != S_OK)
+        return;
+
+    hr = IAudioClient_GetMixFormat(ac, &pwfx);
+    ok(hr == S_OK, "GetMixFormat failed: %08x\n", hr);
+    if (hr != S_OK)
+        return;
+
+    ok(pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Invalid wFormatTag\n");
+    if (pwfx->wFormatTag != WAVE_FORMAT_EXTENSIBLE) {
+        CoTaskMemFree(pwfx);
+        return;
+    }
+
+    pwfe = (WAVEFORMATEXTENSIBLE*)pwfx;
+    ok(pwfe->Samples.wValidBitsPerSample, "wValidBitsPerSample should be non-zero\n");
+
+    if (pwfx->nChannels > 2) {
+        trace("Limiting channels to 2\n");
+        pwfx->nChannels = 2;
+        pwfx->nBlockAlign = pwfx->wBitsPerSample / 8 * pwfx->nChannels;
+        pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
+        pwfe->dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
+    }
+
+    wfe = *pwfe;
+    pwfx->nAvgBytesPerSec = pwfx->nBlockAlign = 0;
+
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+    ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+       "Exclusive IsFormatSupported with nAvgBytesPerSec=0 and nBlockAlign=0 returned %08x\n", hr);
+
+    pwfx2 = NULL;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+    ok((hr == E_INVALIDARG || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && !pwfx2,
+       "Shared IsFormatSupported with nAvgBytesPerSec=0 and nBlockAlign=0 returned %08x %p\n", hr, pwfx2);
+    CoTaskMemFree(pwfx2);
+
+    pwfx->wFormatTag = WAVE_FORMAT_PCM;
+    pwfx2 = NULL;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+    ok((hr == S_OK || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && !pwfx2,
+       "Shared IsFormatSupported with nAvgBytesPerSec=0 and nBlockAlign=0 returned %08x %p\n", hr, pwfx2);
+    CoTaskMemFree(pwfx2);
+
+    *pwfe = wfe;
+    pwfe->dwChannelMask = 0;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+    ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+       "Exclusive IsFormatSupported with dwChannelMask=0 returned %08x\n", hr);
+
+    pwfx2 = NULL;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+    ok(hr == S_OK,
+       "Shared IsFormatSupported with dwChannelMask=0 returned %08x\n", hr);
+    CoTaskMemFree(pwfx2);
+
+
+    pwfe->dwChannelMask = 0x3ffff;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+    ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+       "Exclusive IsFormatSupported with dwChannelMask=0x3ffff returned %08x\n", hr);
+
+    pwfx2 = NULL;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+    ok(hr == S_OK && !pwfx2,
+       "Shared IsFormatSupported with dwChannelMask=0x3ffff returned %08x %p\n", hr, pwfx2);
+    CoTaskMemFree(pwfx2);
+
+
+    pwfe->dwChannelMask = 0x40000000;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+    ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+       "Exclusive IsFormatSupported with dwChannelMask=0x40000000 returned %08x\n", hr);
+
+    pwfx2 = NULL;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+    ok(hr == S_OK && !pwfx2,
+       "Shared IsFormatSupported with dwChannelMask=0x40000000 returned %08x %p\n", hr, pwfx2);
+    CoTaskMemFree(pwfx2);
+
+    pwfe->dwChannelMask = SPEAKER_ALL | SPEAKER_RESERVED;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+    ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+       "Exclusive IsFormatSupported with dwChannelMask=SPEAKER_ALL | SPEAKER_RESERVED returned %08x\n", hr);
+
+    pwfx2 = NULL;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+    ok(hr == S_OK && !pwfx2,
+       "Shared IsFormatSupported with dwChannelMask=SPEAKER_ALL | SPEAKER_RESERVED returned %08x %p\n", hr, pwfx2);
+    CoTaskMemFree(pwfx2);
+
+    *pwfe = wfe;
+    pwfe->Samples.wValidBitsPerSample = 0;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_EXCLUSIVE, pwfx, NULL);
+    ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT || hr == AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED,
+       "Exclusive IsFormatSupported with wValidBitsPerSample=0 returned %08x\n", hr);
+
+    pwfx2 = NULL;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+    ok((hr == S_FALSE || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && pwfx2,
+       "Shared IsFormatSupported with wValidBitsPerSample=0 returned %08x %p\n", hr, pwfx2);
+    if (pwfx2) {
+        pwfe2 = (WAVEFORMATEXTENSIBLE*)pwfx2;
+        ok(pwfe2->Samples.wValidBitsPerSample == pwfx->wBitsPerSample,
+           "Shared IsFormatSupported had wValidBitsPerSample set to %u, not %u\n",
+           pwfe2->Samples.wValidBitsPerSample, pwfx->wBitsPerSample);
+        CoTaskMemFree(pwfx2);
+    }
+
+    pwfx2 = NULL;
+    pwfe->Samples.wValidBitsPerSample = pwfx->wBitsPerSample + 1;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+    ok((hr == E_INVALIDARG || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && !pwfx2,
+       "Shared IsFormatSupported with wValidBitsPerSample += 1 returned %08x %p\n", hr, pwfx2);
+
+    *pwfe = wfe;
+    memset(&pwfe->SubFormat, 0xff, 16);
+    pwfx2 = NULL;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+    ok(hr == AUDCLNT_E_UNSUPPORTED_FORMAT && !pwfx2,
+       "Shared IsFormatSupported with SubFormat=-1 returned %08x %p\n", hr, pwfx2);
+    CoTaskMemFree(pwfx2);
+
+    *pwfe = wfe;
+    pwfx2 = NULL;
+    pwfe->Samples.wValidBitsPerSample = pwfx->wBitsPerSample = 256;
+    pwfx->nBlockAlign = pwfx->wBitsPerSample / 8 * pwfx->nChannels;
+    pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+    ok((hr == E_INVALIDARG || hr == AUDCLNT_E_UNSUPPORTED_FORMAT) && !pwfx2,
+       "Shared IsFormatSupported with wBitsPerSample=256 returned %08x %p\n", hr, pwfx2);
+    CoTaskMemFree(pwfx2);
+
+    *pwfe = wfe;
+    pwfx2 = NULL;
+    pwfe->Samples.wValidBitsPerSample = pwfx->wBitsPerSample - 1;
+    hr = IAudioClient_IsFormatSupported(ac, AUDCLNT_SHAREMODE_SHARED, pwfx, &pwfx2);
+    ok(hr == S_FALSE && pwfx2,
+       "Shared IsFormatSupported with wValidBitsPerSample-=1 returned %08x %p\n", hr, pwfx2);
+    if (pwfx2) {
+        pwfe2 = (WAVEFORMATEXTENSIBLE*)pwfx2;
+        ok(pwfe2->Samples.wValidBitsPerSample == pwfx->wBitsPerSample,
+           "Shared IsFormatSupported had wValidBitsPerSample set to %u, not %u\n",
+           pwfe2->Samples.wValidBitsPerSample, pwfx->wBitsPerSample);
+        CoTaskMemFree(pwfx2);
+    }
+
+    CoTaskMemFree(pwfx);
+    IAudioClient_Release(ac);
+}
+
 static void test_references(void)
 {
     IAudioClient *ac;
 static void test_references(void)
 {
     IAudioClient *ac;
@@ -1020,7 +1183,7 @@ static void test_clock(int share)
     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
     ok(pos >= last, "Position %u vs. last %u\n", (UINT)pos,(UINT)last);
     last = pos;
     ok(hr == S_OK, "GetPosition failed: %08x\n", hr);
     ok(pos >= last, "Position %u vs. last %u\n", (UINT)pos,(UINT)last);
     last = pos;
-    if(/*share &&*/ winetest_debug>1) todo_wine
+    if(/*share &&*/ winetest_debug>1)
         ok(pos*1000/freq <= slept*1.1, "Position %u too far after stop %ums\n", (UINT)pos, slept);
 
     hr = IAudioClient_Start(ac); /* #2 */
         ok(pos*1000/freq <= slept*1.1, "Position %u too far after stop %ums\n", (UINT)pos, slept);
 
     hr = IAudioClient_Start(ac); /* #2 */
@@ -1054,7 +1217,7 @@ static void test_clock(int share)
     ok(pos * pwfx->nSamplesPerSec <= sum * freq, "Position %u > written %u\n", (UINT)pos, sum);
     /* Prove that Stop must not drop frames (in shared mode). */
     ok(pad ? pos > last : pos >= last, "Position %u vs. last %u\n", (UINT)pos,(UINT)last);
     ok(pos * pwfx->nSamplesPerSec <= sum * freq, "Position %u > written %u\n", (UINT)pos, sum);
     /* Prove that Stop must not drop frames (in shared mode). */
     ok(pad ? pos > last : pos >= last, "Position %u vs. last %u\n", (UINT)pos,(UINT)last);
-    if (share && pad > 0 && winetest_debug>1) todo_wine
+    if (share && pad > 0 && winetest_debug>1)
         ok(pos*1000/freq <= slept*1.1, "Position %u too far after playing %ums\n", (UINT)pos, slept);
     /* in exclusive mode, testbot's w7 machines yield pos > sum-pad */
     if(/*share &&*/ winetest_debug>1)
         ok(pos*1000/freq <= slept*1.1, "Position %u too far after playing %ums\n", (UINT)pos, slept);
     /* in exclusive mode, testbot's w7 machines yield pos > sum-pad */
     if(/*share &&*/ winetest_debug>1)
@@ -1133,7 +1296,7 @@ static void test_clock(int share)
     ok(pos >= last, "Position %u vs. last %u\n", (UINT)pos,(UINT)last);
     ok(pcpos > pcpos0, "pcpos should increase\n");
     ok(pos * pwfx->nSamplesPerSec <= sum * freq, "Position %u > written %u\n", (UINT)pos, sum);
     ok(pos >= last, "Position %u vs. last %u\n", (UINT)pos,(UINT)last);
     ok(pcpos > pcpos0, "pcpos should increase\n");
     ok(pos * pwfx->nSamplesPerSec <= sum * freq, "Position %u > written %u\n", (UINT)pos, sum);
-    if (pad > 0 && winetest_debug>1) todo_wine
+    if (pad > 0 && winetest_debug>1)
         ok(pos*1000/freq <= slept*1.1, "Position %u too far after stop %ums\n", (UINT)pos, slept);
     if(winetest_debug>1)
         ok(pos * pwfx->nSamplesPerSec == (sum-pad) * freq,
         ok(pos*1000/freq <= slept*1.1, "Position %u too far after stop %ums\n", (UINT)pos, slept);
     if(winetest_debug>1)
         ok(pos * pwfx->nSamplesPerSec == (sum-pad) * freq,
@@ -1223,7 +1386,7 @@ static void test_clock(int share)
             ok(pos*1000/freq <= slept*1.1, "Position %u too far after %ums\n", (UINT)pos, slept);
             if (pad) /* not in case of underrun */
                 ok((pos-last)*1000/freq >= 90 && 110 >= (pos-last)*1000/freq,
             ok(pos*1000/freq <= slept*1.1, "Position %u too far after %ums\n", (UINT)pos, slept);
             if (pad) /* not in case of underrun */
                 ok((pos-last)*1000/freq >= 90 && 110 >= (pos-last)*1000/freq,
-                   "Position delta %ld not regular\n", (long)(pos-last));
+                   "Position delta %ld not regular: %ld ms\n", (long)(pos-last), (long)((pos-last)*1000/freq));
         }
         last = pos;
 
         }
         last = pos;
 
@@ -1237,7 +1400,7 @@ static void test_clock(int share)
         /* ok(hr == AUDCLNT_E_BUFFER_TOO_LARGE || (hr == S_OK && i==0) without todo_wine */
         ok(hr == S_OK || hr == AUDCLNT_E_BUFFER_TOO_LARGE,
            "GetBuffer large (%u) failed: %08x\n", avail, hr);
         /* ok(hr == AUDCLNT_E_BUFFER_TOO_LARGE || (hr == S_OK && i==0) without todo_wine */
         ok(hr == S_OK || hr == AUDCLNT_E_BUFFER_TOO_LARGE,
            "GetBuffer large (%u) failed: %08x\n", avail, hr);
-        if(hr == S_OK && i) todo_wine ok(FALSE, "GetBuffer large (%u) at iteration %d\n", avail, i);
+        if(hr == S_OK && i) ok(FALSE, "GetBuffer large (%u) at iteration %d\n", avail, i);
         /* Only the first iteration should allow that large a buffer
          * as prefill was drained during the first 350+100ms sleep.
          * Afterwards, only 100ms of data should find room per iteration. */
         /* Only the first iteration should allow that large a buffer
          * as prefill was drained during the first 350+100ms sleep.
          * Afterwards, only 100ms of data should find room per iteration. */
@@ -2256,6 +2419,7 @@ START_TEST(render)
     test_audioclient();
     test_formats(AUDCLNT_SHAREMODE_EXCLUSIVE);
     test_formats(AUDCLNT_SHAREMODE_SHARED);
     test_audioclient();
     test_formats(AUDCLNT_SHAREMODE_EXCLUSIVE);
     test_formats(AUDCLNT_SHAREMODE_SHARED);
+    test_formats2();
     test_references();
     test_marshal();
     trace("Output to a MS-DOS console is particularly slow and disturbs timing.\n");
     test_references();
     test_marshal();
     trace("Output to a MS-DOS console is particularly slow and disturbs timing.\n");