1 /* 2 * Tests basic sound playback in DirectSound. 3 * In particular we test each standard Windows sound format to make sure 4 * we handle the sound card/driver quirks correctly. 5 * 6 * Part of this test involves playing test tones. But this only makes 7 * sense if someone is going to carefully listen to it, and would only 8 * bother everyone else. 9 * So this is only done if the test is being run in interactive mode. 10 * 11 * Copyright (c) 2002-2004 Francois Gouget 12 * Copyright (c) 2007 Maarten Lankhorst 13 * 14 * This library is free software; you can redistribute it and/or 15 * modify it under the terms of the GNU Lesser General Public 16 * License as published by the Free Software Foundation; either 17 * version 2.1 of the License, or (at your option) any later version. 18 * 19 * This library is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 * Lesser General Public License for more details. 23 * 24 * You should have received a copy of the GNU Lesser General Public 25 * License along with this library; if not, write to the Free Software 26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 27 */ 28 29 #include "dsound_test.h" 30 31 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); 32 33 static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL; 34 static HRESULT (WINAPI *pDirectSoundCreate)(LPCGUID,LPDIRECTSOUND*, 35 LPUNKNOWN)=NULL; 36 37 static BOOL gotdx8; 38 39 static void IDirectSound_test(LPDIRECTSOUND dso, BOOL initialized, 40 LPCGUID lpGuid) 41 { 42 HRESULT rc; 43 DSCAPS dscaps; 44 int ref; 45 IUnknown * unknown; 46 IDirectSound * ds; 47 IDirectSound8 * ds8; 48 DWORD speaker_config, new_speaker_config, ref_speaker_config; 49 50 /* Try to Query for objects */ 51 rc=IDirectSound_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown); 52 ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IUnknown) failed: %08x\n", rc); 53 if (rc==DS_OK) 54 IDirectSound_Release(unknown); 55 56 rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds); 57 ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %08x\n", rc); 58 if (rc==DS_OK) 59 IDirectSound_Release(ds); 60 61 rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8); 62 ok(rc==E_NOINTERFACE,"IDirectSound_QueryInterface(IID_IDirectSound8) " 63 "should have failed: %08x\n",rc); 64 if (rc==DS_OK) 65 IDirectSound8_Release(ds8); 66 67 if (initialized == FALSE) { 68 /* try uninitialized object */ 69 rc=IDirectSound_GetCaps(dso,0); 70 ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetCaps(NULL) " 71 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc); 72 73 rc=IDirectSound_GetCaps(dso,&dscaps); 74 ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetCaps() " 75 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc); 76 77 rc=IDirectSound_Compact(dso); 78 ok(rc==DSERR_UNINITIALIZED,"IDirectSound_Compact() " 79 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc); 80 81 rc=IDirectSound_GetSpeakerConfig(dso,&speaker_config); 82 ok(rc==DSERR_UNINITIALIZED,"IDirectSound_GetSpeakerConfig() " 83 "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc); 84 85 rc=IDirectSound_Initialize(dso,lpGuid); 86 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, 87 "IDirectSound_Initialize() failed: %08x\n",rc); 88 if (rc==DSERR_NODRIVER) { 89 trace(" No Driver\n"); 90 goto EXIT; 91 } else if (rc==E_FAIL) { 92 trace(" No Device\n"); 93 goto EXIT; 94 } else if (rc==DSERR_ALLOCATED) { 95 trace(" Already In Use\n"); 96 goto EXIT; 97 } 98 } 99 100 rc=IDirectSound_Initialize(dso,lpGuid); 101 ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSound_Initialize() " 102 "should have returned DSERR_ALREADYINITIALIZED: %08x\n", rc); 103 104 /* DSOUND: Error: Invalid caps buffer */ 105 rc=IDirectSound_GetCaps(dso,0); 106 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetCaps(NULL) " 107 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); 108 109 ZeroMemory(&dscaps, sizeof(dscaps)); 110 111 /* DSOUND: Error: Invalid caps buffer */ 112 rc=IDirectSound_GetCaps(dso,&dscaps); 113 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetCaps() " 114 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); 115 116 dscaps.dwSize=sizeof(dscaps); 117 118 /* DSOUND: Running on a certified driver */ 119 rc=IDirectSound_GetCaps(dso,&dscaps); 120 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %08x\n",rc); 121 122 rc=IDirectSound_Compact(dso); 123 ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound_Compact() failed: %08x\n", rc); 124 125 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 126 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 127 128 rc=IDirectSound_Compact(dso); 129 ok(rc==DS_OK,"IDirectSound_Compact() failed: %08x\n",rc); 130 131 rc=IDirectSound_GetSpeakerConfig(dso,0); 132 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_GetSpeakerConfig(NULL) " 133 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); 134 135 rc=IDirectSound_GetSpeakerConfig(dso,&speaker_config); 136 ok(rc==DS_OK,"IDirectSound_GetSpeakerConfig() failed: %08x\n", rc); 137 ref_speaker_config = speaker_config; 138 139 speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 140 DSSPEAKER_GEOMETRY_WIDE); 141 if (speaker_config == ref_speaker_config) 142 speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, 143 DSSPEAKER_GEOMETRY_NARROW); 144 if(rc==DS_OK) { 145 rc=IDirectSound_SetSpeakerConfig(dso,speaker_config); 146 ok(rc==DS_OK,"IDirectSound_SetSpeakerConfig() failed: %08x\n", rc); 147 } 148 if (rc==DS_OK) { 149 rc=IDirectSound_GetSpeakerConfig(dso,&new_speaker_config); 150 ok(rc==DS_OK,"IDirectSound_GetSpeakerConfig() failed: %08x\n", rc); 151 if (rc==DS_OK && speaker_config!=new_speaker_config) 152 trace("IDirectSound_GetSpeakerConfig() failed to set speaker " 153 "config: expected 0x%08x, got 0x%08x\n", 154 speaker_config,new_speaker_config); 155 IDirectSound_SetSpeakerConfig(dso,ref_speaker_config); 156 } 157 158 EXIT: 159 ref=IDirectSound_Release(dso); 160 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 161 } 162 163 static void IDirectSound_tests(void) 164 { 165 HRESULT rc; 166 IDirectSound *dso=(IDirectSound*)0xdeadbeef; 167 LPCLASSFACTORY cf=NULL; 168 169 trace("Testing IDirectSound\n"); 170 171 rc=CoGetClassObject(&CLSID_DirectSound, CLSCTX_INPROC_SERVER, NULL, 172 &IID_IClassFactory, (void**)&cf); 173 ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSound, IID_IClassFactory) " 174 "failed: %08x\n", rc); 175 176 rc=CoGetClassObject(&CLSID_DirectSound, CLSCTX_INPROC_SERVER, NULL, 177 &IID_IUnknown, (void**)&cf); 178 ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSound, IID_IUnknown) " 179 "failed: %08x\n", rc); 180 181 /* COM aggregation */ 182 rc=CoCreateInstance(&CLSID_DirectSound, (IUnknown*)&dso, CLSCTX_INPROC_SERVER, 183 &IID_IDirectSound, (void**)&dso); 184 ok(rc==CLASS_E_NOAGGREGATION || broken(rc==DSERR_INVALIDPARAM), 185 "DirectMusicPerformance create failed: %08x, expected CLASS_E_NOAGGREGATION\n", rc); 186 187 /* try the COM class factory method of creation with no device specified */ 188 rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, 189 &IID_IDirectSound, (void**)&dso); 190 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc); 191 if (dso) 192 IDirectSound_test(dso, FALSE, NULL); 193 194 /* try the COM class factory method of creation with default playback 195 * device specified */ 196 rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, 197 &IID_IDirectSound, (void**)&dso); 198 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc); 199 if (dso) 200 IDirectSound_test(dso, FALSE, &DSDEVID_DefaultPlayback); 201 202 /* try the COM class factory method of creation with default voice 203 * playback device specified */ 204 rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, 205 &IID_IDirectSound, (void**)&dso); 206 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc); 207 if (dso) 208 IDirectSound_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback); 209 210 /* try the COM class factory method of creation with a bad 211 * IID specified */ 212 rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, 213 &CLSID_DirectSoundPrivate, (void**)&dso); 214 ok(rc==E_NOINTERFACE, 215 "CoCreateInstance(CLSID_DirectSound,CLSID_DirectSoundPrivate) " 216 "should have failed: %08x\n",rc); 217 218 /* try the COM class factory method of creation with a bad 219 * GUID and IID specified */ 220 rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER, 221 &IID_IDirectSound, (void**)&dso); 222 ok(rc==REGDB_E_CLASSNOTREG, 223 "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound) " 224 "should have failed: %08x\n",rc); 225 226 /* try with no device specified */ 227 rc=pDirectSoundCreate(NULL,&dso,NULL); 228 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, 229 "DirectSoundCreate(NULL) failed: %08x\n",rc); 230 if (rc==S_OK && dso) 231 IDirectSound_test(dso, TRUE, NULL); 232 233 /* try with default playback device specified */ 234 rc=pDirectSoundCreate(&DSDEVID_DefaultPlayback,&dso,NULL); 235 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, 236 "DirectSoundCreate(DSDEVID_DefaultPlayback) failed: %08x\n", rc); 237 if (rc==DS_OK && dso) 238 IDirectSound_test(dso, TRUE, NULL); 239 240 /* try with default voice playback device specified */ 241 rc=pDirectSoundCreate(&DSDEVID_DefaultVoicePlayback,&dso,NULL); 242 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, 243 "DirectSoundCreate(DSDEVID_DefaultVoicePlayback) failed: %08x\n", rc); 244 if (rc==DS_OK && dso) 245 IDirectSound_test(dso, TRUE, NULL); 246 247 /* try with a bad device specified */ 248 rc=pDirectSoundCreate(&DSDEVID_DefaultVoiceCapture,&dso,NULL); 249 ok(rc==DSERR_NODRIVER,"DirectSoundCreate(DSDEVID_DefaultVoiceCapture) " 250 "should have failed: %08x\n",rc); 251 if (rc==DS_OK && dso) 252 IDirectSound_Release(dso); 253 } 254 255 static HRESULT test_dsound(LPGUID lpGuid) 256 { 257 HRESULT rc; 258 LPDIRECTSOUND dso=NULL; 259 int ref; 260 261 /* DSOUND: Error: Invalid interface buffer */ 262 rc=pDirectSoundCreate(lpGuid,0,NULL); 263 ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate() should have returned " 264 "DSERR_INVALIDPARAM, returned: %08x\n",rc); 265 266 /* Create the DirectSound object */ 267 rc=pDirectSoundCreate(lpGuid,&dso,NULL); 268 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, 269 "DirectSoundCreate() failed: %08x\n",rc); 270 if (rc!=DS_OK) 271 return rc; 272 273 /* Try the enumerated device */ 274 IDirectSound_test(dso, TRUE, lpGuid); 275 276 /* Try the COM class factory method of creation with enumerated device */ 277 rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, 278 &IID_IDirectSound, (void**)&dso); 279 ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc); 280 if (dso) 281 IDirectSound_test(dso, FALSE, lpGuid); 282 283 /* Create a DirectSound object */ 284 rc=pDirectSoundCreate(lpGuid,&dso,NULL); 285 ok(rc==DS_OK,"DirectSoundCreate() failed: %08x\n",rc); 286 if (rc==DS_OK) { 287 LPDIRECTSOUND dso1=NULL; 288 289 /* Create a second DirectSound object */ 290 rc=pDirectSoundCreate(lpGuid,&dso1,NULL); 291 ok(rc==DS_OK,"DirectSoundCreate() failed: %08x\n",rc); 292 if (rc==DS_OK) { 293 /* Release the second DirectSound object */ 294 ref=IDirectSound_Release(dso1); 295 ok(ref==0,"IDirectSound_Release() has %d references, should have " 296 "0\n",ref); 297 ok(dso!=dso1,"DirectSound objects should be unique: dso=%p,dso1=%p\n",dso,dso1); 298 } 299 300 /* Release the first DirectSound object */ 301 ref=IDirectSound_Release(dso); 302 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n", 303 ref); 304 if (ref!=0) 305 return DSERR_GENERIC; 306 } else 307 return rc; 308 309 /* Create a DirectSound object */ 310 rc=pDirectSoundCreate(lpGuid,&dso,NULL); 311 ok(rc==DS_OK,"DirectSoundCreate() failed: %08x\n",rc); 312 if (rc==DS_OK) { 313 LPDIRECTSOUNDBUFFER secondary; 314 DSBUFFERDESC bufdesc; 315 WAVEFORMATEX wfx; 316 317 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1); 318 ZeroMemory(&bufdesc, sizeof(bufdesc)); 319 bufdesc.dwSize=sizeof(bufdesc); 320 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D; 321 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, 322 wfx.nBlockAlign); 323 bufdesc.lpwfxFormat=&wfx; 324 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 325 ok((rc==DS_OK && secondary!=NULL) || broken(rc == DSERR_CONTROLUNAVAIL), /* vmware drivers on w2k */ 326 "IDirectSound_CreateSoundBuffer() failed to create a secondary " 327 "buffer %08x\n",rc); 328 if (rc==DS_OK && secondary!=NULL) { 329 LPDIRECTSOUND3DBUFFER buffer3d; 330 rc=IDirectSound_QueryInterface(secondary, &IID_IDirectSound3DBuffer, 331 (void **)&buffer3d); 332 ok(rc==DS_OK && buffer3d!=NULL,"IDirectSound_QueryInterface() " 333 "failed: %08x\n",rc); 334 if (rc==DS_OK && buffer3d!=NULL) { 335 ref=IDirectSound3DBuffer_AddRef(buffer3d); 336 ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, " 337 "should have 2\n",ref); 338 } 339 ref=IDirectSoundBuffer_AddRef(secondary); 340 ok(ref==2,"IDirectSoundBuffer_AddRef() has %d references, " 341 "should have 2\n",ref); 342 } 343 /* release with buffer */ 344 ref=IDirectSound_Release(dso); 345 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n", 346 ref); 347 if (ref!=0) 348 return DSERR_GENERIC; 349 } else 350 return rc; 351 352 return DS_OK; 353 } 354 355 static HRESULT test_primary(LPGUID lpGuid) 356 { 357 HRESULT rc; 358 LPDIRECTSOUND dso=NULL; 359 LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL; 360 DSBUFFERDESC bufdesc; 361 DSCAPS dscaps; 362 WAVEFORMATEX wfx; 363 int ref; 364 365 /* Create the DirectSound object */ 366 rc=pDirectSoundCreate(lpGuid,&dso,NULL); 367 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, 368 "DirectSoundCreate() failed: %08x\n",rc); 369 if (rc!=DS_OK) 370 return rc; 371 372 /* Get the device capabilities */ 373 ZeroMemory(&dscaps, sizeof(dscaps)); 374 dscaps.dwSize=sizeof(dscaps); 375 rc=IDirectSound_GetCaps(dso,&dscaps); 376 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %08x\n",rc); 377 if (rc!=DS_OK) 378 goto EXIT; 379 380 /* DSOUND: Error: Invalid buffer description pointer */ 381 rc=IDirectSound_CreateSoundBuffer(dso,0,0,NULL); 382 ok(rc==DSERR_INVALIDPARAM, 383 "IDirectSound_CreateSoundBuffer() should have failed: %08x\n", rc); 384 385 /* DSOUND: Error: NULL pointer is invalid */ 386 /* DSOUND: Error: Invalid buffer description pointer */ 387 rc=IDirectSound_CreateSoundBuffer(dso,0,&primary,NULL); 388 ok(rc==DSERR_INVALIDPARAM && primary==0, 389 "IDirectSound_CreateSoundBuffer() should have failed: rc=%08x," 390 "dsbo=%p\n",rc,primary); 391 392 /* DSOUND: Error: Invalid size */ 393 /* DSOUND: Error: Invalid buffer description */ 394 primary=NULL; 395 ZeroMemory(&bufdesc, sizeof(bufdesc)); 396 bufdesc.dwSize=sizeof(bufdesc)-1; 397 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 398 ok(rc==DSERR_INVALIDPARAM && primary==0, 399 "IDirectSound_CreateSoundBuffer() should have failed: rc=%08x," 400 "primary=%p\n",rc,primary); 401 402 /* DSOUND: Error: DSBCAPS_PRIMARYBUFFER flag with non-NULL lpwfxFormat */ 403 /* DSOUND: Error: Invalid buffer description pointer */ 404 primary=NULL; 405 ZeroMemory(&bufdesc, sizeof(bufdesc)); 406 bufdesc.dwSize=sizeof(bufdesc); 407 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; 408 bufdesc.lpwfxFormat=&wfx; 409 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 410 ok(rc==DSERR_INVALIDPARAM && primary==0, 411 "IDirectSound_CreateSoundBuffer() should have failed: rc=%08x," 412 "primary=%p\n",rc,primary); 413 414 /* DSOUND: Error: No DSBCAPS_PRIMARYBUFFER flag with NULL lpwfxFormat */ 415 /* DSOUND: Error: Invalid buffer description pointer */ 416 primary=NULL; 417 ZeroMemory(&bufdesc, sizeof(bufdesc)); 418 bufdesc.dwSize=sizeof(bufdesc); 419 bufdesc.dwFlags=0; 420 bufdesc.lpwfxFormat=NULL; 421 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 422 ok(rc==DSERR_INVALIDPARAM && primary==0, 423 "IDirectSound_CreateSoundBuffer() should have failed: rc=%08x," 424 "primary=%p\n",rc,primary); 425 426 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */ 427 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 428 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 429 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 430 if (rc!=DS_OK) 431 goto EXIT; 432 433 /* Testing the primary buffer */ 434 primary=NULL; 435 ZeroMemory(&bufdesc, sizeof(bufdesc)); 436 bufdesc.dwSize=sizeof(bufdesc); 437 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME; 438 bufdesc.lpwfxFormat = &wfx; 439 init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2); 440 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 441 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_CreateSoundBuffer() should have " 442 "returned DSERR_INVALIDPARAM, returned: %08x\n", rc); 443 if (rc==DS_OK && primary!=NULL) 444 IDirectSoundBuffer_Release(primary); 445 446 primary=NULL; 447 ZeroMemory(&bufdesc, sizeof(bufdesc)); 448 bufdesc.dwSize=sizeof(bufdesc); 449 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME; 450 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 451 ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL), 452 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: %08x\n",rc); 453 if (rc==DSERR_CONTROLUNAVAIL) 454 trace(" No Primary\n"); 455 else if (rc==DS_OK && primary!=NULL) { 456 LONG vol; 457 458 /* Try to create a second primary buffer */ 459 /* DSOUND: Error: The primary buffer already exists. 460 * Any changes made to the buffer description will be ignored. */ 461 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&second,NULL); 462 ok(rc==DS_OK && second==primary, 463 "IDirectSound_CreateSoundBuffer() should have returned original " 464 "primary buffer: %08x\n",rc); 465 ref=IDirectSoundBuffer_Release(second); 466 ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, " 467 "should have 1\n",ref); 468 469 /* Try to duplicate a primary buffer */ 470 /* DSOUND: Error: Can't duplicate primary buffers */ 471 rc=IDirectSound_DuplicateSoundBuffer(dso,primary,&third); 472 /* rc=0x88780032 */ 473 ok(rc!=DS_OK,"IDirectSound_DuplicateSoundBuffer() primary buffer " 474 "should have failed %08x\n",rc); 475 476 rc=IDirectSoundBuffer_GetVolume(primary,&vol); 477 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc); 478 479 if (winetest_interactive) { 480 trace("Playing a 5 seconds reference tone at the current " 481 "volume.\n"); 482 if (rc==DS_OK) 483 trace("(the current volume is %d according to DirectSound)\n", 484 vol); 485 trace("All subsequent tones should be identical to this one.\n"); 486 trace("Listen for stutter, changes in pitch, volume, etc.\n"); 487 } 488 test_buffer(dso,&primary,1,FALSE,0,FALSE,0,winetest_interactive && 489 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0,FALSE,0); 490 491 ref=IDirectSoundBuffer_Release(primary); 492 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references\n",ref); 493 494 ref=IDirectSoundBuffer_AddRef(primary); 495 ok(ref==1,"IDirectSoundBuffer_AddRef() primary has %d references\n",ref); 496 497 ref=IDirectSoundBuffer_Release(primary); 498 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references\n",ref); 499 500 ref=IDirectSoundBuffer_Release(primary); 501 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 502 "should have 0\n",ref); 503 } 504 505 /* Set the CooperativeLevel back to normal */ 506 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 507 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 508 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 509 510 EXIT: 511 ref=IDirectSound_Release(dso); 512 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 513 if (ref!=0) 514 return DSERR_GENERIC; 515 516 return rc; 517 } 518 519 /* 520 * Test the primary buffer at different formats while keeping the 521 * secondary buffer at a constant format. 522 */ 523 static HRESULT test_primary_secondary(LPGUID lpGuid) 524 { 525 HRESULT rc; 526 LPDIRECTSOUND dso=NULL; 527 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL; 528 DSBUFFERDESC bufdesc; 529 DSCAPS dscaps; 530 WAVEFORMATEX wfx, wfx2; 531 int f,ref,tag; 532 533 /* Create the DirectSound object */ 534 rc=pDirectSoundCreate(lpGuid,&dso,NULL); 535 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, 536 "DirectSoundCreate() failed: %08x\n",rc); 537 if (rc!=DS_OK) 538 return rc; 539 540 /* Get the device capabilities */ 541 ZeroMemory(&dscaps, sizeof(dscaps)); 542 dscaps.dwSize=sizeof(dscaps); 543 rc=IDirectSound_GetCaps(dso,&dscaps); 544 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %08x\n",rc); 545 if (rc!=DS_OK) 546 goto EXIT; 547 548 /* We must call SetCooperativeLevel before creating primary buffer */ 549 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 550 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 551 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 552 if (rc!=DS_OK) 553 goto EXIT; 554 555 ZeroMemory(&bufdesc, sizeof(bufdesc)); 556 bufdesc.dwSize=sizeof(bufdesc); 557 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; 558 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 559 ok(rc==DS_OK && primary!=NULL, 560 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer %08x\n",rc); 561 562 if (rc==DS_OK && primary!=NULL) { 563 for (f=0;f<NB_FORMATS;f++) { 564 for (tag=0;tag<NB_TAGS;tag++) { 565 /* if float, we only want to test 32-bit */ 566 if ((format_tags[tag] == WAVE_FORMAT_IEEE_FLOAT) && (formats[f][1] != 32)) 567 continue; 568 569 /* We must call SetCooperativeLevel to be allowed to call 570 * SetFormat */ 571 /* DSOUND: Setting DirectSound cooperative level to 572 * DSSCL_PRIORITY */ 573 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 574 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 575 if (rc!=DS_OK) 576 goto EXIT; 577 578 init_format(&wfx,format_tags[tag],formats[f][0],formats[f][1], 579 formats[f][2]); 580 wfx2=wfx; 581 rc=IDirectSoundBuffer_SetFormat(primary,&wfx); 582 583 if (wfx.wBitsPerSample <= 16) 584 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat(%s) failed: %08x\n", 585 format_string(&wfx), rc); 586 else 587 ok(rc==DS_OK || rc == E_INVALIDARG, "SetFormat (%s) failed: %08x\n", 588 format_string(&wfx), rc); 589 590 /* There is no guarantee that SetFormat will actually change the 591 * format to what we asked for. It depends on what the soundcard 592 * supports. So we must re-query the format. 593 */ 594 rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL); 595 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc); 596 if (rc==DS_OK && 597 (wfx.wFormatTag!=wfx2.wFormatTag || 598 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec || 599 wfx.wBitsPerSample!=wfx2.wBitsPerSample || 600 wfx.nChannels!=wfx2.nChannels)) { 601 trace("Requested primary format tag=0x%04x %dx%dx%d " 602 "avg.B/s=%d align=%d\n", 603 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample, 604 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign); 605 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n", 606 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample, 607 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign); 608 } 609 610 /* Set the CooperativeLevel back to normal */ 611 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 612 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 613 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 614 615 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2); 616 617 secondary=NULL; 618 ZeroMemory(&bufdesc, sizeof(bufdesc)); 619 bufdesc.dwSize=sizeof(bufdesc); 620 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; 621 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, 622 wfx.nBlockAlign); 623 bufdesc.lpwfxFormat=&wfx2; 624 if (winetest_interactive) { 625 trace(" Testing a primary buffer at %dx%dx%d (fmt=%d) with a " 626 "secondary buffer at %dx%dx%d\n", 627 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,format_tags[tag], 628 wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels); 629 } 630 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 631 ok((rc==DS_OK && secondary!=NULL) || broken(rc == DSERR_CONTROLUNAVAIL), /* vmware drivers on w2k */ 632 "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc); 633 634 if (rc==DS_OK && secondary!=NULL) { 635 test_buffer(dso,&secondary,0,FALSE,0,FALSE,0, 636 winetest_interactive,1.0,0,NULL,0,0,FALSE,0); 637 638 ref=IDirectSoundBuffer_Release(secondary); 639 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " 640 "should have 0\n",ref); 641 } 642 } 643 } 644 645 ref=IDirectSoundBuffer_Release(primary); 646 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 647 "should have 0\n",ref); 648 } 649 650 /* Set the CooperativeLevel back to normal */ 651 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 652 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 653 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 654 655 EXIT: 656 ref=IDirectSound_Release(dso); 657 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 658 if (ref!=0) 659 return DSERR_GENERIC; 660 661 return rc; 662 } 663 664 static HRESULT test_secondary(LPGUID lpGuid) 665 { 666 HRESULT rc; 667 LPDIRECTSOUND dso=NULL; 668 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL; 669 DSBUFFERDESC bufdesc; 670 DSCAPS dscaps; 671 WAVEFORMATEX wfx, wfx1; 672 DWORD f, tag; 673 int ref; 674 675 /* Create the DirectSound object */ 676 rc=pDirectSoundCreate(lpGuid,&dso,NULL); 677 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, 678 "DirectSoundCreate() failed: %08x\n",rc); 679 if (rc!=DS_OK) 680 return rc; 681 682 /* Get the device capabilities */ 683 ZeroMemory(&dscaps, sizeof(dscaps)); 684 dscaps.dwSize=sizeof(dscaps); 685 rc=IDirectSound_GetCaps(dso,&dscaps); 686 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %08x\n",rc); 687 if (rc!=DS_OK) 688 goto EXIT; 689 690 /* We must call SetCooperativeLevel before creating primary buffer */ 691 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 692 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 693 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 694 if (rc!=DS_OK) 695 goto EXIT; 696 697 ZeroMemory(&bufdesc, sizeof(bufdesc)); 698 bufdesc.dwSize=sizeof(bufdesc); 699 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; 700 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 701 ok(rc==DS_OK && primary!=NULL, 702 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer %08x\n",rc); 703 704 if (rc==DS_OK && primary!=NULL) { 705 rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL); 706 ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc); 707 if (rc!=DS_OK) 708 goto EXIT1; 709 710 for (f=0;f<NB_FORMATS;f++) { 711 for (tag=0;tag<NB_TAGS;tag++) { 712 WAVEFORMATEXTENSIBLE wfxe; 713 714 /* if float, we only want to test 32-bit */ 715 if ((format_tags[tag] == WAVE_FORMAT_IEEE_FLOAT) && (formats[f][1] != 32)) 716 continue; 717 718 init_format(&wfx,format_tags[tag],formats[f][0],formats[f][1], 719 formats[f][2]); 720 secondary=NULL; 721 ZeroMemory(&bufdesc, sizeof(bufdesc)); 722 bufdesc.dwSize=sizeof(bufdesc); 723 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; 724 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, 725 wfx.nBlockAlign); 726 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 727 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_CreateSoundBuffer() " 728 "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); 729 if (rc==DS_OK && secondary!=NULL) 730 IDirectSoundBuffer_Release(secondary); 731 732 secondary=NULL; 733 ZeroMemory(&bufdesc, sizeof(bufdesc)); 734 bufdesc.dwSize=sizeof(bufdesc); 735 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; 736 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, 737 wfx.nBlockAlign); 738 bufdesc.lpwfxFormat=&wfx; 739 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 740 if (gotdx8 || wfx.wBitsPerSample <= 16 || wfx.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) 741 { 742 if (wfx.wBitsPerSample > 16) 743 ok(broken((rc == DSERR_CONTROLUNAVAIL || rc == DSERR_INVALIDCALL || rc == DSERR_INVALIDPARAM /* 2003 */) && !secondary) 744 || rc == DS_OK, /* driver dependent? */ 745 "IDirectSound_CreateSoundBuffer() " 746 "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) " 747 "and NULL, returned: %08x %p\n", rc, secondary); 748 else 749 ok((rc==DS_OK && secondary!=NULL) || broken(rc == DSERR_CONTROLUNAVAIL), /* vmware drivers on w2k */ 750 "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc); 751 } 752 else 753 ok(rc==E_INVALIDARG, "Creating %d bpp buffer on dx < 8 returned: %p %08x\n", 754 wfx.wBitsPerSample, secondary, rc); 755 756 if (!gotdx8) 757 { 758 win_skip("Not doing the WAVE_FORMAT_EXTENSIBLE tests\n"); 759 /* Apparently they succeed with bogus values, 760 * which means that older dsound doesn't look at them 761 */ 762 goto no_wfe; 763 } 764 765 if (secondary) 766 IDirectSoundBuffer_Release(secondary); 767 secondary = NULL; 768 769 bufdesc.lpwfxFormat=(WAVEFORMATEX*)&wfxe; 770 wfxe.Format = wfx; 771 wfxe.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; 772 wfxe.SubFormat = (format_tags[tag] == WAVE_FORMAT_PCM ? KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT); 773 wfxe.Format.cbSize = 1; 774 wfxe.Samples.wValidBitsPerSample = wfx.wBitsPerSample; 775 wfxe.dwChannelMask = (wfx.nChannels == 1 ? KSAUDIO_SPEAKER_MONO : KSAUDIO_SPEAKER_STEREO); 776 777 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 778 ok((rc==DSERR_INVALIDPARAM || rc==DSERR_INVALIDCALL /* 2003 */) && !secondary, 779 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", 780 rc, secondary); 781 if (secondary) 782 { 783 IDirectSoundBuffer_Release(secondary); 784 secondary=NULL; 785 } 786 787 wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx) + 1; 788 789 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 790 ok(((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL || rc==DSERR_INVALIDPARAM) 791 && !secondary) 792 || rc==DS_OK, /* 2003 / 2008 */ 793 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", 794 rc, secondary); 795 if (secondary) 796 { 797 IDirectSoundBuffer_Release(secondary); 798 secondary=NULL; 799 } 800 801 wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx); 802 wfxe.SubFormat = GUID_NULL; 803 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 804 ok((rc==DSERR_INVALIDPARAM || rc==DSERR_INVALIDCALL) && !secondary, 805 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", 806 rc, secondary); 807 if (secondary) 808 { 809 IDirectSoundBuffer_Release(secondary); 810 secondary=NULL; 811 } 812 wfxe.SubFormat = (format_tags[tag] == WAVE_FORMAT_PCM ? KSDATAFORMAT_SUBTYPE_PCM : KSDATAFORMAT_SUBTYPE_IEEE_FLOAT); 813 814 ++wfxe.Samples.wValidBitsPerSample; 815 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 816 ok(rc==DSERR_INVALIDPARAM && !secondary, 817 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", 818 rc, secondary); 819 if (secondary) 820 { 821 IDirectSoundBuffer_Release(secondary); 822 secondary=NULL; 823 } 824 --wfxe.Samples.wValidBitsPerSample; 825 826 wfxe.Samples.wValidBitsPerSample = 0; 827 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 828 ok(rc==DS_OK && secondary, 829 "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", 830 rc, secondary); 831 if (secondary) 832 { 833 IDirectSoundBuffer_Release(secondary); 834 secondary=NULL; 835 } 836 wfxe.Samples.wValidBitsPerSample = wfxe.Format.wBitsPerSample; 837 838 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 839 ok(rc==DS_OK && secondary!=NULL, 840 "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc); 841 842 no_wfe: 843 if (rc==DS_OK && secondary!=NULL) { 844 if (winetest_interactive) { 845 trace(" Testing a secondary buffer at %dx%dx%d (fmt=%d) " 846 "with a primary buffer at %dx%dx%d\n", 847 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,format_tags[tag], 848 wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels); 849 } 850 test_buffer(dso,&secondary,0,FALSE,0,FALSE,0, 851 winetest_interactive,1.0,0,NULL,0,0,FALSE,0); 852 853 ref=IDirectSoundBuffer_Release(secondary); 854 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " 855 "should have 0\n",ref); 856 } 857 } 858 } 859 EXIT1: 860 ref=IDirectSoundBuffer_Release(primary); 861 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 862 "should have 0\n",ref); 863 } 864 865 /* Set the CooperativeLevel back to normal */ 866 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 867 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 868 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 869 870 EXIT: 871 ref=IDirectSound_Release(dso); 872 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 873 if (ref!=0) 874 return DSERR_GENERIC; 875 876 return rc; 877 } 878 879 static HRESULT test_block_align(LPGUID lpGuid) 880 { 881 HRESULT rc; 882 LPDIRECTSOUND dso=NULL; 883 LPDIRECTSOUNDBUFFER secondary=NULL; 884 DSBUFFERDESC bufdesc; 885 DSBCAPS dsbcaps; 886 WAVEFORMATEX wfx; 887 DWORD pos, pos2; 888 int ref; 889 890 /* Create the DirectSound object */ 891 rc=pDirectSoundCreate(lpGuid,&dso,NULL); 892 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, 893 "DirectSoundCreate() failed: %08x\n",rc); 894 if (rc!=DS_OK) 895 return rc; 896 897 init_format(&wfx,WAVE_FORMAT_PCM,11025,16,2); 898 ZeroMemory(&bufdesc, sizeof(bufdesc)); 899 bufdesc.dwSize=sizeof(bufdesc); 900 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; 901 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec + 1; 902 bufdesc.lpwfxFormat=&wfx; 903 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 904 ok(rc == DS_OK || broken(rc == DSERR_CONTROLUNAVAIL), /* vmware drivers on w2k */ 905 "IDirectSound_CreateSoundBuffer() should have returned DS_OK, returned: %08x\n", rc); 906 907 if (rc==DS_OK && secondary!=NULL) { 908 ZeroMemory(&dsbcaps, sizeof(dsbcaps)); 909 dsbcaps.dwSize = sizeof(dsbcaps); 910 rc=IDirectSoundBuffer_GetCaps(secondary,&dsbcaps); 911 ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() should have returned DS_OK, " 912 "returned: %08x\n", rc); 913 if (rc==DS_OK && wfx.nBlockAlign > 1) 914 { 915 ok(dsbcaps.dwBufferBytes==(wfx.nAvgBytesPerSec + wfx.nBlockAlign), 916 "Buffer size not a multiple of nBlockAlign: requested %d, " 917 "got %d, should be %d\n", bufdesc.dwBufferBytes, 918 dsbcaps.dwBufferBytes, wfx.nAvgBytesPerSec + wfx.nBlockAlign); 919 920 rc = IDirectSoundBuffer_SetCurrentPosition(secondary, 0); 921 ok(rc == DS_OK, "Could not set position to 0: %08x\n", rc); 922 rc = IDirectSoundBuffer_GetCurrentPosition(secondary, &pos, NULL); 923 ok(rc == DS_OK, "Could not get position: %08x\n", rc); 924 rc = IDirectSoundBuffer_SetCurrentPosition(secondary, 1); 925 ok(rc == DS_OK, "Could not set position to 1: %08x\n", rc); 926 rc = IDirectSoundBuffer_GetCurrentPosition(secondary, &pos2, NULL); 927 ok(rc == DS_OK, "Could not get new position: %08x\n", rc); 928 ok(pos == pos2, "Positions not the same! Old position: %d, new position: %d\n", pos, pos2); 929 } 930 ref=IDirectSoundBuffer_Release(secondary); 931 ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d references, " 932 "should have 0\n",ref); 933 } 934 935 ref=IDirectSound_Release(dso); 936 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 937 if (ref!=0) 938 return DSERR_GENERIC; 939 940 return rc; 941 } 942 943 static struct fmt { 944 int bits; 945 int channels; 946 } fmts[] = { { 8, 1 }, { 8, 2 }, { 16, 1 }, {16, 2 } }; 947 948 static HRESULT test_frequency(LPGUID lpGuid) 949 { 950 HRESULT rc; 951 LPDIRECTSOUND dso=NULL; 952 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL; 953 DSBUFFERDESC bufdesc; 954 DSCAPS dscaps; 955 WAVEFORMATEX wfx, wfx1; 956 DWORD f, r; 957 int ref; 958 int rates[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 959 48000, 96000 }; 960 961 /* Create the DirectSound object */ 962 rc=pDirectSoundCreate(lpGuid,&dso,NULL); 963 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, 964 "DirectSoundCreate() failed: %08x\n",rc); 965 if (rc!=DS_OK) 966 return rc; 967 968 /* Get the device capabilities */ 969 ZeroMemory(&dscaps, sizeof(dscaps)); 970 dscaps.dwSize=sizeof(dscaps); 971 rc=IDirectSound_GetCaps(dso,&dscaps); 972 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %08x\n",rc); 973 if (rc!=DS_OK) 974 goto EXIT; 975 976 /* We must call SetCooperativeLevel before creating primary buffer */ 977 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 978 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 979 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 980 if (rc!=DS_OK) 981 goto EXIT; 982 983 ZeroMemory(&bufdesc, sizeof(bufdesc)); 984 bufdesc.dwSize=sizeof(bufdesc); 985 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; 986 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 987 ok(rc==DS_OK && primary!=NULL, 988 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer %08x\n",rc); 989 990 if (rc==DS_OK && primary!=NULL) { 991 rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL); 992 ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc); 993 if (rc!=DS_OK) 994 goto EXIT1; 995 996 for (f=0;f<sizeof(fmts)/sizeof(fmts[0]);f++) { 997 for (r=0;r<sizeof(rates)/sizeof(rates[0]);r++) { 998 init_format(&wfx,WAVE_FORMAT_PCM,11025,fmts[f].bits, 999 fmts[f].channels); 1000 secondary=NULL; 1001 ZeroMemory(&bufdesc, sizeof(bufdesc)); 1002 bufdesc.dwSize=sizeof(bufdesc); 1003 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRLFREQUENCY; 1004 bufdesc.dwBufferBytes=align((wfx.nAvgBytesPerSec*rates[r]/11025)* 1005 BUFFER_LEN/1000,wfx.nBlockAlign); 1006 bufdesc.lpwfxFormat=&wfx; 1007 if (winetest_interactive) { 1008 trace(" Testing a secondary buffer at %dx%dx%d " 1009 "with a primary buffer at %dx%dx%d\n", 1010 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels, 1011 wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels); 1012 } 1013 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 1014 ok((rc==DS_OK && secondary!=NULL) || broken(rc == DSERR_CONTROLUNAVAIL), /* vmware drivers on w2k */ 1015 "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc); 1016 1017 if (rc==DS_OK && secondary!=NULL) { 1018 test_buffer(dso,&secondary,0,FALSE,0,FALSE,0, 1019 winetest_interactive,1.0,0,NULL,0,0,TRUE,rates[r]); 1020 1021 ref=IDirectSoundBuffer_Release(secondary); 1022 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " 1023 "should have 0\n",ref); 1024 } 1025 } 1026 } 1027 EXIT1: 1028 ref=IDirectSoundBuffer_Release(primary); 1029 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 1030 "should have 0\n",ref); 1031 } 1032 1033 /* Set the CooperativeLevel back to normal */ 1034 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 1035 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 1036 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 1037 1038 EXIT: 1039 ref=IDirectSound_Release(dso); 1040 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 1041 if (ref!=0) 1042 return DSERR_GENERIC; 1043 1044 return rc; 1045 } 1046 1047 static HRESULT test_notify(LPDIRECTSOUNDBUFFER dsb, 1048 DWORD count, LPHANDLE event, 1049 DWORD expected) 1050 { 1051 HRESULT rc; 1052 DWORD ret; 1053 1054 rc=IDirectSoundBuffer_SetCurrentPosition(dsb,0); 1055 ok(rc==DS_OK, 1056 "IDirectSoundBuffer_SetCurrentPosition failed %08x\n",rc); 1057 if(rc!=DS_OK) 1058 return rc; 1059 1060 rc=IDirectSoundBuffer_Play(dsb,0,0,0); 1061 ok(rc==DS_OK,"IDirectSoundBuffer_Play failed %08x\n",rc); 1062 if(rc!=DS_OK) 1063 return rc; 1064 1065 rc=IDirectSoundBuffer_Stop(dsb); 1066 ok(rc==DS_OK,"IDirectSoundBuffer_Stop failed %08x\n",rc); 1067 if(rc!=DS_OK) 1068 return rc; 1069 1070 ret=WaitForMultipleObjects(count,event,FALSE,0); 1071 ok(ret==expected,"expected %d. got %d\n",expected,ret); 1072 return rc; 1073 } 1074 1075 static HRESULT test_duplicate(LPGUID lpGuid) 1076 { 1077 HRESULT rc; 1078 LPDIRECTSOUND dso=NULL; 1079 LPDIRECTSOUNDBUFFER primary=NULL; 1080 DSBUFFERDESC bufdesc; 1081 int ref; 1082 1083 /* Create the DirectSound object */ 1084 rc=pDirectSoundCreate(lpGuid,&dso,NULL); 1085 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, 1086 "DirectSoundCreate() failed: %08x\n",rc); 1087 if (rc!=DS_OK) 1088 return rc; 1089 1090 /* We must call SetCooperativeLevel before creating primary buffer */ 1091 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 1092 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 1093 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 1094 if (rc!=DS_OK) 1095 goto EXIT; 1096 1097 ZeroMemory(&bufdesc, sizeof(bufdesc)); 1098 bufdesc.dwSize=sizeof(bufdesc); 1099 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; 1100 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 1101 ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() failed " 1102 "to create a primary buffer %08x\n",rc); 1103 1104 if (rc==DS_OK && primary!=NULL) { 1105 LPDIRECTSOUNDBUFFER original=NULL; 1106 WAVEFORMATEX wfx; 1107 1108 init_format(&wfx,WAVE_FORMAT_PCM,22050,16,1); 1109 ZeroMemory(&bufdesc, sizeof(bufdesc)); 1110 bufdesc.dwSize=sizeof(bufdesc); 1111 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRLPOSITIONNOTIFY; 1112 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec/100; /* very short buffer */ 1113 bufdesc.lpwfxFormat=&wfx; 1114 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&original,NULL); 1115 ok(rc==DS_OK && original!=NULL, 1116 "IDirectSound_CreateSoundBuffer() failed to create a original " 1117 "buffer %08x\n",rc); 1118 if (rc==DS_OK && original!=NULL) { 1119 LPDIRECTSOUNDBUFFER duplicated=NULL; 1120 LPDIRECTSOUNDNOTIFY notify=NULL; 1121 HANDLE event[2]; 1122 LPVOID buf=NULL; 1123 DWORD bufsize; 1124 int i; 1125 1126 /* Prepare notify events */ 1127 for (i=0;i<sizeof(event)/sizeof(event[0]);i++) { 1128 event[i] = CreateEvent(NULL,FALSE,FALSE,NULL); 1129 } 1130 1131 /* Make silent buffer */ 1132 rc=IDirectSoundBuffer_Lock(original,0,0,&buf,&bufsize, 1133 NULL,NULL,DSBLOCK_ENTIREBUFFER); 1134 ok(rc==DS_OK && buf!=NULL, 1135 "IDirectSoundBuffer_Lock failed to lock the buffer %08x\n",rc); 1136 if (rc==DS_OK && buf!=NULL) { 1137 ZeroMemory(buf,bufsize); 1138 rc=IDirectSoundBuffer_Unlock(original,buf,bufsize, 1139 NULL,0); 1140 ok(rc==DS_OK,"IDirectSoundBuffer_Unlock failed to unlock " 1141 "%08x\n",rc); 1142 } 1143 1144 rc=IDirectSoundBuffer_QueryInterface(original, 1145 &IID_IDirectSoundNotify, 1146 (void**)¬ify); 1147 ok(rc==DS_OK && notify!=NULL, 1148 "IDirectSoundBuffer_QueryInterface() failed to create a " 1149 "notification %08x\n",rc); 1150 if (rc==DS_OK && notify!=NULL) { 1151 DSBPOSITIONNOTIFY dsbpn; 1152 LPDIRECTSOUNDNOTIFY dup_notify=NULL; 1153 1154 dsbpn.dwOffset=DSBPN_OFFSETSTOP; 1155 dsbpn.hEventNotify=event[0]; 1156 rc=IDirectSoundNotify_SetNotificationPositions(notify, 1157 1,&dsbpn); 1158 ok(rc==DS_OK,"IDirectSoundNotify_SetNotificationPositions " 1159 "failed %08x\n",rc); 1160 1161 rc=IDirectSound_DuplicateSoundBuffer(dso,original,&duplicated); 1162 ok(rc==DS_OK && duplicated!=NULL, 1163 "IDirectSound_DuplicateSoundBuffer failed %08x\n",rc); 1164 1165 trace("testing duplicated buffer without notifications.\n"); 1166 test_notify(duplicated,sizeof(event)/sizeof(event[0]), 1167 event,WAIT_TIMEOUT); 1168 1169 rc=IDirectSoundBuffer_QueryInterface(duplicated, 1170 &IID_IDirectSoundNotify, 1171 (void**)&dup_notify); 1172 ok(rc==DS_OK&&dup_notify!=NULL, 1173 "IDirectSoundBuffer_QueryInterface() failed to create a " 1174 "notification %08x\n",rc); 1175 if(rc==DS_OK&&dup_notify!=NULL) { 1176 dsbpn.dwOffset=DSBPN_OFFSETSTOP; 1177 dsbpn.hEventNotify=event[1]; 1178 rc=IDirectSoundNotify_SetNotificationPositions(dup_notify, 1179 1,&dsbpn); 1180 ok(rc==DS_OK,"IDirectSoundNotify_SetNotificationPositions " 1181 "failed %08x\n",rc); 1182 1183 trace("testing duplicated buffer with a notification.\n"); 1184 test_notify(duplicated,sizeof(event)/sizeof(event[0]), 1185 event,WAIT_OBJECT_0+1); 1186 1187 ref=IDirectSoundNotify_Release(dup_notify); 1188 ok(ref==0,"IDirectSoundNotify_Release() has %d references, " 1189 "should have 0\n",ref); 1190 } 1191 ref=IDirectSoundNotify_Release(notify); 1192 ok(ref==0,"IDirectSoundNotify_Release() has %d references, " 1193 "should have 0\n",ref); 1194 1195 trace("testing original buffer with a notification.\n"); 1196 test_notify(original,sizeof(event)/sizeof(event[0]), 1197 event,WAIT_OBJECT_0); 1198 1199 ref=IDirectSoundBuffer_Release(duplicated); 1200 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " 1201 "should have 0\n",ref); 1202 } 1203 ref=IDirectSoundBuffer_Release(original); 1204 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " 1205 "should have 0\n",ref); 1206 } 1207 ref=IDirectSoundBuffer_Release(primary); 1208 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " 1209 "should have 0\n",ref); 1210 } 1211 1212 /* Set the CooperativeLevel back to normal */ 1213 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 1214 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 1215 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 1216 1217 EXIT: 1218 ref=IDirectSound_Release(dso); 1219 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 1220 if (ref!=0) 1221 return DSERR_GENERIC; 1222 1223 return rc; 1224 } 1225 1226 static HRESULT test_invalid_fmts(LPGUID lpGuid) 1227 { 1228 HRESULT rc; 1229 LPDIRECTSOUND dso=NULL; 1230 LPDIRECTSOUNDBUFFER primary=NULL; 1231 DSBUFFERDESC bufdesc; 1232 1233 /* Create the DirectSound object */ 1234 rc=pDirectSoundCreate(lpGuid,&dso,NULL); 1235 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, 1236 "DirectSoundCreate() failed: %08x\n",rc); 1237 if (rc!=DS_OK) 1238 return rc; 1239 1240 /* We must call SetCooperativeLevel before creating primary buffer */ 1241 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 1242 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 1243 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); 1244 if (rc!=DS_OK){ 1245 IDirectSound_Release(dso); 1246 return rc; 1247 } 1248 1249 ZeroMemory(&bufdesc, sizeof(bufdesc)); 1250 bufdesc.dwSize=sizeof(bufdesc); 1251 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; 1252 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 1253 ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() failed " 1254 "to create a primary buffer %08x\n",rc); 1255 1256 if (rc==DS_OK && primary!=NULL) { 1257 WAVEFORMATEX wfx; 1258 WAVEFORMATEXTENSIBLE fmtex; 1259 1260 wfx.wFormatTag = WAVE_FORMAT_PCM; 1261 wfx.nChannels = 0; 1262 wfx.nSamplesPerSec = 44100; 1263 wfx.wBitsPerSample = 16; 1264 wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; 1265 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; 1266 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1267 ok(rc == E_INVALIDARG, "SetFormat: %08x\n", rc); 1268 1269 wfx.nChannels = 2; 1270 wfx.nSamplesPerSec = 44100; 1271 wfx.wBitsPerSample = 0; 1272 wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; 1273 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; 1274 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1275 ok(rc == E_INVALIDARG, "SetFormat: %08x\n", rc); 1276 1277 wfx.nChannels = 2; 1278 wfx.nSamplesPerSec = 44100; 1279 wfx.wBitsPerSample = 2; 1280 wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; 1281 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; 1282 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1283 ok(rc == E_INVALIDARG, "SetFormat: %08x\n", rc); 1284 1285 wfx.nChannels = 2; 1286 wfx.nSamplesPerSec = 44100; 1287 wfx.wBitsPerSample = 12; 1288 wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; 1289 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; 1290 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1291 ok(rc == E_INVALIDARG, "SetFormat: %08x\n", rc); 1292 1293 wfx.nChannels = 2; 1294 wfx.nSamplesPerSec = 0; 1295 wfx.wBitsPerSample = 16; 1296 wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; 1297 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; 1298 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1299 ok(rc == E_INVALIDARG, "SetFormat: %08x\n", rc); 1300 1301 wfx.nChannels = 2; 1302 wfx.nSamplesPerSec = 44100; 1303 wfx.wBitsPerSample = 16; 1304 wfx.nBlockAlign = 0; 1305 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; 1306 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1307 ok(rc == E_INVALIDARG, "SetFormat: %08x\n", rc); 1308 1309 wfx.nChannels = 2; 1310 wfx.nSamplesPerSec = 44100; 1311 wfx.wBitsPerSample = 16; 1312 wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; 1313 wfx.nAvgBytesPerSec = 0; 1314 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1315 ok(rc == E_INVALIDARG, "SetFormat: %08x\n", rc); 1316 1317 wfx.nChannels = 2; 1318 wfx.nSamplesPerSec = 44100; 1319 wfx.wBitsPerSample = 16; 1320 wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample / 8) - 1; 1321 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; 1322 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1323 ok(rc == E_INVALIDARG, "SetFormat: %08x\n", rc); 1324 1325 wfx.nChannels = 2; 1326 wfx.nSamplesPerSec = 44100; 1327 wfx.wBitsPerSample = 16; 1328 wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample / 8) + 1; 1329 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; 1330 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1331 ok(rc == E_INVALIDARG, "SetFormat: %08x\n", rc); 1332 1333 wfx.nChannels = 2; 1334 wfx.nSamplesPerSec = 44100; 1335 wfx.wBitsPerSample = 16; 1336 wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; 1337 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign + 1; 1338 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1339 ok(rc == S_OK, "SetFormat: %08x\n", rc); 1340 1341 rc = IDirectSoundBuffer_GetFormat(primary, &wfx, sizeof(wfx), NULL); 1342 ok(rc == S_OK, "GetFormat: %08x\n", rc); 1343 ok(wfx.wFormatTag == WAVE_FORMAT_PCM, "format: 0x%x\n", wfx.wFormatTag); 1344 ok(wfx.nChannels == 2, "channels: %u\n", wfx.nChannels); 1345 ok(wfx.nSamplesPerSec == 44100, "rate: %u\n", wfx.nSamplesPerSec); 1346 ok(wfx.wBitsPerSample == 16, "bps: %u\n", wfx.wBitsPerSample); 1347 ok(wfx.nBlockAlign == 4, "blockalign: %u\n", wfx.nBlockAlign); 1348 ok(wfx.nAvgBytesPerSec == 44100 * 4 + 1, "avgbytes: %u\n", wfx.nAvgBytesPerSec); 1349 1350 wfx.nChannels = 2; 1351 wfx.nSamplesPerSec = 44100; 1352 wfx.wBitsPerSample = 16; 1353 wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; 1354 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign - 1; 1355 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1356 ok(rc == S_OK, "SetFormat: %08x\n", rc); 1357 1358 rc = IDirectSoundBuffer_GetFormat(primary, &wfx, sizeof(wfx), NULL); 1359 ok(rc == S_OK, "GetFormat: %08x\n", rc); 1360 ok(wfx.wFormatTag == WAVE_FORMAT_PCM, "format: 0x%x\n", wfx.wFormatTag); 1361 ok(wfx.nChannels == 2, "channels: %u\n", wfx.nChannels); 1362 ok(wfx.nSamplesPerSec == 44100, "rate: %u\n", wfx.nSamplesPerSec); 1363 ok(wfx.wBitsPerSample == 16, "bps: %u\n", wfx.wBitsPerSample); 1364 ok(wfx.nBlockAlign == 4, "blockalign: %u\n", wfx.nBlockAlign); 1365 ok(wfx.nAvgBytesPerSec == 44100 * 4 - 1, "avgbytes: %u\n", wfx.nAvgBytesPerSec); 1366 1367 wfx.nChannels = 2; 1368 wfx.nSamplesPerSec = 44100; 1369 wfx.wBitsPerSample = 16; 1370 wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; 1371 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign + 1; 1372 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1373 ok(rc == S_OK, "SetFormat: %08x\n", rc); 1374 1375 rc = IDirectSoundBuffer_GetFormat(primary, &wfx, sizeof(wfx), NULL); 1376 ok(rc == S_OK, "GetFormat: %08x\n", rc); 1377 ok(wfx.wFormatTag == WAVE_FORMAT_PCM, "format: 0x%x\n", wfx.wFormatTag); 1378 ok(wfx.nChannels == 2, "channels: %u\n", wfx.nChannels); 1379 ok(wfx.nSamplesPerSec == 44100, "rate: %u\n", wfx.nSamplesPerSec); 1380 ok(wfx.wBitsPerSample == 16, "bps: %u\n", wfx.wBitsPerSample); 1381 ok(wfx.nBlockAlign == 4, "blockalign: %u\n", wfx.nBlockAlign); 1382 ok(wfx.nAvgBytesPerSec == 44100 * 4 + 1, "avgbytes: %u\n", wfx.nAvgBytesPerSec); 1383 1384 wfx.wFormatTag = WAVE_FORMAT_ALAW; 1385 wfx.nChannels = 2; 1386 wfx.nSamplesPerSec = 44100; 1387 wfx.wBitsPerSample = 16; 1388 wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8; 1389 wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; 1390 rc = IDirectSoundBuffer_SetFormat(primary, &wfx); 1391 ok(rc == S_OK, "SetFormat: %08x\n", rc); 1392 1393 rc = IDirectSoundBuffer_GetFormat(primary, &wfx, sizeof(wfx), NULL); 1394 ok(rc == S_OK, "GetFormat: %08x\n", rc); 1395 ok(wfx.wFormatTag == WAVE_FORMAT_ALAW, "format: 0x%x\n", wfx.wFormatTag); 1396 ok(wfx.nChannels == 2, "channels: %u\n", wfx.nChannels); 1397 ok(wfx.nSamplesPerSec == 44100, "rate: %u\n", wfx.nSamplesPerSec); 1398 ok(wfx.wBitsPerSample == 16, "bps: %u\n", wfx.wBitsPerSample); 1399 ok(wfx.nBlockAlign == 4, "blockalign: %u\n", wfx.nBlockAlign); 1400 ok(wfx.nAvgBytesPerSec == 44100 * 4, "avgbytes: %u\n", wfx.nAvgBytesPerSec); 1401 1402 if(!gotdx8){ 1403 win_skip("Not doing the WAVE_FORMAT_EXTENSIBLE tests\n"); 1404 goto done; 1405 } 1406 1407 fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); 1408 fmtex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; 1409 fmtex.Format.nChannels = 2; 1410 fmtex.Format.nSamplesPerSec = 44100; 1411 fmtex.Format.wBitsPerSample = 16; 1412 fmtex.Format.nBlockAlign = fmtex.Format.nChannels * fmtex.Format.wBitsPerSample / 8; 1413 fmtex.Format.nAvgBytesPerSec = fmtex.Format.nSamplesPerSec * fmtex.Format.nBlockAlign; 1414 fmtex.Samples.wValidBitsPerSample = 0; 1415 fmtex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; 1416 fmtex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 1417 rc = IDirectSoundBuffer_SetFormat(primary, (WAVEFORMATEX*)&fmtex); 1418 ok(rc == S_OK, "SetFormat: %08x\n", rc); 1419 1420 rc = IDirectSoundBuffer_GetFormat(primary, (WAVEFORMATEX*)&fmtex, sizeof(fmtex), NULL); 1421 ok(rc == S_OK, "GetFormat: %08x\n", rc); 1422 ok(fmtex.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "format: 0x%x\n", fmtex.Format.wFormatTag); 1423 ok(fmtex.Format.nChannels == 2, "channels: %u\n", fmtex.Format.nChannels); 1424 ok(fmtex.Format.nSamplesPerSec == 44100, "rate: %u\n", fmtex.Format.nSamplesPerSec); 1425 ok(fmtex.Format.wBitsPerSample == 16, "bps: %u\n", fmtex.Format.wBitsPerSample); 1426 ok(fmtex.Format.nBlockAlign == 4, "blockalign: %u\n", fmtex.Format.nBlockAlign); 1427 ok(fmtex.Format.nAvgBytesPerSec == 44100 * 4, "avgbytes: %u\n", fmtex.Format.nAvgBytesPerSec); 1428 ok(fmtex.Samples.wValidBitsPerSample == 0 || /* <= XP */ 1429 fmtex.Samples.wValidBitsPerSample == 16, /* >= Vista */ 1430 "validbits: %u\n", fmtex.Samples.wValidBitsPerSample); 1431 ok(IsEqualGUID(&fmtex.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM), "subtype incorrect\n"); 1432 1433 fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); 1434 fmtex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; 1435 fmtex.Format.nChannels = 2; 1436 fmtex.Format.nSamplesPerSec = 44100; 1437 fmtex.Format.wBitsPerSample = 24; 1438 fmtex.Format.nBlockAlign = fmtex.Format.nChannels * fmtex.Format.wBitsPerSample / 8; 1439 fmtex.Format.nAvgBytesPerSec = fmtex.Format.nSamplesPerSec * fmtex.Format.nBlockAlign; 1440 fmtex.Samples.wValidBitsPerSample = 20; 1441 fmtex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; 1442 fmtex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 1443 rc = IDirectSoundBuffer_SetFormat(primary, (WAVEFORMATEX*)&fmtex); 1444 ok(rc == S_OK, "SetFormat: %08x\n", rc); 1445 1446 rc = IDirectSoundBuffer_GetFormat(primary, (WAVEFORMATEX*)&fmtex, sizeof(fmtex), NULL); 1447 ok(rc == S_OK, "GetFormat: %08x\n", rc); 1448 ok(fmtex.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "format: 0x%x\n", fmtex.Format.wFormatTag); 1449 ok(fmtex.Format.nChannels == 2, "channels: %u\n", fmtex.Format.nChannels); 1450 ok(fmtex.Format.nSamplesPerSec == 44100, "rate: %u\n", fmtex.Format.nSamplesPerSec); 1451 ok(fmtex.Format.wBitsPerSample == 24, "bps: %u\n", fmtex.Format.wBitsPerSample); 1452 ok(fmtex.Format.nBlockAlign == 6, "blockalign: %u\n", fmtex.Format.nBlockAlign); 1453 ok(fmtex.Format.nAvgBytesPerSec == 44100 * 6, "avgbytes: %u\n", fmtex.Format.nAvgBytesPerSec); 1454 ok(fmtex.Samples.wValidBitsPerSample == 20, "validbits: %u\n", fmtex.Samples.wValidBitsPerSample); 1455 ok(IsEqualGUID(&fmtex.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM), "subtype incorrect\n"); 1456 1457 fmtex.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); 1458 fmtex.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; 1459 fmtex.Format.nChannels = 2; 1460 fmtex.Format.nSamplesPerSec = 44100; 1461 fmtex.Format.wBitsPerSample = 24; 1462 fmtex.Format.nBlockAlign = fmtex.Format.nChannels * fmtex.Format.wBitsPerSample / 8; 1463 fmtex.Format.nAvgBytesPerSec = fmtex.Format.nSamplesPerSec * fmtex.Format.nBlockAlign; 1464 fmtex.Samples.wValidBitsPerSample = 32; 1465 fmtex.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT; 1466 fmtex.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 1467 rc = IDirectSoundBuffer_SetFormat(primary, (WAVEFORMATEX*)&fmtex); 1468 ok(rc == E_INVALIDARG, "SetFormat: %08x\n", rc); 1469 1470 IDirectSoundBuffer_Release(primary); 1471 } 1472 1473 done: 1474 IDirectSound_Release(dso); 1475 1476 return S_OK; 1477 } 1478 1479 static unsigned int number; 1480 1481 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription, 1482 LPCSTR lpcstrModule, LPVOID lpContext) 1483 { 1484 HRESULT rc; 1485 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule); 1486 1487 /* Don't test the primary device */ 1488 if (!number++) 1489 { 1490 ok (!lpcstrModule[0], "lpcstrModule(%s) != NULL\n", lpcstrModule); 1491 return 1; 1492 } 1493 1494 rc = test_dsound(lpGuid); 1495 if (rc == DSERR_NODRIVER) 1496 trace(" No Driver\n"); 1497 else if (rc == DSERR_ALLOCATED) 1498 trace(" Already In Use\n"); 1499 else if (rc == E_FAIL) 1500 trace(" No Device\n"); 1501 else { 1502 test_block_align(lpGuid); 1503 test_primary(lpGuid); 1504 test_primary_secondary(lpGuid); 1505 test_secondary(lpGuid); 1506 test_frequency(lpGuid); 1507 test_duplicate(lpGuid); 1508 test_invalid_fmts(lpGuid); 1509 } 1510 1511 return 1; 1512 } 1513 1514 static void dsound_tests(void) 1515 { 1516 HRESULT rc; 1517 rc=pDirectSoundEnumerateA(&dsenum_callback,NULL); 1518 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %08x\n",rc); 1519 } 1520 1521 static void test_hw_buffers(void) 1522 { 1523 IDirectSound *ds; 1524 IDirectSoundBuffer *primary, *primary2, **secondaries, *secondary; 1525 IDirectSoundBuffer8 *buf8; 1526 DSCAPS caps; 1527 DSBCAPS bufcaps; 1528 DSBUFFERDESC bufdesc; 1529 WAVEFORMATEX fmt; 1530 UINT i; 1531 HRESULT hr; 1532 1533 hr = pDirectSoundCreate(NULL, &ds, NULL); 1534 ok(hr == S_OK || hr == DSERR_NODRIVER || hr == DSERR_ALLOCATED || hr == E_FAIL, 1535 "DirectSoundCreate failed: %08x\n", hr); 1536 if(hr != S_OK) 1537 return; 1538 1539 caps.dwSize = sizeof(caps); 1540 1541 hr = IDirectSound_GetCaps(ds, &caps); 1542 ok(hr == S_OK, "GetCaps failed: %08x\n", hr); 1543 1544 ok(caps.dwPrimaryBuffers == 1, "Got wrong number of primary buffers: %u\n", 1545 caps.dwPrimaryBuffers); 1546 1547 /* DSBCAPS_LOC* is ignored for primary buffers */ 1548 bufdesc.dwSize = sizeof(bufdesc); 1549 bufdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCHARDWARE | 1550 DSBCAPS_PRIMARYBUFFER; 1551 bufdesc.dwBufferBytes = 0; 1552 bufdesc.dwReserved = 0; 1553 bufdesc.lpwfxFormat = NULL; 1554 bufdesc.guid3DAlgorithm = GUID_NULL; 1555 1556 hr = IDirectSound_CreateSoundBuffer(ds, &bufdesc, &primary, NULL); 1557 ok(hr == S_OK, "CreateSoundBuffer failed: %08x\n", hr); 1558 if(hr != S_OK){ 1559 IDirectSound_Release(ds); 1560 return; 1561 } 1562 1563 bufdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCSOFTWARE | 1564 DSBCAPS_PRIMARYBUFFER; 1565 1566 hr = IDirectSound_CreateSoundBuffer(ds, &bufdesc, &primary2, NULL); 1567 ok(hr == S_OK, "CreateSoundBuffer failed: %08x\n", hr); 1568 ok(primary == primary2, "Got different primary buffers: %p, %p\n", primary, primary2); 1569 if(hr == S_OK) 1570 IDirectSoundBuffer_Release(primary2); 1571 1572 buf8 = (IDirectSoundBuffer8 *)0xDEADBEEF; 1573 hr = IDirectSoundBuffer_QueryInterface(primary, &IID_IDirectSoundBuffer8, 1574 (void**)&buf8); 1575 ok(hr == E_NOINTERFACE, "QueryInterface gave wrong failure: %08x\n", hr); 1576 ok(buf8 == NULL, "Pointer didn't get set to NULL\n"); 1577 1578 fmt.wFormatTag = WAVE_FORMAT_PCM; 1579 fmt.nChannels = 2; 1580 fmt.nSamplesPerSec = 48000; 1581 fmt.wBitsPerSample = 16; 1582 fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; 1583 fmt.nAvgBytesPerSec = fmt.nBlockAlign * fmt.nSamplesPerSec; 1584 fmt.cbSize = 0; 1585 1586 bufdesc.lpwfxFormat = &fmt; 1587 bufdesc.dwBufferBytes = fmt.nSamplesPerSec * fmt.nBlockAlign / 10; 1588 bufdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_LOCHARDWARE | 1589 DSBCAPS_CTRLVOLUME; 1590 1591 secondaries = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1592 sizeof(IDirectSoundBuffer *) * caps.dwMaxHwMixingAllBuffers); 1593 1594 /* try to fill all of the hw buffers */ 1595 trace("dwMaxHwMixingAllBuffers: %u\n", caps.dwMaxHwMixingAllBuffers); 1596 trace("dwMaxHwMixingStaticBuffers: %u\n", caps.dwMaxHwMixingStaticBuffers); 1597 trace("dwMaxHwMixingStreamingBuffers: %u\n", caps.dwMaxHwMixingStreamingBuffers); 1598 for(i = 0; i < caps.dwMaxHwMixingAllBuffers; ++i){ 1599 hr = IDirectSound_CreateSoundBuffer(ds, &bufdesc, &secondaries[i], NULL); 1600 ok(hr == S_OK || hr == E_NOTIMPL || broken(hr == DSERR_CONTROLUNAVAIL) || broken(hr == E_FAIL), 1601 "CreateSoundBuffer(%u) failed: %08x\n", i, hr); 1602 if(hr != S_OK) 1603 break; 1604 1605 bufcaps.dwSize = sizeof(bufcaps); 1606 hr = IDirectSoundBuffer_GetCaps(secondaries[i], &bufcaps); 1607 ok(hr == S_OK, "GetCaps failed: %08x\n", hr); 1608 ok((bufcaps.dwFlags & DSBCAPS_LOCHARDWARE) != 0, 1609 "Buffer wasn't allocated in hardware, dwFlags: %x\n", bufcaps.dwFlags); 1610 } 1611 1612 /* see if we can create one more */ 1613 hr = IDirectSound_CreateSoundBuffer(ds, &bufdesc, &secondary, NULL); 1614 ok((i == caps.dwMaxHwMixingAllBuffers && hr == DSERR_ALLOCATED) || /* out of hw buffers */ 1615 (caps.dwMaxHwMixingAllBuffers == 0 && hr == DSERR_INVALIDCALL) || /* no hw buffers at all */ 1616 hr == E_NOTIMPL || /* don't support hw buffers */ 1617 broken(hr == DSERR_CONTROLUNAVAIL) || /* vmware winxp, others? */ 1618 broken(hr == E_FAIL) || /* broken AC97 driver */ 1619 broken(hr == S_OK) /* broken driver allows more hw bufs than dscaps claims */, 1620 "CreateSoundBuffer(%u) gave wrong error: %08x\n", i, hr); 1621 if(hr == S_OK) 1622 IDirectSoundBuffer_Release(secondary); 1623 1624 for(i = 0; i < caps.dwMaxHwMixingAllBuffers; ++i) 1625 if(secondaries[i]) 1626 IDirectSoundBuffer_Release(secondaries[i]); 1627 HeapFree(GetProcessHeap(), 0, secondaries); 1628 1629 IDirectSoundBuffer_Release(primary); 1630 IDirectSound_Release(ds); 1631 } 1632 1633 START_TEST(dsound) 1634 { 1635 HMODULE hDsound; 1636 1637 CoInitialize(NULL); 1638 1639 hDsound = LoadLibrary("dsound.dll"); 1640 if (hDsound) 1641 { 1642 BOOL ret; 1643 1644 ret = FreeLibrary(hDsound); 1645 ok( ret, "FreeLibrary(1) returned %d\n", GetLastError()); 1646 } 1647 1648 hDsound = LoadLibrary("dsound.dll"); 1649 if (hDsound) 1650 { 1651 1652 pDirectSoundEnumerateA = (void*)GetProcAddress(hDsound, 1653 "DirectSoundEnumerateA"); 1654 pDirectSoundCreate = (void*)GetProcAddress(hDsound, 1655 "DirectSoundCreate"); 1656 1657 gotdx8 = !!GetProcAddress(hDsound, "DirectSoundCreate8"); 1658 1659 IDirectSound_tests(); 1660 dsound_tests(); 1661 test_hw_buffers(); 1662 1663 FreeLibrary(hDsound); 1664 } 1665 else 1666 win_skip("dsound.dll not found - skipping all tests\n"); 1667 1668 CoUninitialize(); 1669 } 1670