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