1 /* 2 * Tests the panning and 3D functions of DirectSound 3 * 4 * Part of this test involves playing test tones. But this only makes 5 * sense if someone is going to carefully listen to it, and would only 6 * bother everyone else. 7 * So this is only done if the test is being run in interactive mode. 8 * 9 * Copyright (c) 2002-2004 Francois Gouget 10 * 11 * This library is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public 13 * License as published by the Free Software Foundation; either 14 * version 2.1 of the License, or (at your option) any later version. 15 * 16 * This library is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with this library; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 24 */ 25 26 #include "dsound_test.h" 27 28 static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL; 29 static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL; 30 31 typedef struct { 32 char* wave; 33 DWORD wave_len; 34 35 LPDIRECTSOUNDBUFFER dsbo; 36 LPWAVEFORMATEX wfx; 37 DWORD buffer_size; 38 DWORD written; 39 DWORD played; 40 DWORD offset; 41 } play_state_t; 42 43 static int buffer_refill8(play_state_t* state, DWORD size) 44 { 45 LPVOID ptr1,ptr2; 46 DWORD len1,len2; 47 HRESULT rc; 48 49 if (size>state->wave_len-state->written) 50 size=state->wave_len-state->written; 51 52 rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size, 53 &ptr1,&len1,&ptr2,&len2,0); 54 ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %08x\n", rc); 55 if (rc!=DS_OK) 56 return -1; 57 58 memcpy(ptr1,state->wave+state->written,len1); 59 state->written+=len1; 60 if (ptr2!=NULL) { 61 memcpy(ptr2,state->wave+state->written,len2); 62 state->written+=len2; 63 } 64 state->offset=state->written % state->buffer_size; 65 rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2); 66 ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %08x\n", rc); 67 if (rc!=DS_OK) 68 return -1; 69 return size; 70 } 71 72 static int buffer_silence8(play_state_t* state, DWORD size) 73 { 74 LPVOID ptr1,ptr2; 75 DWORD len1,len2; 76 HRESULT rc; 77 BYTE s; 78 79 rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size, 80 &ptr1,&len1,&ptr2,&len2,0); 81 ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %08x\n", rc); 82 if (rc!=DS_OK) 83 return -1; 84 85 s=(state->wfx->wBitsPerSample==8?0x80:0); 86 memset(ptr1,s,len1); 87 if (ptr2!=NULL) { 88 memset(ptr2,s,len2); 89 } 90 state->offset=(state->offset+size) % state->buffer_size; 91 rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2); 92 ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %08x\n", rc); 93 if (rc!=DS_OK) 94 return -1; 95 return size; 96 } 97 98 static int buffer_service8(play_state_t* state) 99 { 100 DWORD last_play_pos,play_pos,buf_free; 101 HRESULT rc; 102 103 rc=IDirectSoundBuffer_GetCurrentPosition(state->dsbo,&play_pos,NULL); 104 ok(rc==DS_OK,"IDirectSoundBuffer_GetCurrentPosition() failed: %08x\n", rc); 105 if (rc!=DS_OK) { 106 goto STOP; 107 } 108 109 /* Update the amount played */ 110 last_play_pos=state->played % state->buffer_size; 111 if (play_pos<last_play_pos) 112 state->played+=state->buffer_size-last_play_pos+play_pos; 113 else 114 state->played+=play_pos-last_play_pos; 115 116 if (winetest_debug > 1) 117 trace("buf size=%d last_play_pos=%d play_pos=%d played=%d / %d\n", 118 state->buffer_size,last_play_pos,play_pos,state->played, 119 state->wave_len); 120 121 if (state->played>state->wave_len) 122 { 123 /* Everything has been played */ 124 goto STOP; 125 } 126 127 /* Refill the buffer */ 128 if (state->offset<=play_pos) 129 buf_free=play_pos-state->offset; 130 else 131 buf_free=state->buffer_size-state->offset+play_pos; 132 133 if (winetest_debug > 1) 134 trace("offset=%d free=%d written=%d / %d\n", 135 state->offset,buf_free,state->written,state->wave_len); 136 if (buf_free==0) 137 return 1; 138 139 if (state->written<state->wave_len) 140 { 141 int w=buffer_refill8(state,buf_free); 142 if (w==-1) 143 goto STOP; 144 buf_free-=w; 145 if (state->written==state->wave_len && winetest_debug > 1) 146 trace("last sound byte at %d\n", 147 (state->written % state->buffer_size)); 148 } 149 150 if (buf_free>0) { 151 /* Fill with silence */ 152 if (winetest_debug > 1) 153 trace("writing %d bytes of silence\n",buf_free); 154 if (buffer_silence8(state,buf_free)==-1) 155 goto STOP; 156 } 157 return 1; 158 159 STOP: 160 if (winetest_debug > 1) 161 trace("stopping playback\n"); 162 rc=IDirectSoundBuffer_Stop(state->dsbo); 163 ok(rc==DS_OK,"IDirectSoundBuffer_Stop() failed: %08x\n", rc); 164 return 0; 165 } 166 167 void test_buffer8(LPDIRECTSOUND8 dso, LPDIRECTSOUNDBUFFER * dsbo, 168 BOOL is_primary, BOOL set_volume, LONG volume, 169 BOOL set_pan, LONG pan, BOOL play, double duration, 170 BOOL buffer3d, LPDIRECTSOUND3DLISTENER listener, 171 BOOL move_listener, BOOL move_sound) 172 { 173 HRESULT rc; 174 DSBCAPS dsbcaps; 175 WAVEFORMATEX wfx,wfx2; 176 DWORD size,status,freq; 177 BOOL ieee = FALSE; 178 int ref; 179 180 /* DSOUND: Error: Invalid caps pointer */ 181 rc=IDirectSoundBuffer_GetCaps(*dsbo,0); 182 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have " 183 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc); 184 185 ZeroMemory(&dsbcaps, sizeof(dsbcaps)); 186 187 /* DSOUND: Error: Invalid caps pointer */ 188 rc=IDirectSoundBuffer_GetCaps(*dsbo,&dsbcaps); 189 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have " 190 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc); 191 192 dsbcaps.dwSize=sizeof(dsbcaps); 193 rc=IDirectSoundBuffer_GetCaps(*dsbo,&dsbcaps); 194 ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() failed: %08x\n", rc); 195 if (rc==DS_OK && winetest_debug > 1) { 196 trace(" Caps: flags=0x%08x size=%d\n",dsbcaps.dwFlags, 197 dsbcaps.dwBufferBytes); 198 } 199 200 /* Query the format size. */ 201 size=0; 202 rc=IDirectSoundBuffer_GetFormat(*dsbo,NULL,0,&size); 203 ok(rc==DS_OK && size!=0,"IDirectSoundBuffer_GetFormat() should have " 204 "returned the needed size: rc=%08x size=%d\n",rc,size); 205 206 ok(size == sizeof(WAVEFORMATEX) || size == sizeof(WAVEFORMATEXTENSIBLE), 207 "Expected a correct structure size, got %d\n", size); 208 209 if (size == sizeof(WAVEFORMATEX)) { 210 rc=IDirectSoundBuffer_GetFormat(*dsbo,&wfx,size,NULL); 211 ieee = (wfx.wFormatTag == WAVE_FORMAT_IEEE_FLOAT); 212 } else if (size == sizeof(WAVEFORMATEXTENSIBLE)) { 213 WAVEFORMATEXTENSIBLE wfxe; 214 rc=IDirectSoundBuffer_GetFormat(*dsbo,(WAVEFORMATEX*)&wfxe,size,NULL); 215 wfx = wfxe.Format; 216 ieee = IsEqualGUID(&wfxe.SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT); 217 } else 218 return; 219 220 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc); 221 if (rc==DS_OK && winetest_debug > 1) { 222 trace(" Format: %s tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n", 223 is_primary ? "Primary" : "Secondary", 224 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample, 225 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign); 226 } 227 228 /* DSOUND: Error: Invalid frequency buffer */ 229 rc=IDirectSoundBuffer_GetFrequency(*dsbo,0); 230 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetFrequency() should have " 231 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc); 232 233 /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */ 234 rc=IDirectSoundBuffer_GetFrequency(*dsbo,&freq); 235 ok((rc==DS_OK && !is_primary) || (rc==DSERR_CONTROLUNAVAIL&&is_primary) || 236 (rc==DSERR_CONTROLUNAVAIL&&!(dsbcaps.dwFlags&DSBCAPS_CTRLFREQUENCY)), 237 "IDirectSoundBuffer_GetFrequency() failed: %08x\n",rc); 238 if (rc==DS_OK) { 239 ok(freq==wfx.nSamplesPerSec,"The frequency returned by GetFrequency " 240 "%d does not match the format %d\n",freq,wfx.nSamplesPerSec); 241 } 242 243 /* DSOUND: Error: Invalid status pointer */ 244 rc=IDirectSoundBuffer_GetStatus(*dsbo,0); 245 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetStatus() should have " 246 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc); 247 248 rc=IDirectSoundBuffer_GetStatus(*dsbo,&status); 249 ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %08x\n", rc); 250 ok(status==0,"status=0x%x instead of 0\n",status); 251 252 if (is_primary) { 253 DSBCAPS new_dsbcaps; 254 /* We must call SetCooperativeLevel to be allowed to call SetFormat */ 255 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 256 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 257 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_PRIORITY) " 258 "failed: %08x\n",rc); 259 if (rc!=DS_OK) 260 return; 261 262 /* DSOUND: Error: Invalid format pointer */ 263 rc=IDirectSoundBuffer_SetFormat(*dsbo,0); 264 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_SetFormat() should have " 265 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc); 266 267 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2); 268 rc=IDirectSoundBuffer_SetFormat(*dsbo,&wfx2); 269 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat(%s) failed: %08x\n", 270 format_string(&wfx2), rc); 271 272 /* There is no guarantee that SetFormat will actually change the 273 * format to what we asked for. It depends on what the soundcard 274 * supports. So we must re-query the format. 275 */ 276 rc=IDirectSoundBuffer_GetFormat(*dsbo,&wfx,sizeof(wfx),NULL); 277 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc); 278 if (rc==DS_OK && 279 (wfx.wFormatTag!=wfx2.wFormatTag || 280 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec || 281 wfx.wBitsPerSample!=wfx2.wBitsPerSample || 282 wfx.nChannels!=wfx2.nChannels)) { 283 trace("Requested format tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n", 284 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample, 285 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign); 286 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n", 287 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample, 288 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign); 289 } 290 291 ZeroMemory(&new_dsbcaps, sizeof(new_dsbcaps)); 292 new_dsbcaps.dwSize = sizeof(new_dsbcaps); 293 rc=IDirectSoundBuffer_GetCaps(*dsbo,&new_dsbcaps); 294 ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() failed: %08x\n", rc); 295 if (rc==DS_OK && winetest_debug > 1) { 296 trace(" new Caps: flags=0x%08x size=%d\n",new_dsbcaps.dwFlags, 297 new_dsbcaps.dwBufferBytes); 298 } 299 300 /* Check for primary buffer size change */ 301 ok(new_dsbcaps.dwBufferBytes == dsbcaps.dwBufferBytes, 302 " buffer size changed after SetFormat() - " 303 "previous size was %u, current size is %u\n", 304 dsbcaps.dwBufferBytes, new_dsbcaps.dwBufferBytes); 305 dsbcaps.dwBufferBytes = new_dsbcaps.dwBufferBytes; 306 307 /* Check for primary buffer flags change */ 308 ok(new_dsbcaps.dwFlags == dsbcaps.dwFlags, 309 " flags changed after SetFormat() - " 310 "previous flags were %08x, current flags are %08x\n", 311 dsbcaps.dwFlags, new_dsbcaps.dwFlags); 312 313 /* Set the CooperativeLevel back to normal */ 314 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 315 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 316 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_NORMAL) " 317 "failed: %08x\n",rc); 318 } 319 320 if (play) { 321 play_state_t state; 322 DS3DLISTENER listener_param; 323 LPDIRECTSOUND3DBUFFER buffer=NULL; 324 DS3DBUFFER buffer_param; 325 DWORD start_time,now; 326 LPVOID buffer1; 327 DWORD length1; 328 329 if (winetest_interactive) { 330 trace(" Playing %g second 440Hz tone at %dx%dx%d\n", duration, 331 wfx.nSamplesPerSec, wfx.wBitsPerSample,wfx.nChannels); 332 } 333 334 if (is_primary) { 335 /* We must call SetCooperativeLevel to be allowed to call Lock */ 336 /* DSOUND: Setting DirectSound cooperative level to 337 * DSSCL_WRITEPRIMARY */ 338 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(), 339 DSSCL_WRITEPRIMARY); 340 ok(rc==DS_OK, 341 "IDirectSound8_SetCooperativeLevel(DSSCL_WRITEPRIMARY) failed: %08x\n",rc); 342 if (rc!=DS_OK) 343 return; 344 } 345 if (buffer3d) { 346 LPDIRECTSOUNDBUFFER temp_buffer; 347 348 rc=IDirectSoundBuffer_QueryInterface(*dsbo,&IID_IDirectSound3DBuffer, 349 (LPVOID *)&buffer); 350 ok(rc==DS_OK,"IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc); 351 if (rc!=DS_OK) 352 return; 353 354 /* check the COM interface */ 355 rc=IDirectSoundBuffer_QueryInterface(*dsbo, &IID_IDirectSoundBuffer, 356 (LPVOID *)&temp_buffer); 357 ok(rc==DS_OK && temp_buffer!=NULL, 358 "IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc); 359 ok(temp_buffer==*dsbo,"COM interface broken: %p != %p\n", 360 temp_buffer,*dsbo); 361 ref=IDirectSoundBuffer_Release(temp_buffer); 362 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " 363 "should have 1\n",ref); 364 365 temp_buffer=NULL; 366 rc=IDirectSound3DBuffer_QueryInterface(*dsbo, &IID_IDirectSoundBuffer, 367 (LPVOID *)&temp_buffer); 368 ok(rc==DS_OK && temp_buffer!=NULL, 369 "IDirectSound3DBuffer_QueryInterface() failed: %08x\n", rc); 370 ok(temp_buffer==*dsbo,"COM interface broken: %p != %p\n", 371 temp_buffer,*dsbo); 372 ref=IDirectSoundBuffer_Release(temp_buffer); 373 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " 374 "should have 1\n",ref); 375 376 ref=IDirectSoundBuffer_Release(*dsbo); 377 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " 378 "should have 0\n",ref); 379 380 rc=IDirectSound3DBuffer_QueryInterface(buffer, 381 &IID_IDirectSoundBuffer, 382 (LPVOID *)dsbo); 383 ok(rc==DS_OK && *dsbo!=NULL,"IDirectSound3DBuffer_QueryInterface() " 384 "failed: %08x\n",rc); 385 386 /* DSOUND: Error: Invalid buffer */ 387 rc=IDirectSound3DBuffer_GetAllParameters(buffer,0); 388 ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() " 389 "failed: %08x\n",rc); 390 391 ZeroMemory(&buffer_param, sizeof(buffer_param)); 392 393 /* DSOUND: Error: Invalid buffer */ 394 rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param); 395 ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() " 396 "failed: %08x\n",rc); 397 398 buffer_param.dwSize=sizeof(buffer_param); 399 rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param); 400 ok(rc==DS_OK,"IDirectSound3DBuffer_GetAllParameters() failed: %08x\n", rc); 401 } 402 if (set_volume) { 403 if (dsbcaps.dwFlags & DSBCAPS_CTRLVOLUME) { 404 LONG val; 405 rc=IDirectSoundBuffer_GetVolume(*dsbo,&val); 406 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc); 407 408 rc=IDirectSoundBuffer_SetVolume(*dsbo,volume); 409 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume() failed: %08x\n", rc); 410 } else { 411 /* DSOUND: Error: Buffer does not have CTRLVOLUME */ 412 rc=IDirectSoundBuffer_GetVolume(*dsbo,&volume); 413 ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetVolume() " 414 "should have returned DSERR_CONTROLUNAVAIL, returned: %08x\n", rc); 415 } 416 } 417 418 if (set_pan) { 419 if (dsbcaps.dwFlags & DSBCAPS_CTRLPAN) { 420 LONG val; 421 rc=IDirectSoundBuffer_GetPan(*dsbo,&val); 422 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan() failed: %08x\n", rc); 423 424 rc=IDirectSoundBuffer_SetPan(*dsbo,pan); 425 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan() failed: %08x\n", rc); 426 } else { 427 /* DSOUND: Error: Buffer does not have CTRLPAN */ 428 rc=IDirectSoundBuffer_GetPan(*dsbo,&pan); 429 ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetPan() " 430 "should have returned DSERR_CONTROLUNAVAIL, returned: %08x\n", rc); 431 } 432 } 433 434 /* try an offset past the end of the buffer */ 435 rc = IDirectSoundBuffer_Lock(*dsbo, dsbcaps.dwBufferBytes, 0, &buffer1, 436 &length1, NULL, NULL, 437 DSBLOCK_ENTIREBUFFER); 438 ok(rc==DSERR_INVALIDPARAM, "IDirectSoundBuffer_Lock() should have " 439 "returned DSERR_INVALIDPARAM, returned %08x\n", rc); 440 441 /* try a size larger than the buffer */ 442 rc = IDirectSoundBuffer_Lock(*dsbo, 0, dsbcaps.dwBufferBytes + 1, 443 &buffer1, &length1, NULL, NULL, 444 DSBLOCK_FROMWRITECURSOR); 445 ok(rc==DSERR_INVALIDPARAM, "IDirectSoundBuffer_Lock() should have " 446 "returned DSERR_INVALIDPARAM, returned %08x\n", rc); 447 448 state.wave=wave_generate_la(&wfx,duration,&state.wave_len,ieee); 449 450 state.dsbo=*dsbo; 451 state.wfx=&wfx; 452 state.buffer_size=dsbcaps.dwBufferBytes; 453 state.played=state.written=state.offset=0; 454 buffer_refill8(&state,state.buffer_size); 455 456 rc=IDirectSoundBuffer_Play(*dsbo,0,0,DSBPLAY_LOOPING); 457 ok(rc==DS_OK,"IDirectSoundBuffer_Play() failed: %08x\n", rc); 458 459 rc=IDirectSoundBuffer_GetStatus(*dsbo,&status); 460 ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %08x\n", rc); 461 ok(status==(DSBSTATUS_PLAYING|DSBSTATUS_LOOPING), 462 "GetStatus: bad status: %x\n",status); 463 464 if (listener) { 465 ZeroMemory(&listener_param,sizeof(listener_param)); 466 listener_param.dwSize=sizeof(listener_param); 467 rc=IDirectSound3DListener_GetAllParameters(listener,&listener_param); 468 ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters() " 469 "failed: %08x\n",rc); 470 if (move_listener) { 471 listener_param.vPosition.x = -5.0f; 472 listener_param.vVelocity.x = (float)(10.0/duration); 473 } 474 rc=IDirectSound3DListener_SetAllParameters(listener, 475 &listener_param, 476 DS3D_IMMEDIATE); 477 ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: %08x\n", rc); 478 } 479 if (buffer3d) { 480 if (move_sound) { 481 buffer_param.vPosition.x = 100.0f; 482 buffer_param.vVelocity.x = (float)(-200.0/duration); 483 } 484 buffer_param.flMinDistance = 10; 485 rc=IDirectSound3DBuffer_SetAllParameters(buffer,&buffer_param, 486 DS3D_IMMEDIATE); 487 ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %08x\n", rc); 488 } 489 490 start_time=GetTickCount(); 491 while (buffer_service8(&state)) { 492 WaitForSingleObject(GetCurrentProcess(),TIME_SLICE); 493 now=GetTickCount(); 494 if (listener && move_listener) { 495 listener_param.vPosition.x = (float)(-5.0+10.0*(now-start_time)/1000/duration); 496 if (winetest_debug>2) 497 trace("listener position=%g\n",listener_param.vPosition.x); 498 rc=IDirectSound3DListener_SetPosition(listener, 499 listener_param.vPosition.x,listener_param.vPosition.y, 500 listener_param.vPosition.z,DS3D_IMMEDIATE); 501 ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: %08x\n",rc); 502 } 503 if (buffer3d && move_sound) { 504 buffer_param.vPosition.x = (float)(100-200.0*(now-start_time)/1000/duration); 505 if (winetest_debug>2) 506 trace("sound position=%g\n",buffer_param.vPosition.x); 507 rc=IDirectSound3DBuffer_SetPosition(buffer, 508 buffer_param.vPosition.x,buffer_param.vPosition.y, 509 buffer_param.vPosition.z,DS3D_IMMEDIATE); 510 ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %08x\n", rc); 511 } 512 } 513 /* Check the sound duration was within 10% of the expected value */ 514 now=GetTickCount(); 515 ok(fabs(1000*duration-now+start_time)<=100*duration, 516 "The sound played for %d ms instead of %g ms\n", 517 now-start_time,1000*duration); 518 519 HeapFree(GetProcessHeap(), 0, state.wave); 520 if (is_primary) { 521 /* Set the CooperativeLevel back to normal */ 522 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 523 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 524 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_NORMAL) " 525 "failed: %08x\n",rc); 526 } 527 if (buffer3d) { 528 ref=IDirectSound3DBuffer_Release(buffer); 529 ok(ref==0,"IDirectSound3DBuffer_Release() has %d references, " 530 "should have 0\n",ref); 531 } 532 } 533 } 534 535 static HRESULT test_secondary8(LPGUID lpGuid, int play, 536 int has_3d, int has_3dbuffer, 537 int has_listener, int has_duplicate, 538 int move_listener, int move_sound) 539 { 540 HRESULT rc; 541 LPDIRECTSOUND8 dso=NULL; 542 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL; 543 LPDIRECTSOUND3DLISTENER listener=NULL; 544 DSBUFFERDESC bufdesc; 545 WAVEFORMATEX wfx, wfx1; 546 int ref; 547 548 /* Create the DirectSound object */ 549 rc=pDirectSoundCreate8(lpGuid,&dso,NULL); 550 ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate8() failed: %08x\n", rc); 551 if (rc!=DS_OK) 552 return rc; 553 554 /* We must call SetCooperativeLevel before creating primary buffer */ 555 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 556 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 557 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc); 558 if (rc!=DS_OK) 559 goto EXIT; 560 561 ZeroMemory(&bufdesc, sizeof(bufdesc)); 562 bufdesc.dwSize=sizeof(bufdesc); 563 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; 564 if (has_3d) 565 bufdesc.dwFlags|=DSBCAPS_CTRL3D; 566 else 567 bufdesc.dwFlags|=(DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN); 568 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 569 ok((rc==DS_OK && primary!=NULL) || (rc == DSERR_CONTROLUNAVAIL), 570 "IDirectSound8_CreateSoundBuffer() failed to create a %sprimary buffer: %08x\n",has_3d?"3D ":"", rc); 571 if (rc == DSERR_CONTROLUNAVAIL) 572 trace(" No Primary\n"); 573 else if (rc==DS_OK && primary!=NULL) { 574 rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL); 575 ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc); 576 if (rc!=DS_OK) 577 goto EXIT1; 578 579 if (has_listener) { 580 rc=IDirectSoundBuffer_QueryInterface(primary, 581 &IID_IDirectSound3DListener, 582 (void **)&listener); 583 ok(rc==DS_OK && listener!=NULL, 584 "IDirectSoundBuffer_QueryInterface() failed to get a 3D " 585 "listener %08x\n",rc); 586 ref=IDirectSoundBuffer_Release(primary); 587 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 588 "should have 0\n",ref); 589 if (rc==DS_OK && listener!=NULL) { 590 DS3DLISTENER listener_param; 591 ZeroMemory(&listener_param,sizeof(listener_param)); 592 /* DSOUND: Error: Invalid buffer */ 593 rc=IDirectSound3DListener_GetAllParameters(listener,0); 594 ok(rc==DSERR_INVALIDPARAM, 595 "IDirectSound3dListener_GetAllParameters() should have " 596 "returned DSERR_INVALIDPARAM, returned: %08x\n", rc); 597 598 /* DSOUND: Error: Invalid buffer */ 599 rc=IDirectSound3DListener_GetAllParameters(listener, 600 &listener_param); 601 ok(rc==DSERR_INVALIDPARAM, 602 "IDirectSound3dListener_GetAllParameters() should have " 603 "returned DSERR_INVALIDPARAM, returned: %08x\n", rc); 604 605 listener_param.dwSize=sizeof(listener_param); 606 rc=IDirectSound3DListener_GetAllParameters(listener, 607 &listener_param); 608 ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters() " 609 "failed: %08x\n",rc); 610 } else { 611 ok(listener==NULL, "IDirectSoundBuffer_QueryInterface() " 612 "failed but returned a listener anyway\n"); 613 ok(rc!=DS_OK, "IDirectSoundBuffer_QueryInterface() succeeded " 614 "but returned a NULL listener\n"); 615 if (listener) { 616 ref=IDirectSound3DListener_Release(listener); 617 ok(ref==0,"IDirectSound3dListener_Release() listener has " 618 "%d references, should have 0\n",ref); 619 } 620 goto EXIT2; 621 } 622 } 623 624 init_format(&wfx,WAVE_FORMAT_PCM,22050,16,2); 625 secondary=NULL; 626 ZeroMemory(&bufdesc, sizeof(bufdesc)); 627 bufdesc.dwSize=sizeof(bufdesc); 628 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; 629 if (has_3d) 630 bufdesc.dwFlags|=DSBCAPS_CTRL3D; 631 else 632 bufdesc.dwFlags|= 633 (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN); 634 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, 635 wfx.nBlockAlign); 636 bufdesc.lpwfxFormat=&wfx; 637 if (has_3d) { 638 /* a stereo 3D buffer should fail */ 639 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 640 ok(rc==DSERR_INVALIDPARAM, 641 "IDirectSound8_CreateSoundBuffer(secondary) should have " 642 "returned DSERR_INVALIDPARAM, returned %08x\n", rc); 643 if (secondary) 644 { 645 ref=IDirectSoundBuffer_Release(secondary); 646 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, should have 0\n",ref); 647 } 648 init_format(&wfx,WAVE_FORMAT_PCM,22050,16,1); 649 } 650 651 if (winetest_interactive) { 652 trace(" Testing a %s%ssecondary buffer %s%s%s%sat %dx%dx%d " 653 "with a primary buffer at %dx%dx%d\n", 654 has_3dbuffer?"3D ":"", 655 has_duplicate?"duplicated ":"", 656 listener!=NULL||move_sound?"with ":"", 657 move_listener?"moving ":"", 658 listener!=NULL?"listener ":"", 659 listener&&move_sound?"and moving sound ":move_sound? 660 "moving sound ":"", 661 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels, 662 wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels); 663 } 664 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 665 ok(rc==DS_OK && secondary!=NULL,"IDirectSound8_CreateSoundBuffer() " 666 "failed to create a %s%ssecondary buffer %s%s%s%sat %dx%dx%d (%s): %08x\n", 667 has_3dbuffer?"3D ":"", has_duplicate?"duplicated ":"", 668 listener!=NULL||move_sound?"with ":"", move_listener?"moving ":"", 669 listener!=NULL?"listener ":"", 670 listener&&move_sound?"and moving sound ":move_sound? 671 "moving sound ":"", 672 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels, 673 getDSBCAPS(bufdesc.dwFlags),rc); 674 if (rc==DS_OK && secondary!=NULL) { 675 if (!has_3d) { 676 LONG refvol,vol,refpan,pan; 677 678 /* Check the initial secondary buffer's volume and pan */ 679 rc=IDirectSoundBuffer_GetVolume(secondary,&vol); 680 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(secondary) failed: %08x\n",rc); 681 ok(vol==0,"wrong volume for a new secondary buffer: %d\n",vol); 682 rc=IDirectSoundBuffer_GetPan(secondary,&pan); 683 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(secondary) failed: %08x\n",rc); 684 ok(pan==0,"wrong pan for a new secondary buffer: %d\n",pan); 685 686 /* Check that changing the secondary buffer's volume and pan 687 * does not impact the primary buffer's volume and pan 688 */ 689 rc=IDirectSoundBuffer_GetVolume(primary,&refvol); 690 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(primary) failed: %08x\n",rc); 691 rc=IDirectSoundBuffer_GetPan(primary,&refpan); 692 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: %08x\n",rc); 693 694 rc=IDirectSoundBuffer_SetVolume(secondary,-1000); 695 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: %08x\n",rc); 696 rc=IDirectSoundBuffer_GetVolume(secondary,&vol); 697 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: %08x\n",rc); 698 ok(vol==-1000,"secondary: wrong volume %d instead of -1000\n", 699 vol); 700 rc=IDirectSoundBuffer_SetPan(secondary,-1000); 701 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: %08x\n",rc); 702 rc=IDirectSoundBuffer_GetPan(secondary,&pan); 703 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(secondary) failed: %08x\n",rc); 704 ok(pan==-1000,"secondary: wrong pan %d instead of -1000\n", 705 pan); 706 707 rc=IDirectSoundBuffer_GetVolume(primary,&vol); 708 ok(rc==DS_OK,"IDirectSoundBuffer_`GetVolume(primary) failed: i%08x\n",rc); 709 ok(vol==refvol,"The primary volume changed from %d to %d\n", 710 refvol,vol); 711 rc=IDirectSoundBuffer_GetPan(primary,&pan); 712 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: %08x\n",rc); 713 ok(pan==refpan,"The primary pan changed from %d to %d\n", 714 refpan,pan); 715 716 rc=IDirectSoundBuffer_SetVolume(secondary,0); 717 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: %08x\n",rc); 718 rc=IDirectSoundBuffer_SetPan(secondary,0); 719 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: %08x\n",rc); 720 } 721 if (has_duplicate) { 722 LPDIRECTSOUNDBUFFER duplicated=NULL; 723 724 /* DSOUND: Error: Invalid source buffer */ 725 rc=IDirectSound8_DuplicateSoundBuffer(dso,0,0); 726 ok(rc==DSERR_INVALIDPARAM, 727 "IDirectSound8_DuplicateSoundBuffer() should have returned " 728 "DSERR_INVALIDPARAM, returned: %08x\n",rc); 729 730 /* DSOUND: Error: Invalid dest buffer */ 731 rc=IDirectSound8_DuplicateSoundBuffer(dso,secondary,0); 732 ok(rc==DSERR_INVALIDPARAM, 733 "IDirectSound8_DuplicateSoundBuffer() should have returned " 734 "DSERR_INVALIDPARAM, returned: %08x\n",rc); 735 736 /* DSOUND: Error: Invalid source buffer */ 737 rc=IDirectSound8_DuplicateSoundBuffer(dso,0,&duplicated); 738 ok(rc==DSERR_INVALIDPARAM, 739 "IDirectSound8_DuplicateSoundBuffer() should have returned " 740 "DSERR_INVALIDPARAM, returned: %08x\n",rc); 741 742 duplicated=NULL; 743 rc=IDirectSound8_DuplicateSoundBuffer(dso,secondary, 744 &duplicated); 745 ok(rc==DS_OK && duplicated!=NULL, 746 "IDirectSound8_DuplicateSoundBuffer() failed to duplicate " 747 "a secondary buffer: %08x\n",rc); 748 749 if (rc==DS_OK && duplicated!=NULL) { 750 ref=IDirectSoundBuffer_Release(secondary); 751 ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d " 752 "references, should have 0\n",ref); 753 secondary=duplicated; 754 } 755 } 756 757 if (rc==DS_OK && secondary!=NULL) { 758 double duration; 759 duration=(move_listener || move_sound?4.0:1.0); 760 test_buffer8(dso,&secondary,0,FALSE,0,FALSE,0, 761 winetest_interactive,duration,has_3dbuffer, 762 listener,move_listener,move_sound); 763 ref=IDirectSoundBuffer_Release(secondary); 764 ok(ref==0,"IDirectSoundBuffer_Release() %s has %d references, " 765 "should have 0\n",has_duplicate?"duplicated":"secondary", 766 ref); 767 } 768 } 769 EXIT1: 770 if (has_listener) { 771 if (listener) { 772 ref=IDirectSound3DListener_Release(listener); 773 ok(ref==0,"IDirectSound3dListener_Release() listener has %d " 774 "references, should have 0\n",ref); 775 } 776 } else { 777 ref=IDirectSoundBuffer_Release(primary); 778 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 779 "should have 0\n",ref); 780 } 781 } else { 782 ok(primary==NULL,"IDirectSound8_CreateSoundBuffer(primary) failed " 783 "but primary created anyway\n"); 784 ok(rc!=DS_OK,"IDirectSound8_CreateSoundBuffer(primary) succeeded " 785 "but primary not created\n"); 786 if (primary) { 787 ref=IDirectSoundBuffer_Release(primary); 788 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 789 "should have 0\n",ref); 790 } 791 } 792 EXIT2: 793 /* Set the CooperativeLevel back to normal */ 794 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 795 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 796 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_NORMAL) failed: %08x\n",rc); 797 798 EXIT: 799 ref=IDirectSound8_Release(dso); 800 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref); 801 if (ref!=0) 802 return DSERR_GENERIC; 803 804 return rc; 805 } 806 807 static HRESULT test_for_driver8(LPGUID lpGuid) 808 { 809 HRESULT rc; 810 LPDIRECTSOUND8 dso=NULL; 811 int ref; 812 813 /* Create the DirectSound object */ 814 rc=pDirectSoundCreate8(lpGuid,&dso,NULL); 815 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, 816 "DirectSoundCreate8() failed: %08x\n",rc); 817 if (rc!=DS_OK) 818 return rc; 819 820 ref=IDirectSound8_Release(dso); 821 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref); 822 if (ref!=0) 823 return DSERR_GENERIC; 824 825 return rc; 826 } 827 828 static HRESULT test_primary8(LPGUID lpGuid) 829 { 830 HRESULT rc; 831 LPDIRECTSOUND8 dso=NULL; 832 LPDIRECTSOUNDBUFFER primary=NULL; 833 DSBUFFERDESC bufdesc; 834 DSCAPS dscaps; 835 int ref, i; 836 837 /* Create the DirectSound object */ 838 rc=pDirectSoundCreate8(lpGuid,&dso,NULL); 839 ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate8() failed: %08x\n", rc); 840 if (rc!=DS_OK) 841 return rc; 842 843 /* Get the device capabilities */ 844 ZeroMemory(&dscaps, sizeof(dscaps)); 845 dscaps.dwSize=sizeof(dscaps); 846 rc=IDirectSound8_GetCaps(dso,&dscaps); 847 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc); 848 if (rc!=DS_OK) 849 goto EXIT; 850 851 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */ 852 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 853 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 854 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc); 855 if (rc!=DS_OK) 856 goto EXIT; 857 858 /* Testing the primary buffer */ 859 primary=NULL; 860 ZeroMemory(&bufdesc, sizeof(bufdesc)); 861 bufdesc.dwSize=sizeof(bufdesc); 862 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN; 863 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 864 ok((rc==DS_OK && primary!=NULL) || (rc == DSERR_CONTROLUNAVAIL), 865 "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: %08x\n",rc); 866 if (rc == DSERR_CONTROLUNAVAIL) 867 trace(" No Primary\n"); 868 else if (rc==DS_OK && primary!=NULL) { 869 test_buffer8(dso,&primary,1,TRUE,0,TRUE,0,winetest_interactive && 870 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,NULL,0,0); 871 if (winetest_interactive) { 872 LONG volume,pan; 873 874 volume = DSBVOLUME_MAX; 875 for (i = 0; i < 6; i++) { 876 test_buffer8(dso,&primary,1,TRUE,volume,TRUE,0, 877 winetest_interactive && 878 !(dscaps.dwFlags & DSCAPS_EMULDRIVER), 879 1.0,0,NULL,0,0); 880 volume -= ((DSBVOLUME_MAX-DSBVOLUME_MIN) / 40); 881 } 882 883 pan = DSBPAN_LEFT; 884 for (i = 0; i < 7; i++) { 885 test_buffer8(dso,&primary,1,TRUE,0,TRUE,pan, 886 winetest_interactive && 887 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0); 888 pan += ((DSBPAN_RIGHT-DSBPAN_LEFT) / 6); 889 } 890 } 891 ref=IDirectSoundBuffer_Release(primary); 892 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 893 "should have 0\n",ref); 894 } 895 896 /* Set the CooperativeLevel back to normal */ 897 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 898 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 899 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_NORMAL) failed: %08x\n",rc); 900 901 EXIT: 902 ref=IDirectSound8_Release(dso); 903 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref); 904 if (ref!=0) 905 return DSERR_GENERIC; 906 907 return rc; 908 } 909 910 static HRESULT test_primary_3d8(LPGUID lpGuid) 911 { 912 HRESULT rc; 913 LPDIRECTSOUND8 dso=NULL; 914 LPDIRECTSOUNDBUFFER primary=NULL; 915 DSBUFFERDESC bufdesc; 916 DSCAPS dscaps; 917 int ref; 918 919 /* Create the DirectSound object */ 920 rc=pDirectSoundCreate8(lpGuid,&dso,NULL); 921 ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate8() failed: %08x\n", rc); 922 if (rc!=DS_OK) 923 return rc; 924 925 /* Get the device capabilities */ 926 ZeroMemory(&dscaps, sizeof(dscaps)); 927 dscaps.dwSize=sizeof(dscaps); 928 rc=IDirectSound8_GetCaps(dso,&dscaps); 929 ok(rc==DS_OK,"IDirectSound8_GetCaps failed: %08x\n",rc); 930 if (rc!=DS_OK) 931 goto EXIT; 932 933 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */ 934 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 935 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 936 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc); 937 if (rc!=DS_OK) 938 goto EXIT; 939 940 primary=NULL; 941 ZeroMemory(&bufdesc, sizeof(bufdesc)); 942 bufdesc.dwSize=sizeof(bufdesc); 943 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; 944 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 945 ok(rc==DS_OK && primary!=NULL,"IDirectSound8_CreateSoundBuffer() failed " 946 "to create a primary buffer: %08x\n",rc); 947 if (rc==DS_OK && primary!=NULL) { 948 ref=IDirectSoundBuffer_Release(primary); 949 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 950 "should have 0\n",ref); 951 primary=NULL; 952 ZeroMemory(&bufdesc, sizeof(bufdesc)); 953 bufdesc.dwSize=sizeof(bufdesc); 954 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D; 955 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 956 ok(rc==DS_OK && primary!=NULL,"IDirectSound8_CreateSoundBuffer() " 957 "failed to create a 3D primary buffer: %08x\n",rc); 958 if (rc==DS_OK && primary!=NULL) { 959 test_buffer8(dso,&primary,1,FALSE,0,FALSE,0, 960 winetest_interactive && 961 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0); 962 ref=IDirectSoundBuffer_Release(primary); 963 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 964 "should have 0\n",ref); 965 } 966 } 967 /* Set the CooperativeLevel back to normal */ 968 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 969 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 970 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_NORMAL) failed: %08x\n",rc); 971 972 EXIT: 973 ref=IDirectSound8_Release(dso); 974 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref); 975 if (ref!=0) 976 return DSERR_GENERIC; 977 978 return rc; 979 } 980 981 static HRESULT test_primary_3d_with_listener8(LPGUID lpGuid) 982 { 983 HRESULT rc; 984 LPDIRECTSOUND8 dso=NULL; 985 LPDIRECTSOUNDBUFFER primary=NULL; 986 DSBUFFERDESC bufdesc; 987 DSCAPS dscaps; 988 int ref; 989 990 /* Create the DirectSound object */ 991 rc=pDirectSoundCreate8(lpGuid,&dso,NULL); 992 ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate8() failed: %08x\n", rc); 993 if (rc!=DS_OK) 994 return rc; 995 996 /* Get the device capabilities */ 997 ZeroMemory(&dscaps, sizeof(dscaps)); 998 dscaps.dwSize=sizeof(dscaps); 999 rc=IDirectSound8_GetCaps(dso,&dscaps); 1000 ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc); 1001 if (rc!=DS_OK) 1002 goto EXIT; 1003 1004 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */ 1005 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 1006 rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 1007 ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc); 1008 if (rc!=DS_OK) 1009 goto EXIT; 1010 primary=NULL; 1011 ZeroMemory(&bufdesc, sizeof(bufdesc)); 1012 bufdesc.dwSize=sizeof(bufdesc); 1013 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D; 1014 rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 1015 ok(rc==DS_OK && primary!=NULL,"IDirectSound8_CreateSoundBuffer() failed " 1016 "to create a 3D primary buffer %08x\n",rc); 1017 if (rc==DS_OK && primary!=NULL) { 1018 LPDIRECTSOUND3DLISTENER listener=NULL; 1019 rc=IDirectSoundBuffer_QueryInterface(primary, 1020 &IID_IDirectSound3DListener, 1021 (void **)&listener); 1022 ok(rc==DS_OK && listener!=NULL,"IDirectSoundBuffer_QueryInterface() " 1023 "failed to get a 3D listener: %08x\n",rc); 1024 if (rc==DS_OK && listener!=NULL) { 1025 LPDIRECTSOUNDBUFFER temp_buffer=NULL; 1026 1027 /* Checking the COM interface */ 1028 rc=IDirectSoundBuffer_QueryInterface(primary, 1029 &IID_IDirectSoundBuffer, 1030 (LPVOID *)&temp_buffer); 1031 ok(rc==DS_OK && temp_buffer!=NULL, 1032 "IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc); 1033 ok(temp_buffer==primary,"COM interface broken: %p != %p\n",temp_buffer,primary); 1034 if (rc==DS_OK && temp_buffer!=NULL) { 1035 ref=IDirectSoundBuffer_Release(temp_buffer); 1036 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " 1037 "should have 1\n",ref); 1038 1039 temp_buffer=NULL; 1040 rc=IDirectSound3DListener_QueryInterface(listener, 1041 &IID_IDirectSoundBuffer,(LPVOID *)&temp_buffer); 1042 ok(rc==DS_OK && temp_buffer!=NULL, 1043 "IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc); 1044 ok(temp_buffer==primary,"COM interface broken: %p != %p\n",temp_buffer,primary); 1045 ref=IDirectSoundBuffer_Release(temp_buffer); 1046 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " 1047 "should have 1\n",ref); 1048 1049 /* Testing the buffer */ 1050 test_buffer8(dso,&primary,1,FALSE,0,FALSE,0, 1051 winetest_interactive && 1052 !(dscaps.dwFlags & DSCAPS_EMULDRIVER), 1053 1.0,0,listener,0,0); 1054 } 1055 1056 /* Testing the reference counting */ 1057 ref=IDirectSound3DListener_Release(listener); 1058 ok(ref==0,"IDirectSound3DListener_Release() listener has %d " 1059 "references, should have 0\n",ref); 1060 } 1061 1062 /* Testing the reference counting */ 1063 ref=IDirectSoundBuffer_Release(primary); 1064 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 1065 "should have 0\n",ref); 1066 } 1067 1068 EXIT: 1069 ref=IDirectSound8_Release(dso); 1070 ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref); 1071 if (ref!=0) 1072 return DSERR_GENERIC; 1073 1074 return rc; 1075 } 1076 1077 static unsigned driver_count = 0; 1078 1079 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription, 1080 LPCSTR lpcstrModule, LPVOID lpContext) 1081 { 1082 HRESULT rc; 1083 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule); 1084 driver_count++; 1085 1086 rc = test_for_driver8(lpGuid); 1087 if (rc == DSERR_NODRIVER) { 1088 trace(" No Driver\n"); 1089 return 1; 1090 } else if (rc == DSERR_ALLOCATED) { 1091 trace(" Already In Use\n"); 1092 return 1; 1093 } else if (rc == E_FAIL) { 1094 trace(" No Device\n"); 1095 return 1; 1096 } 1097 1098 trace(" Testing the primary buffer\n"); 1099 test_primary8(lpGuid); 1100 1101 trace(" Testing 3D primary buffer\n"); 1102 test_primary_3d8(lpGuid); 1103 1104 trace(" Testing 3D primary buffer with listener\n"); 1105 test_primary_3d_with_listener8(lpGuid); 1106 1107 /* Testing secondary buffers */ 1108 test_secondary8(lpGuid,winetest_interactive,0,0,0,0,0,0); 1109 test_secondary8(lpGuid,winetest_interactive,0,0,0,1,0,0); 1110 1111 /* Testing 3D secondary buffers */ 1112 test_secondary8(lpGuid,winetest_interactive,1,0,0,0,0,0); 1113 test_secondary8(lpGuid,winetest_interactive,1,1,0,0,0,0); 1114 test_secondary8(lpGuid,winetest_interactive,1,1,0,1,0,0); 1115 test_secondary8(lpGuid,winetest_interactive,1,0,1,0,0,0); 1116 test_secondary8(lpGuid,winetest_interactive,1,0,1,1,0,0); 1117 test_secondary8(lpGuid,winetest_interactive,1,1,1,0,0,0); 1118 test_secondary8(lpGuid,winetest_interactive,1,1,1,1,0,0); 1119 test_secondary8(lpGuid,winetest_interactive,1,1,1,0,1,0); 1120 test_secondary8(lpGuid,winetest_interactive,1,1,1,0,0,1); 1121 test_secondary8(lpGuid,winetest_interactive,1,1,1,0,1,1); 1122 1123 return 1; 1124 } 1125 1126 static void ds3d8_tests(void) 1127 { 1128 HRESULT rc; 1129 rc=pDirectSoundEnumerateA(&dsenum_callback,NULL); 1130 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %08x\n",rc); 1131 trace("tested %u DirectSound drivers\n", driver_count); 1132 } 1133 1134 START_TEST(ds3d8) 1135 { 1136 HMODULE hDsound; 1137 1138 CoInitialize(NULL); 1139 1140 hDsound = LoadLibrary("dsound.dll"); 1141 if (hDsound) 1142 { 1143 1144 pDirectSoundEnumerateA = (void*)GetProcAddress(hDsound, 1145 "DirectSoundEnumerateA"); 1146 pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, 1147 "DirectSoundCreate8"); 1148 if (pDirectSoundCreate8) 1149 ds3d8_tests(); 1150 else 1151 skip("DirectSoundCreate8 missing - skipping all tests\n"); 1152 1153 FreeLibrary(hDsound); 1154 } 1155 else 1156 skip("dsound.dll not found - skipping all tests\n"); 1157 1158 CoUninitialize(); 1159 } 1160