Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygends3d.c
Go to the documentation of this file.
00001 /* 00002 * Tests the panning and 3D functions of DirectSound 00003 * 00004 * Part of this test involves playing test tones. But this only makes 00005 * sense if someone is going to carefully listen to it, and would only 00006 * bother everyone else. 00007 * So this is only done if the test is being run in interactive mode. 00008 * 00009 * Copyright (c) 2002-2004 Francois Gouget 00010 * 00011 * This library is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU Lesser General Public 00013 * License as published by the Free Software Foundation; either 00014 * version 2.1 of the License, or (at your option) any later version. 00015 * 00016 * This library is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 * Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with this library; if not, write to the Free Software 00023 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00024 */ 00025 00026 #define NONAMELESSSTRUCT 00027 #define NONAMELESSUNION 00028 #include <windows.h> 00029 00030 #include <math.h> 00031 00032 #include "wine/test.h" 00033 #include "dsound.h" 00034 #include "dxerr8.h" 00035 00036 #include "dsound_test.h" 00037 00038 #define PI 3.14159265358979323846 00039 char* wave_generate_la(WAVEFORMATEX* wfx, double duration, DWORD* size) 00040 { 00041 int i; 00042 int nb_samples; 00043 char* buf; 00044 char* b; 00045 00046 nb_samples=(int)(duration*wfx->nSamplesPerSec); 00047 *size=nb_samples*wfx->nBlockAlign; 00048 b=buf=malloc(*size); 00049 for (i=0;i<nb_samples;i++) { 00050 double y=sin(440.0*2*PI*i/wfx->nSamplesPerSec); 00051 if (wfx->wBitsPerSample==8) { 00052 unsigned char sample=(unsigned char)((double)127.5*(y+1.0)); 00053 *b++=sample; 00054 if (wfx->nChannels==2) 00055 *b++=sample; 00056 } else { 00057 signed short sample=(signed short)((double)32767.5*y-0.5); 00058 b[0]=sample & 0xff; 00059 b[1]=sample >> 8; 00060 b+=2; 00061 if (wfx->nChannels==2) { 00062 b[0]=sample & 0xff; 00063 b[1]=sample >> 8; 00064 b+=2; 00065 } 00066 } 00067 } 00068 return buf; 00069 } 00070 00071 const char * getDSBCAPS(DWORD xmask) { 00072 static struct { 00073 DWORD mask; 00074 const char *name; 00075 } flags[] = { 00076 #define FE(x) { x, #x }, 00077 FE(DSBCAPS_PRIMARYBUFFER) 00078 FE(DSBCAPS_STATIC) 00079 FE(DSBCAPS_LOCHARDWARE) 00080 FE(DSBCAPS_LOCSOFTWARE) 00081 FE(DSBCAPS_CTRL3D) 00082 FE(DSBCAPS_CTRLFREQUENCY) 00083 FE(DSBCAPS_CTRLPAN) 00084 FE(DSBCAPS_CTRLVOLUME) 00085 FE(DSBCAPS_CTRLPOSITIONNOTIFY) 00086 FE(DSBCAPS_STICKYFOCUS) 00087 FE(DSBCAPS_GLOBALFOCUS) 00088 FE(DSBCAPS_GETCURRENTPOSITION2) 00089 FE(DSBCAPS_MUTE3DATMAXDISTANCE) 00090 #undef FE 00091 }; 00092 static char buffer[512]; 00093 unsigned int i; 00094 BOOL first = TRUE; 00095 00096 buffer[0] = 0; 00097 00098 for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) { 00099 if ((flags[i].mask & xmask) == flags[i].mask) { 00100 if (first) 00101 first = FALSE; 00102 else 00103 strcat(buffer, "|"); 00104 strcat(buffer, flags[i].name); 00105 } 00106 } 00107 00108 return buffer; 00109 } 00110 00111 HWND get_hwnd() 00112 { 00113 HWND hwnd=GetForegroundWindow(); 00114 if (!hwnd) 00115 hwnd=GetDesktopWindow(); 00116 return hwnd; 00117 } 00118 00119 void init_format(WAVEFORMATEX* wfx, int format, int rate, int depth, 00120 int channels) 00121 { 00122 wfx->wFormatTag=format; 00123 wfx->nChannels=channels; 00124 wfx->wBitsPerSample=depth; 00125 wfx->nSamplesPerSec=rate; 00126 wfx->nBlockAlign=wfx->nChannels*wfx->wBitsPerSample/8; 00127 /* FIXME: Shouldn't this test be if (format!=WAVE_FORMAT_PCM) */ 00128 if (wfx->nBlockAlign==0) 00129 { 00130 /* align compressed formats to byte boundary */ 00131 wfx->nBlockAlign=1; 00132 } 00133 wfx->nAvgBytesPerSec=wfx->nSamplesPerSec*wfx->nBlockAlign; 00134 wfx->cbSize=0; 00135 } 00136 00137 typedef struct { 00138 char* wave; 00139 DWORD wave_len; 00140 00141 LPDIRECTSOUNDBUFFER dsbo; 00142 LPWAVEFORMATEX wfx; 00143 DWORD buffer_size; 00144 DWORD written; 00145 DWORD played; 00146 DWORD offset; 00147 } play_state_t; 00148 00149 static int buffer_refill(play_state_t* state, DWORD size) 00150 { 00151 LPVOID ptr1,ptr2; 00152 DWORD len1,len2; 00153 HRESULT rc; 00154 00155 if (size>state->wave_len-state->written) 00156 size=state->wave_len-state->written; 00157 00158 rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size, 00159 &ptr1,&len1,&ptr2,&len2,0); 00160 ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n", 00161 DXGetErrorString8(rc)); 00162 if (rc!=DS_OK) 00163 return -1; 00164 00165 memcpy(ptr1,state->wave+state->written,len1); 00166 state->written+=len1; 00167 if (ptr2!=NULL) { 00168 memcpy(ptr2,state->wave+state->written,len2); 00169 state->written+=len2; 00170 } 00171 state->offset=state->written % state->buffer_size; 00172 rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2); 00173 ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n", 00174 DXGetErrorString8(rc)); 00175 if (rc!=DS_OK) 00176 return -1; 00177 return size; 00178 } 00179 00180 static int buffer_silence(play_state_t* state, DWORD size) 00181 { 00182 LPVOID ptr1,ptr2; 00183 DWORD len1,len2; 00184 HRESULT rc; 00185 BYTE s; 00186 00187 rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size, 00188 &ptr1,&len1,&ptr2,&len2,0); 00189 ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n", 00190 DXGetErrorString8(rc)); 00191 if (rc!=DS_OK) 00192 return -1; 00193 00194 s=(state->wfx->wBitsPerSample==8?0x80:0); 00195 memset(ptr1,s,len1); 00196 if (ptr2!=NULL) { 00197 memset(ptr2,s,len2); 00198 } 00199 state->offset=(state->offset+size) % state->buffer_size; 00200 rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2); 00201 ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n", 00202 DXGetErrorString8(rc)); 00203 if (rc!=DS_OK) 00204 return -1; 00205 return size; 00206 } 00207 00208 static int buffer_service(play_state_t* state) 00209 { 00210 DWORD last_play_pos,play_pos,buf_free; 00211 HRESULT rc; 00212 00213 rc=IDirectSoundBuffer_GetCurrentPosition(state->dsbo,&play_pos,NULL); 00214 ok(rc==DS_OK,"IDirectSoundBuffer_GetCurrentPosition() failed: %s\n", 00215 DXGetErrorString8(rc)); 00216 if (rc!=DS_OK) { 00217 goto STOP; 00218 } 00219 00220 /* Update the amount played */ 00221 last_play_pos=state->played % state->buffer_size; 00222 if (play_pos<last_play_pos) 00223 state->played+=state->buffer_size-last_play_pos+play_pos; 00224 else 00225 state->played+=play_pos-last_play_pos; 00226 00227 if (winetest_debug > 1) 00228 trace("buf size=%ld last_play_pos=%ld play_pos=%ld played=%ld / %ld\n", 00229 state->buffer_size,last_play_pos,play_pos,state->played, 00230 state->wave_len); 00231 00232 if (state->played>state->wave_len) 00233 { 00234 /* Everything has been played */ 00235 goto STOP; 00236 } 00237 00238 /* Refill the buffer */ 00239 if (state->offset<=play_pos) 00240 buf_free=play_pos-state->offset; 00241 else 00242 buf_free=state->buffer_size-state->offset+play_pos; 00243 00244 if (winetest_debug > 1) 00245 trace("offset=%ld free=%ld written=%ld / %ld\n", 00246 state->offset,buf_free,state->written,state->wave_len); 00247 if (buf_free==0) 00248 return 1; 00249 00250 if (state->written<state->wave_len) 00251 { 00252 int w=buffer_refill(state,buf_free); 00253 if (w==-1) 00254 goto STOP; 00255 buf_free-=w; 00256 if (state->written==state->wave_len && winetest_debug > 1) 00257 trace("last sound byte at %ld\n", 00258 (state->written % state->buffer_size)); 00259 } 00260 00261 if (buf_free>0) { 00262 /* Fill with silence */ 00263 if (winetest_debug > 1) 00264 trace("writing %ld bytes of silence\n",buf_free); 00265 if (buffer_silence(state,buf_free)==-1) 00266 goto STOP; 00267 } 00268 return 1; 00269 00270 STOP: 00271 if (winetest_debug > 1) 00272 trace("stopping playback\n"); 00273 rc=IDirectSoundBuffer_Stop(state->dsbo); 00274 ok(rc==DS_OK,"IDirectSoundBuffer_Stop() failed: %s\n", 00275 DXGetErrorString8(rc)); 00276 return 0; 00277 } 00278 00279 void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo, 00280 BOOL is_primary, BOOL set_volume, LONG volume, 00281 BOOL set_pan, LONG pan, BOOL play, double duration, 00282 BOOL buffer3d, LPDIRECTSOUND3DLISTENER listener, 00283 BOOL move_listener, BOOL move_sound, 00284 BOOL set_frequency, DWORD frequency) 00285 { 00286 HRESULT rc; 00287 DSBCAPS dsbcaps; 00288 WAVEFORMATEX wfx,wfx2; 00289 DWORD size,status,freq; 00290 int ref; 00291 00292 if (set_frequency) { 00293 rc=IDirectSoundBuffer_SetFrequency(dsbo,frequency); 00294 ok(rc==DS_OK||rc==DSERR_CONTROLUNAVAIL, 00295 "IDirectSoundBuffer_SetFrequency() failed to set frequency " 00296 "%s\n",DXGetErrorString8(rc)); 00297 if (rc!=DS_OK) 00298 return; 00299 } 00300 00301 /* DSOUND: Error: Invalid caps pointer */ 00302 rc=IDirectSoundBuffer_GetCaps(dsbo,0); 00303 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have " 00304 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); 00305 00306 ZeroMemory(&dsbcaps, sizeof(dsbcaps)); 00307 00308 /* DSOUND: Error: Invalid caps pointer */ 00309 rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps); 00310 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have " 00311 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); 00312 00313 dsbcaps.dwSize=sizeof(dsbcaps); 00314 rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps); 00315 ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() failed: %s\n", 00316 DXGetErrorString8(rc)); 00317 if (rc==DS_OK && winetest_debug > 1) { 00318 trace(" Caps: flags=0x%08lx size=%ld\n",dsbcaps.dwFlags, 00319 dsbcaps.dwBufferBytes); 00320 } 00321 00322 /* Query the format size. Note that it may not match sizeof(wfx) */ 00323 size=0; 00324 rc=IDirectSoundBuffer_GetFormat(dsbo,NULL,0,&size); 00325 ok(rc==DS_OK && size!=0,"IDirectSoundBuffer_GetFormat() should have " 00326 "returned the needed size: rc=%s size=%ld\n",DXGetErrorString8(rc),size); 00327 00328 rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL); 00329 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n", 00330 DXGetErrorString8(rc)); 00331 if (rc==DS_OK && winetest_debug > 1) { 00332 trace(" Format: %s tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n", 00333 is_primary ? "Primary" : "Secondary", 00334 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample, 00335 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign); 00336 } 00337 00338 /* DSOUND: Error: Invalid frequency buffer */ 00339 rc=IDirectSoundBuffer_GetFrequency(dsbo,0); 00340 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetFrequency() should have " 00341 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); 00342 00343 /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */ 00344 rc=IDirectSoundBuffer_GetFrequency(dsbo,&freq); 00345 ok((rc==DS_OK && !is_primary) || (rc==DSERR_CONTROLUNAVAIL&&is_primary) || 00346 (rc==DSERR_CONTROLUNAVAIL&&!(dsbcaps.dwFlags&DSBCAPS_CTRLFREQUENCY)), 00347 "IDirectSoundBuffer_GetFrequency() failed: %s\n",DXGetErrorString8(rc)); 00348 if (rc==DS_OK) { 00349 DWORD f = set_frequency?frequency:wfx.nSamplesPerSec; 00350 ok(freq==f,"The frequency returned by GetFrequency " 00351 "%ld does not match the format %ld\n",freq,f); 00352 } 00353 00354 /* DSOUND: Error: Invalid status pointer */ 00355 rc=IDirectSoundBuffer_GetStatus(dsbo,0); 00356 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetStatus() should have " 00357 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); 00358 00359 rc=IDirectSoundBuffer_GetStatus(dsbo,&status); 00360 ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %s\n", 00361 DXGetErrorString8(rc)); 00362 ok(status==0,"status=0x%lx instead of 0\n",status); 00363 00364 if (is_primary) { 00365 /* We must call SetCooperativeLevel to be allowed to call SetFormat */ 00366 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 00367 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 00368 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: " 00369 "%s\n",DXGetErrorString8(rc)); 00370 if (rc!=DS_OK) 00371 return; 00372 00373 /* DSOUND: Error: Invalid format pointer */ 00374 rc=IDirectSoundBuffer_SetFormat(dsbo,0); 00375 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_SetFormat() should have " 00376 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); 00377 00378 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2); 00379 rc=IDirectSoundBuffer_SetFormat(dsbo,&wfx2); 00380 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n", 00381 DXGetErrorString8(rc)); 00382 00383 /* There is no garantee that SetFormat will actually change the 00384 * format to what we asked for. It depends on what the soundcard 00385 * supports. So we must re-query the format. 00386 */ 00387 rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL); 00388 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n", 00389 DXGetErrorString8(rc)); 00390 if (rc==DS_OK && 00391 (wfx.wFormatTag!=wfx2.wFormatTag || 00392 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec || 00393 wfx.wBitsPerSample!=wfx2.wBitsPerSample || 00394 wfx.nChannels!=wfx2.nChannels)) { 00395 trace("Requested format tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n", 00396 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample, 00397 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign); 00398 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n", 00399 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample, 00400 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign); 00401 } 00402 00403 /* Set the CooperativeLevel back to normal */ 00404 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 00405 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 00406 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: " 00407 "%s\n",DXGetErrorString8(rc)); 00408 } 00409 00410 if (play) { 00411 play_state_t state; 00412 DS3DLISTENER listener_param; 00413 LPDIRECTSOUND3DBUFFER buffer=NULL; 00414 DS3DBUFFER buffer_param; 00415 DWORD start_time,now; 00416 00417 if (winetest_interactive) { 00418 if (set_frequency) 00419 trace(" Playing %g second 440Hz tone at %ldx%dx%d with a " 00420 "frequency of %ld (%ldHz)\n", duration, 00421 wfx.nSamplesPerSec, wfx.wBitsPerSample, wfx.nChannels, 00422 frequency, (440 * frequency) / wfx.nSamplesPerSec); 00423 else 00424 trace(" Playing %g second 440Hz tone at %ldx%dx%d\n", duration, 00425 wfx.nSamplesPerSec, wfx.wBitsPerSample, wfx.nChannels); 00426 } 00427 00428 if (is_primary) { 00429 /* We must call SetCooperativeLevel to be allowed to call Lock */ 00430 /* DSOUND: Setting DirectSound cooperative level to 00431 * DSSCL_WRITEPRIMARY */ 00432 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(), 00433 DSSCL_WRITEPRIMARY); 00434 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_WRITEPRIMARY) " 00435 "failed: %s\n",DXGetErrorString8(rc)); 00436 if (rc!=DS_OK) 00437 return; 00438 } 00439 if (buffer3d) { 00440 LPDIRECTSOUNDBUFFER temp_buffer; 00441 00442 rc=IDirectSoundBuffer_QueryInterface(dsbo,&IID_IDirectSound3DBuffer, 00443 (LPVOID *)&buffer); 00444 ok(rc==DS_OK,"IDirectSoundBuffer_QueryInterface() failed: %s\n", 00445 DXGetErrorString8(rc)); 00446 if (rc!=DS_OK) 00447 return; 00448 00449 /* check the COM interface */ 00450 rc=IDirectSoundBuffer_QueryInterface(dsbo, &IID_IDirectSoundBuffer, 00451 (LPVOID *)&temp_buffer); 00452 ok(rc==DS_OK && temp_buffer!=NULL, 00453 "IDirectSoundBuffer_QueryInterface() failed: %s\n", 00454 DXGetErrorString8(rc)); 00455 ok(temp_buffer==dsbo,"COM interface broken: %p != %p\n", 00456 temp_buffer,dsbo); 00457 ref=IDirectSoundBuffer_Release(temp_buffer); 00458 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " 00459 "should have 1\n",ref); 00460 00461 temp_buffer=NULL; 00462 rc=IDirectSound3DBuffer_QueryInterface(dsbo, 00463 &IID_IDirectSoundBuffer, 00464 (LPVOID *)&temp_buffer); 00465 ok(rc==DS_OK && temp_buffer!=NULL, 00466 "IDirectSound3DBuffer_QueryInterface() failed: %s\n", 00467 DXGetErrorString8(rc)); 00468 ok(temp_buffer==dsbo,"COM interface broken: %p != %p\n", 00469 temp_buffer,dsbo); 00470 ref=IDirectSoundBuffer_Release(temp_buffer); 00471 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " 00472 "should have 1\n",ref); 00473 00474 #if 0 00475 /* FIXME: this works on windows */ 00476 ref=IDirectSoundBuffer_Release(dsbo); 00477 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " 00478 "should have 0\n",ref); 00479 00480 rc=IDirectSound3DBuffer_QueryInterface(buffer, 00481 &IID_IDirectSoundBuffer, 00482 (LPVOID *)&dsbo); 00483 ok(rc==DS_OK && dsbo!=NULL,"IDirectSound3DBuffer_QueryInterface() " 00484 "failed: %s\n",DXGetErrorString8(rc)); 00485 #endif 00486 00487 /* DSOUND: Error: Invalid buffer */ 00488 rc=IDirectSound3DBuffer_GetAllParameters(buffer,0); 00489 ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() " 00490 "failed: %s\n",DXGetErrorString8(rc)); 00491 00492 ZeroMemory(&buffer_param, sizeof(buffer_param)); 00493 00494 /* DSOUND: Error: Invalid buffer */ 00495 rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param); 00496 ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() " 00497 "failed: %s\n",DXGetErrorString8(rc)); 00498 00499 buffer_param.dwSize=sizeof(buffer_param); 00500 rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param); 00501 ok(rc==DS_OK,"IDirectSound3DBuffer_GetAllParameters() failed: %s\n", 00502 DXGetErrorString8(rc)); 00503 } 00504 if (set_volume) { 00505 if (dsbcaps.dwFlags & DSBCAPS_CTRLVOLUME) { 00506 LONG val; 00507 rc=IDirectSoundBuffer_GetVolume(dsbo,&val); 00508 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n", 00509 DXGetErrorString8(rc)); 00510 00511 rc=IDirectSoundBuffer_SetVolume(dsbo,volume); 00512 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume() failed: %s\n", 00513 DXGetErrorString8(rc)); 00514 } else { 00515 /* DSOUND: Error: Buffer does not have CTRLVOLUME */ 00516 rc=IDirectSoundBuffer_GetVolume(dsbo,&volume); 00517 ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetVolume() " 00518 "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n", 00519 DXGetErrorString8(rc)); 00520 } 00521 } 00522 00523 if (set_pan) { 00524 if (dsbcaps.dwFlags & DSBCAPS_CTRLPAN) { 00525 LONG val; 00526 rc=IDirectSoundBuffer_GetPan(dsbo,&val); 00527 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan() failed: %s\n", 00528 DXGetErrorString8(rc)); 00529 00530 rc=IDirectSoundBuffer_SetPan(dsbo,pan); 00531 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan() failed: %s\n", 00532 DXGetErrorString8(rc)); 00533 } else { 00534 /* DSOUND: Error: Buffer does not have CTRLPAN */ 00535 rc=IDirectSoundBuffer_GetPan(dsbo,&pan); 00536 ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetPan() " 00537 "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n", 00538 DXGetErrorString8(rc)); 00539 } 00540 } 00541 00542 if (set_frequency) 00543 state.wave=wave_generate_la(&wfx,(duration*frequency)/wfx.nSamplesPerSec,&state.wave_len); 00544 else 00545 state.wave=wave_generate_la(&wfx,duration,&state.wave_len); 00546 00547 state.dsbo=dsbo; 00548 state.wfx=&wfx; 00549 state.buffer_size=dsbcaps.dwBufferBytes; 00550 state.played=state.written=state.offset=0; 00551 buffer_refill(&state,state.buffer_size); 00552 00553 rc=IDirectSoundBuffer_Play(dsbo,0,0,DSBPLAY_LOOPING); 00554 ok(rc==DS_OK,"IDirectSoundBuffer_Play() failed: %s\n", 00555 DXGetErrorString8(rc)); 00556 00557 rc=IDirectSoundBuffer_GetStatus(dsbo,&status); 00558 ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %s\n", 00559 DXGetErrorString8(rc)); 00560 ok(status==(DSBSTATUS_PLAYING|DSBSTATUS_LOOPING), 00561 "GetStatus: bad status: %lx\n",status); 00562 00563 if (listener) { 00564 ZeroMemory(&listener_param,sizeof(listener_param)); 00565 listener_param.dwSize=sizeof(listener_param); 00566 rc=IDirectSound3DListener_GetAllParameters(listener, 00567 &listener_param); 00568 ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters() " 00569 "failed: %s\n",DXGetErrorString8(rc)); 00570 if (move_listener) { 00571 listener_param.vPosition.x = -5.0; 00572 listener_param.vVelocity.x = 10.0/duration; 00573 } 00574 rc=IDirectSound3DListener_SetAllParameters(listener, 00575 &listener_param, 00576 DS3D_IMMEDIATE); 00577 ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: %s\n", 00578 DXGetErrorString8(rc)); 00579 } 00580 if (buffer3d) { 00581 if (move_sound) { 00582 buffer_param.vPosition.x = 100.0; 00583 buffer_param.vVelocity.x = -200.0/duration; 00584 } 00585 buffer_param.flMinDistance = 10; 00586 rc=IDirectSound3DBuffer_SetAllParameters(buffer,&buffer_param, 00587 DS3D_IMMEDIATE); 00588 ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %s\n", 00589 DXGetErrorString8(rc)); 00590 } 00591 00592 start_time=GetTickCount(); 00593 while (buffer_service(&state)) { 00594 WaitForSingleObject(GetCurrentProcess(),TIME_SLICE); 00595 now=GetTickCount(); 00596 if (listener && move_listener) { 00597 listener_param.vPosition.x = -5.0+10.0*(now-start_time)/ 00598 1000/duration; 00599 if (winetest_debug>2) 00600 trace("listener position=%g\n",listener_param.vPosition.x); 00601 rc=IDirectSound3DListener_SetPosition(listener, 00602 listener_param.vPosition.x,listener_param.vPosition.y, 00603 listener_param.vPosition.z,DS3D_IMMEDIATE); 00604 ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: " 00605 "%s\n",DXGetErrorString8(rc)); 00606 } 00607 if (buffer3d && move_sound) { 00608 buffer_param.vPosition.x = 100-200.0*(now-start_time)/ 00609 1000/duration; 00610 if (winetest_debug>2) 00611 trace("sound position=%g\n",buffer_param.vPosition.x); 00612 rc=IDirectSound3DBuffer_SetPosition(buffer, 00613 buffer_param.vPosition.x,buffer_param.vPosition.y, 00614 buffer_param.vPosition.z,DS3D_IMMEDIATE); 00615 ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %s\n", 00616 DXGetErrorString8(rc)); 00617 } 00618 } 00619 /* Check the sound duration was within 10% of the expected value */ 00620 now=GetTickCount(); 00621 ok(fabs(1000*duration-now+start_time)<=100*duration, 00622 "The sound played for %ld ms instead of %g ms\n", 00623 now-start_time,1000*duration); 00624 00625 free(state.wave); 00626 if (is_primary) { 00627 /* Set the CooperativeLevel back to normal */ 00628 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 00629 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 00630 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) " 00631 "failed: %s\n",DXGetErrorString8(rc)); 00632 } 00633 if (buffer3d) { 00634 ref=IDirectSound3DBuffer_Release(buffer); 00635 ok(ref==0,"IDirectSound3DBuffer_Release() has %d references, " 00636 "should have 0\n",ref); 00637 } 00638 } 00639 } 00640 00641 static HRESULT test_secondary(LPGUID lpGuid, int play, 00642 int has_3d, int has_3dbuffer, 00643 int has_listener, int has_duplicate, 00644 int move_listener, int move_sound) 00645 { 00646 HRESULT rc; 00647 LPDIRECTSOUND dso=NULL; 00648 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL; 00649 LPDIRECTSOUND3DLISTENER listener=NULL; 00650 DSBUFFERDESC bufdesc; 00651 WAVEFORMATEX wfx, wfx1; 00652 int ref; 00653 00654 /* Create the DirectSound object */ 00655 rc=DirectSoundCreate(lpGuid,&dso,NULL); 00656 ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n", 00657 DXGetErrorString8(rc)); 00658 if (rc!=DS_OK) 00659 return rc; 00660 00661 /* We must call SetCooperativeLevel before creating primary buffer */ 00662 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 00663 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 00664 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: " 00665 "%s\n",DXGetErrorString8(rc)); 00666 if (rc!=DS_OK) 00667 goto EXIT; 00668 00669 ZeroMemory(&bufdesc, sizeof(bufdesc)); 00670 bufdesc.dwSize=sizeof(bufdesc); 00671 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; 00672 if (has_3d) 00673 bufdesc.dwFlags|=DSBCAPS_CTRL3D; 00674 else 00675 bufdesc.dwFlags|=(DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN); 00676 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 00677 ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL), 00678 "IDirectSound_CreateSoundBuffer() failed to create a %sprimary buffer: " 00679 "%s\n",has_3d?"3D ":"", DXGetErrorString8(rc)); 00680 if (rc==DSERR_CONTROLUNAVAIL) 00681 trace(" No Primary\n"); 00682 else if (rc==DS_OK && primary!=NULL) { 00683 rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL); 00684 ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n", 00685 DXGetErrorString8(rc)); 00686 if (rc!=DS_OK) 00687 goto EXIT1; 00688 00689 if (has_listener) { 00690 rc=IDirectSoundBuffer_QueryInterface(primary, 00691 &IID_IDirectSound3DListener, 00692 (void **)&listener); 00693 ok(rc==DS_OK && listener!=NULL, 00694 "IDirectSoundBuffer_QueryInterface() failed to get a 3D " 00695 "listener: %s\n",DXGetErrorString8(rc)); 00696 ref=IDirectSoundBuffer_Release(primary); 00697 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 00698 "should have 0\n",ref); 00699 if (rc==DS_OK && listener!=NULL) { 00700 DS3DLISTENER listener_param; 00701 ZeroMemory(&listener_param,sizeof(listener_param)); 00702 /* DSOUND: Error: Invalid buffer */ 00703 rc=IDirectSound3DListener_GetAllParameters(listener,0); 00704 ok(rc==DSERR_INVALIDPARAM, 00705 "IDirectSound3dListener_GetAllParameters() should have " 00706 "returned DSERR_INVALIDPARAM, returned: %s\n", 00707 DXGetErrorString8(rc)); 00708 00709 /* DSOUND: Error: Invalid buffer */ 00710 rc=IDirectSound3DListener_GetAllParameters(listener, 00711 &listener_param); 00712 ok(rc==DSERR_INVALIDPARAM, 00713 "IDirectSound3dListener_GetAllParameters() should have " 00714 "returned DSERR_INVALIDPARAM, returned: %s\n", 00715 DXGetErrorString8(rc)); 00716 00717 listener_param.dwSize=sizeof(listener_param); 00718 rc=IDirectSound3DListener_GetAllParameters(listener, 00719 &listener_param); 00720 ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters() " 00721 "failed: %s\n",DXGetErrorString8(rc)); 00722 } 00723 else 00724 goto EXIT; 00725 } 00726 00727 init_format(&wfx,WAVE_FORMAT_PCM,22050,16,2); 00728 secondary=NULL; 00729 ZeroMemory(&bufdesc, sizeof(bufdesc)); 00730 bufdesc.dwSize=sizeof(bufdesc); 00731 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; 00732 if (has_3d) 00733 bufdesc.dwFlags|=DSBCAPS_CTRL3D; 00734 else 00735 bufdesc.dwFlags|= 00736 (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN); 00737 bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, 00738 wfx.nBlockAlign); 00739 bufdesc.lpwfxFormat=&wfx; 00740 if (winetest_interactive) { 00741 trace(" Testing a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d " 00742 "with a primary buffer at %ldx%dx%d\n", 00743 has_3dbuffer?"3D ":"", 00744 has_duplicate?"duplicated ":"", 00745 listener!=NULL||move_sound?"with ":"", 00746 move_listener?"moving ":"", 00747 listener!=NULL?"listener ":"", 00748 listener&&move_sound?"and moving sound ":move_sound? 00749 "moving sound ":"", 00750 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels, 00751 wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels); 00752 } 00753 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); 00754 ok(rc==DS_OK && secondary!=NULL,"IDirectSound_CreateSoundBuffer() " 00755 "failed to create a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d (%s): %s\n", 00756 has_3dbuffer?"3D ":"", has_duplicate?"duplicated ":"", 00757 listener!=NULL||move_sound?"with ":"", move_listener?"moving ":"", 00758 listener!=NULL?"listener ":"", 00759 listener&&move_sound?"and moving sound ":move_sound? 00760 "moving sound ":"", 00761 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels, 00762 getDSBCAPS(bufdesc.dwFlags),DXGetErrorString8(rc)); 00763 if (rc==DS_OK && secondary!=NULL) { 00764 if (!has_3d) { 00765 LONG refvol,vol,refpan,pan; 00766 00767 /* Check the initial secondary buffer's volume and pan */ 00768 rc=IDirectSoundBuffer_GetVolume(secondary,&vol); 00769 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(secondary) failed: " 00770 "%s\n",DXGetErrorString8(rc)); 00771 ok(vol==0,"wrong volume for a new secondary buffer: %ld\n",vol); 00772 rc=IDirectSoundBuffer_GetPan(secondary,&pan); 00773 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(secondary) failed: " 00774 "%s\n",DXGetErrorString8(rc)); 00775 ok(pan==0,"wrong pan for a new secondary buffer: %ld\n",pan); 00776 00777 /* Check that changing the secondary buffer's volume and pan 00778 * does not impact the primary buffer's volume and pan 00779 */ 00780 rc=IDirectSoundBuffer_GetVolume(primary,&refvol); 00781 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(primary) failed: " 00782 "%s\n",DXGetErrorString8(rc)); 00783 rc=IDirectSoundBuffer_GetPan(primary,&refpan); 00784 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: %s\n", 00785 DXGetErrorString8(rc)); 00786 00787 rc=IDirectSoundBuffer_SetVolume(secondary,-1000); 00788 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: " 00789 "%s\n",DXGetErrorString8(rc)); 00790 rc=IDirectSoundBuffer_GetVolume(secondary,&vol); 00791 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: " 00792 "%s\n",DXGetErrorString8(rc)); 00793 ok(vol==-1000,"secondary: wrong volume %ld instead of -1000\n", 00794 vol); 00795 rc=IDirectSoundBuffer_SetPan(secondary,-1000); 00796 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: " 00797 "%s\n",DXGetErrorString8(rc)); 00798 rc=IDirectSoundBuffer_GetPan(secondary,&pan); 00799 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: " 00800 "%s\n",DXGetErrorString8(rc)); 00801 ok(pan==-1000,"secondary: wrong pan %ld instead of -1000\n", 00802 pan); 00803 00804 rc=IDirectSoundBuffer_GetVolume(primary,&vol); 00805 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(primary) failed: " 00806 "%s\n",DXGetErrorString8(rc)); 00807 ok(vol==refvol,"The primary volume changed from %ld to %ld\n", 00808 refvol,vol); 00809 rc=IDirectSoundBuffer_GetPan(primary,&pan); 00810 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: %s\n", 00811 DXGetErrorString8(rc)); 00812 ok(pan==refpan,"The primary pan changed from %ld to %ld\n", 00813 refpan,pan); 00814 00815 rc=IDirectSoundBuffer_SetVolume(secondary,0); 00816 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: " 00817 "%s\n",DXGetErrorString8(rc)); 00818 rc=IDirectSoundBuffer_SetPan(secondary,0); 00819 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: " 00820 "%s\n",DXGetErrorString8(rc)); 00821 } 00822 if (has_duplicate) { 00823 LPDIRECTSOUNDBUFFER duplicated=NULL; 00824 00825 /* DSOUND: Error: Invalid source buffer */ 00826 rc=IDirectSound_DuplicateSoundBuffer(dso,0,0); 00827 ok(rc==DSERR_INVALIDPARAM, 00828 "IDirectSound_DuplicateSoundBuffer() should have returned " 00829 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); 00830 00831 /* DSOUND: Error: Invalid dest buffer */ 00832 rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,0); 00833 ok(rc==DSERR_INVALIDPARAM, 00834 "IDirectSound_DuplicateSoundBuffer() should have returned " 00835 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); 00836 00837 /* DSOUND: Error: Invalid source buffer */ 00838 rc=IDirectSound_DuplicateSoundBuffer(dso,0,&duplicated); 00839 ok(rc==DSERR_INVALIDPARAM, 00840 "IDirectSound_DuplicateSoundBuffer() should have returned " 00841 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc)); 00842 00843 duplicated=NULL; 00844 rc=IDirectSound_DuplicateSoundBuffer(dso,secondary, 00845 &duplicated); 00846 ok(rc==DS_OK && duplicated!=NULL, 00847 "IDirectSound_DuplicateSoundBuffer() failed to duplicate " 00848 "a secondary buffer: %s\n",DXGetErrorString8(rc)); 00849 00850 if (rc==DS_OK && duplicated!=NULL) { 00851 ref=IDirectSoundBuffer_Release(secondary); 00852 ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d " 00853 "references, should have 0\n",ref); 00854 secondary=duplicated; 00855 } 00856 } 00857 00858 if (rc==DS_OK && secondary!=NULL) { 00859 double duration; 00860 duration=(move_listener || move_sound?4.0:1.0); 00861 test_buffer(dso,secondary,0,FALSE,0,FALSE,0, 00862 winetest_interactive,duration,has_3dbuffer, 00863 listener,move_listener,move_sound,FALSE,0); 00864 ref=IDirectSoundBuffer_Release(secondary); 00865 ok(ref==0,"IDirectSoundBuffer_Release() %s has %d references, " 00866 "should have 0\n",has_duplicate?"duplicated":"secondary", 00867 ref); 00868 } 00869 } 00870 } 00871 EXIT1: 00872 if (has_listener) { 00873 ref=IDirectSound3DListener_Release(listener); 00874 ok(ref==0,"IDirectSound3dListener_Release() listener has %d " 00875 "references, should have 0\n",ref); 00876 } else { 00877 ref=IDirectSoundBuffer_Release(primary); 00878 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 00879 "should have 0\n",ref); 00880 } 00881 00882 /* Set the CooperativeLevel back to normal */ 00883 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 00884 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 00885 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n", 00886 DXGetErrorString8(rc)); 00887 00888 EXIT: 00889 ref=IDirectSound_Release(dso); 00890 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 00891 if (ref!=0) 00892 return DSERR_GENERIC; 00893 00894 return rc; 00895 } 00896 00897 static HRESULT test_for_driver(LPGUID lpGuid) 00898 { 00899 HRESULT rc; 00900 LPDIRECTSOUND dso=NULL; 00901 int ref; 00902 00903 /* Create the DirectSound object */ 00904 rc=DirectSoundCreate(lpGuid,&dso,NULL); 00905 ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, 00906 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc)); 00907 if (rc!=DS_OK) 00908 return rc; 00909 00910 ref=IDirectSound_Release(dso); 00911 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 00912 if (ref!=0) 00913 return DSERR_GENERIC; 00914 00915 return rc; 00916 } 00917 00918 static HRESULT test_primary(LPGUID lpGuid) 00919 { 00920 HRESULT rc; 00921 LPDIRECTSOUND dso=NULL; 00922 LPDIRECTSOUNDBUFFER primary=NULL; 00923 DSBUFFERDESC bufdesc; 00924 DSCAPS dscaps; 00925 int ref, i; 00926 00927 /* Create the DirectSound object */ 00928 rc=DirectSoundCreate(lpGuid,&dso,NULL); 00929 ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n", 00930 DXGetErrorString8(rc)); 00931 if (rc!=DS_OK) 00932 return rc; 00933 00934 /* Get the device capabilities */ 00935 ZeroMemory(&dscaps, sizeof(dscaps)); 00936 dscaps.dwSize=sizeof(dscaps); 00937 rc=IDirectSound_GetCaps(dso,&dscaps); 00938 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc)); 00939 if (rc!=DS_OK) 00940 goto EXIT; 00941 00942 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */ 00943 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 00944 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 00945 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: " 00946 "%s\n",DXGetErrorString8(rc)); 00947 if (rc!=DS_OK) 00948 goto EXIT; 00949 00950 /* Testing the primary buffer */ 00951 primary=NULL; 00952 ZeroMemory(&bufdesc, sizeof(bufdesc)); 00953 bufdesc.dwSize=sizeof(bufdesc); 00954 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN; 00955 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 00956 ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL), 00957 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: " 00958 "%s\n",DXGetErrorString8(rc)); 00959 if (rc==DSERR_CONTROLUNAVAIL) 00960 trace(" No Primary\n"); 00961 else if (rc==DS_OK && primary!=NULL) { 00962 test_buffer(dso,primary,1,TRUE,0,TRUE,0,winetest_interactive && 00963 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,NULL,0,0, 00964 FALSE,0); 00965 if (winetest_interactive) { 00966 LONG volume,pan; 00967 00968 volume = DSBVOLUME_MAX; 00969 for (i = 0; i < 6; i++) { 00970 test_buffer(dso,primary,1,TRUE,volume,TRUE,0, 00971 winetest_interactive && 00972 !(dscaps.dwFlags & DSCAPS_EMULDRIVER), 00973 1.0,0,NULL,0,0,FALSE,0); 00974 volume -= ((DSBVOLUME_MAX-DSBVOLUME_MIN) / 40); 00975 } 00976 00977 pan = DSBPAN_LEFT; 00978 for (i = 0; i < 7; i++) { 00979 test_buffer(dso,primary,1,TRUE,0,TRUE,pan, 00980 winetest_interactive && 00981 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0,FALSE,0); 00982 pan += ((DSBPAN_RIGHT-DSBPAN_LEFT) / 6); 00983 } 00984 } 00985 ref=IDirectSoundBuffer_Release(primary); 00986 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 00987 "should have 0\n",ref); 00988 } 00989 00990 /* Set the CooperativeLevel back to normal */ 00991 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 00992 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 00993 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n", 00994 DXGetErrorString8(rc)); 00995 00996 EXIT: 00997 ref=IDirectSound_Release(dso); 00998 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 00999 if (ref!=0) 01000 return DSERR_GENERIC; 01001 01002 return rc; 01003 } 01004 01005 static HRESULT test_primary_3d(LPGUID lpGuid) 01006 { 01007 HRESULT rc; 01008 LPDIRECTSOUND dso=NULL; 01009 LPDIRECTSOUNDBUFFER primary=NULL; 01010 DSBUFFERDESC bufdesc; 01011 DSCAPS dscaps; 01012 int ref; 01013 01014 /* Create the DirectSound object */ 01015 rc=DirectSoundCreate(lpGuid,&dso,NULL); 01016 ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n", 01017 DXGetErrorString8(rc)); 01018 if (rc!=DS_OK) 01019 return rc; 01020 01021 /* Get the device capabilities */ 01022 ZeroMemory(&dscaps, sizeof(dscaps)); 01023 dscaps.dwSize=sizeof(dscaps); 01024 rc=IDirectSound_GetCaps(dso,&dscaps); 01025 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc)); 01026 if (rc!=DS_OK) 01027 goto EXIT; 01028 01029 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */ 01030 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 01031 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 01032 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: " 01033 "%s\n",DXGetErrorString8(rc)); 01034 if (rc!=DS_OK) 01035 goto EXIT; 01036 01037 primary=NULL; 01038 ZeroMemory(&bufdesc, sizeof(bufdesc)); 01039 bufdesc.dwSize=sizeof(bufdesc); 01040 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; 01041 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 01042 ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() failed " 01043 "to create a primary buffer: %s\n",DXGetErrorString8(rc)); 01044 if (rc==DS_OK && primary!=NULL) { 01045 ref=IDirectSoundBuffer_Release(primary); 01046 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 01047 "should have 0\n",ref); 01048 primary=NULL; 01049 ZeroMemory(&bufdesc, sizeof(bufdesc)); 01050 bufdesc.dwSize=sizeof(bufdesc); 01051 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D; 01052 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 01053 ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() " 01054 "failed to create a 3D primary buffer: %s\n",DXGetErrorString8(rc)); 01055 if (rc==DS_OK && primary!=NULL) { 01056 test_buffer(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive && 01057 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0, 01058 FALSE,0); 01059 ref=IDirectSoundBuffer_Release(primary); 01060 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 01061 "should have 0\n",ref); 01062 } 01063 } 01064 /* Set the CooperativeLevel back to normal */ 01065 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ 01066 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); 01067 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n", 01068 DXGetErrorString8(rc)); 01069 01070 EXIT: 01071 ref=IDirectSound_Release(dso); 01072 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 01073 if (ref!=0) 01074 return DSERR_GENERIC; 01075 01076 return rc; 01077 } 01078 01079 static HRESULT test_primary_3d_with_listener(LPGUID lpGuid) 01080 { 01081 HRESULT rc; 01082 LPDIRECTSOUND dso=NULL; 01083 LPDIRECTSOUNDBUFFER primary=NULL; 01084 DSBUFFERDESC bufdesc; 01085 DSCAPS dscaps; 01086 int ref; 01087 01088 /* Create the DirectSound object */ 01089 rc=DirectSoundCreate(lpGuid,&dso,NULL); 01090 ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n", 01091 DXGetErrorString8(rc)); 01092 if (rc!=DS_OK) 01093 return rc; 01094 01095 /* Get the device capabilities */ 01096 ZeroMemory(&dscaps, sizeof(dscaps)); 01097 dscaps.dwSize=sizeof(dscaps); 01098 rc=IDirectSound_GetCaps(dso,&dscaps); 01099 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc)); 01100 if (rc!=DS_OK) 01101 goto EXIT; 01102 01103 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */ 01104 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ 01105 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); 01106 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: " 01107 "%s\n",DXGetErrorString8(rc)); 01108 if (rc!=DS_OK) 01109 goto EXIT; 01110 primary=NULL; 01111 ZeroMemory(&bufdesc, sizeof(bufdesc)); 01112 bufdesc.dwSize=sizeof(bufdesc); 01113 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D; 01114 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); 01115 ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() failed " 01116 "to create a 3D primary buffer: %s\n",DXGetErrorString8(rc)); 01117 if (rc==DS_OK && primary!=NULL) { 01118 LPDIRECTSOUND3DLISTENER listener=NULL; 01119 rc=IDirectSoundBuffer_QueryInterface(primary, 01120 &IID_IDirectSound3DListener,(void **)&listener); 01121 ok(rc==DS_OK && listener!=NULL,"IDirectSoundBuffer_QueryInterface() " 01122 "failed to get a 3D listener: %s\n",DXGetErrorString8(rc)); 01123 if (rc==DS_OK && listener!=NULL) { 01124 LPDIRECTSOUNDBUFFER temp_buffer=NULL; 01125 01126 /* Checking the COM interface */ 01127 rc=IDirectSoundBuffer_QueryInterface(primary, 01128 &IID_IDirectSoundBuffer,(LPVOID *)&temp_buffer); 01129 ok(rc==DS_OK && temp_buffer!=NULL, 01130 "IDirectSoundBuffer_QueryInterface() failed: %s\n", 01131 DXGetErrorString8(rc)); 01132 ok(temp_buffer==primary, 01133 "COM interface broken: %p != %p\n", 01134 temp_buffer,primary); 01135 if (rc==DS_OK && temp_buffer!=NULL) { 01136 ref=IDirectSoundBuffer_Release(temp_buffer); 01137 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " 01138 "should have 1\n",ref); 01139 01140 temp_buffer=NULL; 01141 rc=IDirectSound3DListener_QueryInterface(listener, 01142 &IID_IDirectSoundBuffer,(LPVOID *)&temp_buffer); 01143 ok(rc==DS_OK && temp_buffer!=NULL, 01144 "IDirectSoundBuffer_QueryInterface() failed: %s\n", 01145 DXGetErrorString8(rc)); 01146 ok(temp_buffer==primary, 01147 "COM interface broken: %p != %p\n", 01148 temp_buffer,primary); 01149 ref=IDirectSoundBuffer_Release(temp_buffer); 01150 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, " 01151 "should have 1\n",ref); 01152 01153 /* Testing the buffer */ 01154 test_buffer(dso,primary,1,FALSE,0,FALSE,0, 01155 winetest_interactive && 01156 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0, 01157 listener,0,0,FALSE,0); 01158 } 01159 01160 /* Testing the reference counting */ 01161 ref=IDirectSound3DListener_Release(listener); 01162 ok(ref==0,"IDirectSound3DListener_Release() listener has %d " 01163 "references, should have 0\n",ref); 01164 } 01165 01166 /* Testing the reference counting */ 01167 ref=IDirectSoundBuffer_Release(primary); 01168 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " 01169 "should have 0\n",ref); 01170 } 01171 01172 EXIT: 01173 ref=IDirectSound_Release(dso); 01174 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); 01175 if (ref!=0) 01176 return DSERR_GENERIC; 01177 01178 return rc; 01179 } 01180 01181 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription, 01182 LPCSTR lpcstrModule, LPVOID lpContext) 01183 { 01184 HRESULT rc; 01185 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule); 01186 01187 rc = test_for_driver(lpGuid); 01188 if (rc == DSERR_NODRIVER) { 01189 trace(" No Driver\n"); 01190 return 1; 01191 } else if (rc == DSERR_ALLOCATED) { 01192 trace(" Already In Use\n"); 01193 return 1; 01194 } else if (rc == E_FAIL) { 01195 trace(" No Device\n"); 01196 return 1; 01197 } 01198 01199 trace(" Testing the primary buffer\n"); 01200 test_primary(lpGuid); 01201 01202 trace(" Testing 3D primary buffer\n"); 01203 test_primary_3d(lpGuid); 01204 01205 trace(" Testing 3D primary buffer with listener\n"); 01206 test_primary_3d_with_listener(lpGuid); 01207 01208 /* Testing secondary buffers */ 01209 test_secondary(lpGuid,winetest_interactive,0,0,0,0,0,0); 01210 test_secondary(lpGuid,winetest_interactive,0,0,0,1,0,0); 01211 01212 /* Testing 3D secondary buffers */ 01213 test_secondary(lpGuid,winetest_interactive,1,0,0,0,0,0); 01214 test_secondary(lpGuid,winetest_interactive,1,1,0,0,0,0); 01215 test_secondary(lpGuid,winetest_interactive,1,1,0,1,0,0); 01216 test_secondary(lpGuid,winetest_interactive,1,0,1,0,0,0); 01217 test_secondary(lpGuid,winetest_interactive,1,0,1,1,0,0); 01218 test_secondary(lpGuid,winetest_interactive,1,1,1,0,0,0); 01219 test_secondary(lpGuid,winetest_interactive,1,1,1,1,0,0); 01220 test_secondary(lpGuid,winetest_interactive,1,1,1,0,1,0); 01221 test_secondary(lpGuid,winetest_interactive,1,1,1,0,0,1); 01222 test_secondary(lpGuid,winetest_interactive,1,1,1,0,1,1); 01223 01224 return 1; 01225 } 01226 01227 static void ds3d_tests(void) 01228 { 01229 HRESULT rc; 01230 rc=DirectSoundEnumerateA(&dsenum_callback,NULL); 01231 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc)); 01232 } 01233 01234 START_TEST(ds3d) 01235 { 01236 CoInitialize(NULL); 01237 01238 trace("DLL Version: %s\n", get_file_version("dsound.dll")); 01239 01240 ds3d_tests(); 01241 01242 CoUninitialize(); 01243 } Generated on Sun May 27 2012 04:21:42 for ReactOS by
1.7.6.1
|