Only print format info when in interactive mode for capture test.
[wine/multimedia.git] / dlls / dsound / tests / ds3d.c
blob896209dd6d7dbd807e5cc063c5c41be2c22de3db
1 /*
2 * Tests the panning and 3D functions of DirectSound
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.
9 * Copyright (c) 2002-2004 Francois Gouget
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #define NONAMELESSSTRUCT
27 #define NONAMELESSUNION
28 #include <windows.h>
30 #include <math.h>
31 #include <stdlib.h>
33 #include "wine/test.h"
34 #include "windef.h"
35 #include "wingdi.h"
36 #include "dsound.h"
37 #include "dxerr8.h"
39 #include "dsound_test.h"
41 #define PI 3.14159265358979323846
42 char* wave_generate_la(WAVEFORMATEX* wfx, double duration, DWORD* size)
44 int i;
45 int nb_samples;
46 char* buf;
47 char* b;
49 nb_samples=(int)(duration*wfx->nSamplesPerSec);
50 *size=nb_samples*wfx->nBlockAlign;
51 b=buf=malloc(*size);
52 for (i=0;i<nb_samples;i++) {
53 double y=sin(440.0*2*PI*i/wfx->nSamplesPerSec);
54 if (wfx->wBitsPerSample==8) {
55 unsigned char sample=(unsigned char)((double)127.5*(y+1.0));
56 *b++=sample;
57 if (wfx->nChannels==2)
58 *b++=sample;
59 } else {
60 signed short sample=(signed short)((double)32767.5*y-0.5);
61 b[0]=sample & 0xff;
62 b[1]=sample >> 8;
63 b+=2;
64 if (wfx->nChannels==2) {
65 b[0]=sample & 0xff;
66 b[1]=sample >> 8;
67 b+=2;
71 return buf;
74 HWND get_hwnd()
76 HWND hwnd=GetForegroundWindow();
77 if (!hwnd)
78 hwnd=GetDesktopWindow();
79 return hwnd;
82 void init_format(WAVEFORMATEX* wfx, int format, int rate, int depth,
83 int channels)
85 wfx->wFormatTag=format;
86 wfx->nChannels=channels;
87 wfx->wBitsPerSample=depth;
88 wfx->nSamplesPerSec=rate;
89 wfx->nBlockAlign=wfx->nChannels*wfx->wBitsPerSample/8;
90 /* FIXME: Shouldn't this test be if (format!=WAVE_FORMAT_PCM) */
91 if (wfx->nBlockAlign==0)
93 /* align compressed formats to byte boundary */
94 wfx->nBlockAlign=1;
96 wfx->nAvgBytesPerSec=wfx->nSamplesPerSec*wfx->nBlockAlign;
97 wfx->cbSize=0;
100 typedef struct {
101 char* wave;
102 DWORD wave_len;
104 LPDIRECTSOUNDBUFFER dsbo;
105 LPWAVEFORMATEX wfx;
106 DWORD buffer_size;
107 DWORD written;
108 DWORD played;
109 DWORD offset;
110 } play_state_t;
112 static int buffer_refill(play_state_t* state, DWORD size)
114 LPVOID ptr1,ptr2;
115 DWORD len1,len2;
116 HRESULT rc;
118 if (size>state->wave_len-state->written)
119 size=state->wave_len-state->written;
121 rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size,
122 &ptr1,&len1,&ptr2,&len2,0);
123 ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n",
124 DXGetErrorString8(rc));
125 if (rc!=DS_OK)
126 return -1;
128 memcpy(ptr1,state->wave+state->written,len1);
129 state->written+=len1;
130 if (ptr2!=NULL) {
131 memcpy(ptr2,state->wave+state->written,len2);
132 state->written+=len2;
134 state->offset=state->written % state->buffer_size;
135 rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2);
136 ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n",
137 DXGetErrorString8(rc));
138 if (rc!=DS_OK)
139 return -1;
140 return size;
143 static int buffer_silence(play_state_t* state, DWORD size)
145 LPVOID ptr1,ptr2;
146 DWORD len1,len2;
147 HRESULT rc;
148 BYTE s;
150 rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size,
151 &ptr1,&len1,&ptr2,&len2,0);
152 ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n",
153 DXGetErrorString8(rc));
154 if (rc!=DS_OK)
155 return -1;
157 s=(state->wfx->wBitsPerSample==8?0x80:0);
158 memset(ptr1,s,len1);
159 if (ptr2!=NULL) {
160 memset(ptr2,s,len2);
162 state->offset=(state->offset+size) % state->buffer_size;
163 rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2);
164 ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n",
165 DXGetErrorString8(rc));
166 if (rc!=DS_OK)
167 return -1;
168 return size;
171 static int buffer_service(play_state_t* state)
173 DWORD last_play_pos,play_pos,buf_free;
174 HRESULT rc;
176 rc=IDirectSoundBuffer_GetCurrentPosition(state->dsbo,&play_pos,NULL);
177 ok(rc==DS_OK,"IDirectSoundBuffer_GetCurrentPosition() failed: %s\n",
178 DXGetErrorString8(rc));
179 if (rc!=DS_OK) {
180 goto STOP;
183 /* Update the amount played */
184 last_play_pos=state->played % state->buffer_size;
185 if (play_pos<last_play_pos)
186 state->played+=state->buffer_size-last_play_pos+play_pos;
187 else
188 state->played+=play_pos-last_play_pos;
190 if (winetest_debug > 1)
191 trace("buf size=%ld last_play_pos=%ld play_pos=%ld played=%ld / %ld\n",
192 state->buffer_size,last_play_pos,play_pos,state->played,
193 state->wave_len);
195 if (state->played>state->wave_len)
197 /* Everything has been played */
198 goto STOP;
201 /* Refill the buffer */
202 if (state->offset<=play_pos)
203 buf_free=play_pos-state->offset;
204 else
205 buf_free=state->buffer_size-state->offset+play_pos;
207 if (winetest_debug > 1)
208 trace("offset=%ld free=%ld written=%ld / %ld\n",
209 state->offset,buf_free,state->written,state->wave_len);
210 if (buf_free==0)
211 return 1;
213 if (state->written<state->wave_len)
215 int w=buffer_refill(state,buf_free);
216 if (w==-1)
217 goto STOP;
218 buf_free-=w;
219 if (state->written==state->wave_len && winetest_debug > 1)
220 trace("last sound byte at %ld\n",
221 (state->written % state->buffer_size));
224 if (buf_free>0) {
225 /* Fill with silence */
226 if (winetest_debug > 1)
227 trace("writing %ld bytes of silence\n",buf_free);
228 if (buffer_silence(state,buf_free)==-1)
229 goto STOP;
231 return 1;
233 STOP:
234 if (winetest_debug > 1)
235 trace("stopping playback\n");
236 rc=IDirectSoundBuffer_Stop(state->dsbo);
237 ok(rc==DS_OK,"IDirectSoundBuffer_Stop() failed: %s\n",
238 DXGetErrorString8(rc));
239 return 0;
242 void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
243 BOOL is_primary, BOOL set_volume, LONG volume,
244 BOOL set_pan, LONG pan, BOOL play, double duration,
245 BOOL buffer3d, LPDIRECTSOUND3DLISTENER listener,
246 BOOL move_listener, BOOL move_sound)
248 HRESULT rc;
249 DSBCAPS dsbcaps;
250 WAVEFORMATEX wfx,wfx2;
251 DWORD size,status,freq;
252 int ref;
254 /* DSOUND: Error: Invalid caps pointer */
255 rc=IDirectSoundBuffer_GetCaps(dsbo,0);
256 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have "
257 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
259 ZeroMemory(&dsbcaps, sizeof(dsbcaps));
261 /* DSOUND: Error: Invalid caps pointer */
262 rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps);
263 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have "
264 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
266 dsbcaps.dwSize=sizeof(dsbcaps);
267 rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps);
268 ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() failed: %s\n",
269 DXGetErrorString8(rc));
270 if (rc==DS_OK && winetest_debug > 1) {
271 trace(" Caps: flags=0x%08lx size=%ld\n",dsbcaps.dwFlags,
272 dsbcaps.dwBufferBytes);
275 /* Query the format size. Note that it may not match sizeof(wfx) */
276 size=0;
277 rc=IDirectSoundBuffer_GetFormat(dsbo,NULL,0,&size);
278 ok(rc==DS_OK && size!=0,"IDirectSoundBuffer_GetFormat() should have "
279 "returned the needed size: rc=%s size=%ld\n",DXGetErrorString8(rc),size);
281 rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL);
282 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
283 DXGetErrorString8(rc));
284 if (rc==DS_OK && winetest_debug > 1) {
285 trace(" Format: %s tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
286 is_primary ? "Primary" : "Secondary",
287 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
288 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
291 /* DSOUND: Error: Invalid frequency buffer */
292 rc=IDirectSoundBuffer_GetFrequency(dsbo,0);
293 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetFrequency() should have "
294 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
296 /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */
297 rc=IDirectSoundBuffer_GetFrequency(dsbo,&freq);
298 ok((rc==DS_OK && !is_primary) || (rc==DSERR_CONTROLUNAVAIL&&is_primary) ||
299 (rc==DSERR_CONTROLUNAVAIL&&!(dsbcaps.dwFlags&DSBCAPS_CTRLFREQUENCY)),
300 "IDirectSoundBuffer_GetFrequency() failed: %s\n",DXGetErrorString8(rc));
301 if (rc==DS_OK) {
302 ok(freq==wfx.nSamplesPerSec,"The frequency returned by GetFrequency "
303 "%ld does not match the format %ld\n",freq,wfx.nSamplesPerSec);
306 /* DSOUND: Error: Invalid status pointer */
307 rc=IDirectSoundBuffer_GetStatus(dsbo,0);
308 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetStatus() should have "
309 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
311 rc=IDirectSoundBuffer_GetStatus(dsbo,&status);
312 ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %s\n",
313 DXGetErrorString8(rc));
314 ok(status==0,"status=0x%lx instead of 0\n",status);
316 if (is_primary) {
317 /* We must call SetCooperativeLevel to be allowed to call SetFormat */
318 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
319 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
320 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
321 "%s\n",DXGetErrorString8(rc));
322 if (rc!=DS_OK)
323 return;
325 /* DSOUND: Error: Invalid format pointer */
326 rc=IDirectSoundBuffer_SetFormat(dsbo,0);
327 ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_SetFormat() should have "
328 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
330 init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
331 rc=IDirectSoundBuffer_SetFormat(dsbo,&wfx2);
332 ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
333 DXGetErrorString8(rc));
335 /* There is no garantee that SetFormat will actually change the
336 * format to what we asked for. It depends on what the soundcard
337 * supports. So we must re-query the format.
339 rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL);
340 ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
341 DXGetErrorString8(rc));
342 if (rc==DS_OK &&
343 (wfx.wFormatTag!=wfx2.wFormatTag ||
344 wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
345 wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
346 wfx.nChannels!=wfx2.nChannels)) {
347 trace("Requested format tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
348 wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
349 wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
350 trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
351 wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
352 wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
355 /* Set the CooperativeLevel back to normal */
356 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
357 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
358 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: "
359 "%s\n",DXGetErrorString8(rc));
362 if (play) {
363 play_state_t state;
364 DS3DLISTENER listener_param;
365 LPDIRECTSOUND3DBUFFER buffer=NULL;
366 DS3DBUFFER buffer_param;
367 DWORD start_time,now;
369 if (winetest_interactive) {
370 trace(" Playing %g second 440Hz tone at %ldx%dx%d\n", duration,
371 wfx.nSamplesPerSec, wfx.wBitsPerSample,wfx.nChannels);
374 if (is_primary) {
375 /* We must call SetCooperativeLevel to be allowed to call Lock */
376 /* DSOUND: Setting DirectSound cooperative level to
377 * DSSCL_WRITEPRIMARY */
378 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),
379 DSSCL_WRITEPRIMARY);
380 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_WRITEPRIMARY) "
381 "failed: %s\n",DXGetErrorString8(rc));
382 if (rc!=DS_OK)
383 return;
385 if (buffer3d) {
386 LPDIRECTSOUNDBUFFER temp_buffer;
388 rc=IDirectSoundBuffer_QueryInterface(dsbo,&IID_IDirectSound3DBuffer,
389 (LPVOID *)&buffer);
390 ok(rc==DS_OK,"IDirectSoundBuffer_QueryInterface() failed: %s\n",
391 DXGetErrorString8(rc));
392 if (rc!=DS_OK)
393 return;
395 /* check the COM interface */
396 rc=IDirectSoundBuffer_QueryInterface(dsbo, &IID_IDirectSoundBuffer,
397 (LPVOID *)&temp_buffer);
398 ok(rc==DS_OK && temp_buffer!=NULL,
399 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
400 DXGetErrorString8(rc));
401 ok(temp_buffer==dsbo,"COM interface broken: 0x%08lx != 0x%08lx\n",
402 (DWORD)temp_buffer,(DWORD)dsbo);
403 ref=IDirectSoundBuffer_Release(temp_buffer);
404 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, "
405 "should have 1\n",ref);
407 temp_buffer=NULL;
408 rc=IDirectSound3DBuffer_QueryInterface(dsbo,
409 &IID_IDirectSoundBuffer,
410 (LPVOID *)&temp_buffer);
411 ok(rc==DS_OK && temp_buffer!=NULL,
412 "IDirectSound3DBuffer_QueryInterface() failed: %s\n",
413 DXGetErrorString8(rc));
414 ok(temp_buffer==dsbo,"COM interface broken: 0x%08lx != 0x%08lx\n",
415 (DWORD)temp_buffer,(DWORD)dsbo);
416 ref=IDirectSoundBuffer_Release(temp_buffer);
417 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, "
418 "should have 1\n",ref);
420 #if 0
421 /* FIXME: this works on windows */
422 ref=IDirectSoundBuffer_Release(dsbo);
423 ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
424 "should have 0\n",ref);
426 rc=IDirectSound3DBuffer_QueryInterface(buffer,
427 &IID_IDirectSoundBuffer,
428 (LPVOID *)&dsbo);
429 ok(rc==DS_OK && dsbo!=NULL,"IDirectSound3DBuffer_QueryInterface() "
430 "failed: %s\n",DXGetErrorString8(rc));
431 #endif
433 /* DSOUND: Error: Invalid buffer */
434 rc=IDirectSound3DBuffer_GetAllParameters(buffer,0);
435 ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() "
436 "failed: %s\n",DXGetErrorString8(rc));
438 ZeroMemory(&buffer_param, sizeof(buffer_param));
440 /* DSOUND: Error: Invalid buffer */
441 rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param);
442 ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() "
443 "failed: %s\n",DXGetErrorString8(rc));
445 buffer_param.dwSize=sizeof(buffer_param);
446 rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param);
447 ok(rc==DS_OK,"IDirectSound3DBuffer_GetAllParameters() failed: %s\n",
448 DXGetErrorString8(rc));
450 if (set_volume) {
451 if (dsbcaps.dwFlags & DSBCAPS_CTRLVOLUME) {
452 LONG val;
453 rc=IDirectSoundBuffer_GetVolume(dsbo,&val);
454 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
455 DXGetErrorString8(rc));
457 rc=IDirectSoundBuffer_SetVolume(dsbo,volume);
458 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume() failed: %s\n",
459 DXGetErrorString8(rc));
460 } else {
461 /* DSOUND: Error: Buffer does not have CTRLVOLUME */
462 rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
463 ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetVolume() "
464 "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
465 DXGetErrorString8(rc));
469 if (set_pan) {
470 if (dsbcaps.dwFlags & DSBCAPS_CTRLPAN) {
471 LONG val;
472 rc=IDirectSoundBuffer_GetPan(dsbo,&val);
473 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan() failed: %s\n",
474 DXGetErrorString8(rc));
476 rc=IDirectSoundBuffer_SetPan(dsbo,pan);
477 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan() failed: %s\n",
478 DXGetErrorString8(rc));
479 } else {
480 /* DSOUND: Error: Buffer does not have CTRLPAN */
481 rc=IDirectSoundBuffer_GetPan(dsbo,&pan);
482 ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetPan() "
483 "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
484 DXGetErrorString8(rc));
488 state.wave=wave_generate_la(&wfx,duration,&state.wave_len);
490 state.dsbo=dsbo;
491 state.wfx=&wfx;
492 state.buffer_size=dsbcaps.dwBufferBytes;
493 state.played=state.written=state.offset=0;
494 buffer_refill(&state,state.buffer_size);
496 rc=IDirectSoundBuffer_Play(dsbo,0,0,DSBPLAY_LOOPING);
497 ok(rc==DS_OK,"IDirectSoundBuffer_Play() failed: %s\n",
498 DXGetErrorString8(rc));
500 rc=IDirectSoundBuffer_GetStatus(dsbo,&status);
501 ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %s\n",
502 DXGetErrorString8(rc));
503 ok(status==(DSBSTATUS_PLAYING|DSBSTATUS_LOOPING),
504 "GetStatus: bad status: %lx\n",status);
506 if (listener) {
507 ZeroMemory(&listener_param,sizeof(listener_param));
508 listener_param.dwSize=sizeof(listener_param);
509 rc=IDirectSound3DListener_GetAllParameters(listener,
510 &listener_param);
511 ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters() "
512 "failed: %s\n",DXGetErrorString8(rc));
513 if (move_listener) {
514 listener_param.vPosition.x = -5.0;
515 listener_param.vVelocity.x = 10.0/duration;
517 rc=IDirectSound3DListener_SetAllParameters(listener,
518 &listener_param,
519 DS3D_IMMEDIATE);
520 ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: %s\n",
521 DXGetErrorString8(rc));
523 if (buffer3d) {
524 if (move_sound) {
525 buffer_param.vPosition.x = 100.0;
526 buffer_param.vVelocity.x = -200.0/duration;
528 buffer_param.flMinDistance = 10;
529 rc=IDirectSound3DBuffer_SetAllParameters(buffer,&buffer_param,
530 DS3D_IMMEDIATE);
531 ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
532 DXGetErrorString8(rc));
535 start_time=GetTickCount();
536 while (buffer_service(&state)) {
537 WaitForSingleObject(GetCurrentProcess(),TIME_SLICE);
538 now=GetTickCount();
539 if (listener && move_listener) {
540 listener_param.vPosition.x = -5.0+10.0*(now-start_time)/
541 1000/duration;
542 if (winetest_debug>2)
543 trace("listener position=%g\n",listener_param.vPosition.x);
544 rc=IDirectSound3DListener_SetPosition(listener,
545 listener_param.vPosition.x,listener_param.vPosition.y,
546 listener_param.vPosition.z,DS3D_IMMEDIATE);
547 ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: "
548 "%s\n",DXGetErrorString8(rc));
550 if (buffer3d && move_sound) {
551 buffer_param.vPosition.x = 100-200.0*(now-start_time)/
552 1000/duration;
553 if (winetest_debug>2)
554 trace("sound position=%g\n",buffer_param.vPosition.x);
555 rc=IDirectSound3DBuffer_SetPosition(buffer,
556 buffer_param.vPosition.x,buffer_param.vPosition.y,
557 buffer_param.vPosition.z,DS3D_IMMEDIATE);
558 ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
559 DXGetErrorString8(rc));
562 /* Check the sound duration was within 10% of the expected value */
563 now=GetTickCount();
564 ok(fabs(1000*duration-now+start_time)<=100*duration,
565 "The sound played for %ld ms instead of %g ms\n",
566 now-start_time,1000*duration);
568 free(state.wave);
569 if (is_primary) {
570 /* Set the CooperativeLevel back to normal */
571 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
572 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
573 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) "
574 "failed: %s\n",DXGetErrorString8(rc));
576 if (buffer3d) {
577 ref=IDirectSound3DBuffer_Release(buffer);
578 ok(ref==0,"IDirectSound3DBuffer_Release() has %d references, "
579 "should have 0\n",ref);
584 static HRESULT test_secondary(LPGUID lpGuid, int play,
585 int has_3d, int has_3dbuffer,
586 int has_listener, int has_duplicate,
587 int move_listener, int move_sound)
589 HRESULT rc;
590 LPDIRECTSOUND dso=NULL;
591 LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
592 LPDIRECTSOUND3DLISTENER listener=NULL;
593 DSBUFFERDESC bufdesc;
594 WAVEFORMATEX wfx;
595 int ref;
597 /* Create the DirectSound object */
598 rc=DirectSoundCreate(lpGuid,&dso,NULL);
599 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
600 if (rc!=DS_OK)
601 return rc;
603 /* We must call SetCooperativeLevel before creating primary buffer */
604 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
605 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
606 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
607 "%s\n",DXGetErrorString8(rc));
608 if (rc!=DS_OK)
609 goto EXIT;
611 ZeroMemory(&bufdesc, sizeof(bufdesc));
612 bufdesc.dwSize=sizeof(bufdesc);
613 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
614 if (has_3d)
615 bufdesc.dwFlags|=DSBCAPS_CTRL3D;
616 else
617 bufdesc.dwFlags|=(DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN);
618 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
619 ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() failed "
620 "to create a %sprimary buffer: %s\n",has_3d?"3D ":"",
621 DXGetErrorString8(rc));
623 if (rc==DS_OK && primary!=NULL) {
624 if (has_listener) {
625 rc=IDirectSoundBuffer_QueryInterface(primary,
626 &IID_IDirectSound3DListener,(void **)&listener);
627 ok(rc==DS_OK && listener!=NULL,
628 "IDirectSoundBuffer_QueryInterface() failed to get a 3D "
629 "listener: %s\n",DXGetErrorString8(rc));
630 ref=IDirectSoundBuffer_Release(primary);
631 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
632 "should have 0\n",ref);
633 if (rc==DS_OK && listener!=NULL) {
634 DS3DLISTENER listener_param;
635 ZeroMemory(&listener_param,sizeof(listener_param));
636 /* DSOUND: Error: Invalid buffer */
637 rc=IDirectSound3DListener_GetAllParameters(listener,0);
638 ok(rc==DSERR_INVALIDPARAM,
639 "IDirectSound3dListener_GetAllParameters() failed: %s\n",
640 DXGetErrorString8(rc));
642 /* DSOUND: Error: Invalid buffer */
643 rc=IDirectSound3DListener_GetAllParameters(listener,
644 &listener_param);
645 ok(rc==DSERR_INVALIDPARAM,
646 "IDirectSound3dListener_GetAllParameters() failed: %s\n",
647 DXGetErrorString8(rc));
649 listener_param.dwSize=sizeof(listener_param);
650 rc=IDirectSound3DListener_GetAllParameters(listener,
651 &listener_param);
652 ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters() "
653 "failed: %s\n",DXGetErrorString8(rc));
655 else
656 goto EXIT;
659 init_format(&wfx,WAVE_FORMAT_PCM,22050,16,2);
660 secondary=NULL;
661 ZeroMemory(&bufdesc, sizeof(bufdesc));
662 bufdesc.dwSize=sizeof(bufdesc);
663 bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
664 if (has_3d)
665 bufdesc.dwFlags|=DSBCAPS_CTRL3D;
666 else
667 bufdesc.dwFlags|=
668 (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN);
669 bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec*BUFFER_LEN/1000;
670 bufdesc.lpwfxFormat=&wfx;
671 if (winetest_interactive) {
672 trace(" Testing a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d\n",
673 has_3dbuffer?"3D ":"",
674 has_duplicate?"duplicated ":"",
675 listener!=NULL||move_sound?"with ":"",
676 move_listener?"moving ":"",
677 listener!=NULL?"listener ":"",
678 listener&&move_sound?"and moving sound ":move_sound?
679 "moving sound ":"",
680 wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
682 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
683 ok(rc==DS_OK && secondary!=NULL,"IDirectSound_CreateSoundBuffer() "
684 "failed to create a 3D secondary buffer: %s\n",
685 DXGetErrorString8(rc));
686 if (rc==DS_OK && secondary!=NULL) {
687 if (!has_3d)
689 DWORD refpan,pan;
690 LONG refvol,vol;
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: "
695 "%s\n",DXGetErrorString8(rc));
696 ok(vol==0,"wrong volume for a new secondary buffer: %ld\n",vol);
697 rc=IDirectSoundBuffer_GetPan(secondary,&pan);
698 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(secondary) failed: "
699 "%s\n",DXGetErrorString8(rc));
700 ok(pan==0,"wrong pan for a new secondary buffer: %ld\n",pan);
702 /* Check that changing the secondary buffer's volume and pan
703 * does not impact the primary buffer's volume and pan
705 rc=IDirectSoundBuffer_GetVolume(primary,&refvol);
706 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(primary) failed: "
707 "%s\n",DXGetErrorString8(rc));
708 rc=IDirectSoundBuffer_GetPan(primary,&refpan);
709 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
710 DXGetErrorString8(rc));
712 rc=IDirectSoundBuffer_SetVolume(secondary,-1000);
713 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
714 "%s\n",DXGetErrorString8(rc));
715 rc=IDirectSoundBuffer_GetVolume(secondary,&vol);
716 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
717 "%s\n",DXGetErrorString8(rc));
718 ok(vol==-1000,"secondary: wrong volume %ld instead of -1000\n",
719 vol);
720 rc=IDirectSoundBuffer_SetPan(secondary,-1000);
721 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
722 "%s\n",DXGetErrorString8(rc));
723 rc=IDirectSoundBuffer_GetPan(secondary,&pan);
724 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
725 "%s\n",DXGetErrorString8(rc));
726 ok(pan==-1000,"secondary: wrong pan %ld instead of -1000\n",
727 pan);
729 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
730 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(primary) failed: "
731 "%s\n",DXGetErrorString8(rc));
732 ok(vol==refvol,"The primary volume changed from %ld to %ld\n",
733 refvol,vol);
734 rc=IDirectSoundBuffer_GetPan(primary,&pan);
735 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
736 DXGetErrorString8(rc));
737 ok(pan==refpan,"The primary pan changed from %ld to %ld\n",
738 refpan,pan);
740 rc=IDirectSoundBuffer_SetVolume(secondary,0);
741 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
742 "%s\n",DXGetErrorString8(rc));
743 rc=IDirectSoundBuffer_SetPan(secondary,0);
744 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
745 "%s\n",DXGetErrorString8(rc));
747 if (has_duplicate) {
748 LPDIRECTSOUNDBUFFER duplicated=NULL;
750 /* DSOUND: Error: Invalid source buffer */
751 rc=IDirectSound_DuplicateSoundBuffer(dso,0,0);
752 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer() "
753 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
754 DXGetErrorString8(rc));
756 /* DSOUND: Error: Invalid dest buffer */
757 rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,0);
758 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer() "
759 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
760 DXGetErrorString8(rc));
762 /* DSOUND: Error: Invalid source buffer */
763 rc=IDirectSound_DuplicateSoundBuffer(dso,0,&duplicated);
764 ok(rc==DSERR_INVALIDPARAM,"IDirectSound_DuplicateSoundBuffer() "
765 "should have returned DSERR_INVALIDPARAM, returned: %s\n",
766 DXGetErrorString8(rc));
768 duplicated=NULL;
769 rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,&duplicated);
770 ok(rc==DS_OK && duplicated!=NULL,
771 "IDirectSound_DuplicateSoundBuffer() failed to duplicate "
772 "a secondary buffer: %s\n",DXGetErrorString8(rc));
774 if (rc==DS_OK && duplicated!=NULL) {
775 ref=IDirectSoundBuffer_Release(secondary);
776 ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d "
777 "references, should have 0\n",ref);
778 secondary=duplicated;
782 if (rc==DS_OK && secondary!=NULL) {
783 double duration;
784 duration=(move_listener || move_sound?4.0:1.0);
785 test_buffer(dso,secondary,0,FALSE,0,FALSE,0,
786 winetest_interactive,duration,has_3dbuffer,
787 listener,move_listener,move_sound);
788 ref=IDirectSoundBuffer_Release(secondary);
789 ok(ref==0,"IDirectSoundBuffer_Release() %s has %d references, "
790 "should have 0\n",has_duplicate?"duplicated":"secondary",
791 ref);
795 if (has_listener) {
796 ref=IDirectSound3DListener_Release(listener);
797 ok(ref==0,"IDirectSound3dListener_Release() listener has %d "
798 "references, should have 0\n",ref);
799 } else {
800 ref=IDirectSoundBuffer_Release(primary);
801 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
802 "should have 0\n",ref);
805 /* Set the CooperativeLevel back to normal */
806 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
807 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
808 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
809 DXGetErrorString8(rc));
811 EXIT:
812 ref=IDirectSound_Release(dso);
813 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
814 if (ref!=0)
815 return DSERR_GENERIC;
817 return rc;
820 static HRESULT test_primary(LPGUID lpGuid)
822 HRESULT rc;
823 LPDIRECTSOUND dso=NULL;
824 LPDIRECTSOUNDBUFFER primary=NULL;
825 DSBUFFERDESC bufdesc;
826 DSCAPS dscaps;
827 int ref, i;
829 /* Create the DirectSound object */
830 rc=DirectSoundCreate(lpGuid,&dso,NULL);
831 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
832 if (rc!=DS_OK)
833 return rc;
835 /* Get the device capabilities */
836 ZeroMemory(&dscaps, sizeof(dscaps));
837 dscaps.dwSize=sizeof(dscaps);
838 rc=IDirectSound_GetCaps(dso,&dscaps);
839 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
840 if (rc!=DS_OK)
841 goto EXIT;
843 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
844 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
845 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
846 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
847 "%s\n",DXGetErrorString8(rc));
848 if (rc!=DS_OK)
849 goto EXIT;
851 /* Testing the primary buffer */
852 primary=NULL;
853 ZeroMemory(&bufdesc, sizeof(bufdesc));
854 bufdesc.dwSize=sizeof(bufdesc);
855 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN;
856 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
857 ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() failed "
858 "to create a primary buffer: %s\n",DXGetErrorString8(rc));
859 if (rc==DS_OK && primary!=NULL) {
860 test_buffer(dso,primary,1,TRUE,0,TRUE,0,winetest_interactive &&
861 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,NULL,0,0);
862 if (winetest_interactive) {
863 LONG volume,pan;
865 volume = DSBVOLUME_MAX;
866 for (i = 0; i < 6; i++) {
867 test_buffer(dso,primary,1,TRUE,volume,TRUE,0,
868 winetest_interactive &&
869 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),
870 1.0,0,NULL,0,0);
871 volume -= ((DSBVOLUME_MAX-DSBVOLUME_MIN) / 40);
874 pan = DSBPAN_LEFT;
875 for (i = 0; i < 7; i++) {
876 test_buffer(dso,primary,1,TRUE,0,TRUE,pan,
877 winetest_interactive &&
878 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0);
879 pan += ((DSBPAN_RIGHT-DSBPAN_LEFT) / 6);
882 ref=IDirectSoundBuffer_Release(primary);
883 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
884 "should have 0\n",ref);
887 /* Set the CooperativeLevel back to normal */
888 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
889 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
890 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
891 DXGetErrorString8(rc));
893 EXIT:
894 ref=IDirectSound_Release(dso);
895 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
896 if (ref!=0)
897 return DSERR_GENERIC;
899 return rc;
902 static HRESULT test_primary_3d(LPGUID lpGuid)
904 HRESULT rc;
905 LPDIRECTSOUND dso=NULL;
906 LPDIRECTSOUNDBUFFER primary=NULL;
907 DSBUFFERDESC bufdesc;
908 DSCAPS dscaps;
909 int ref;
911 /* Create the DirectSound object */
912 rc=DirectSoundCreate(lpGuid,&dso,NULL);
913 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
914 if (rc!=DS_OK)
915 return rc;
917 /* Get the device capabilities */
918 ZeroMemory(&dscaps, sizeof(dscaps));
919 dscaps.dwSize=sizeof(dscaps);
920 rc=IDirectSound_GetCaps(dso,&dscaps);
921 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
922 if (rc!=DS_OK)
923 goto EXIT;
925 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
926 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
927 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
928 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
929 "%s\n",DXGetErrorString8(rc));
930 if (rc!=DS_OK)
931 goto EXIT;
933 primary=NULL;
934 ZeroMemory(&bufdesc, sizeof(bufdesc));
935 bufdesc.dwSize=sizeof(bufdesc);
936 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
937 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
938 ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() failed "
939 "to create a primary buffer: %s\n",DXGetErrorString8(rc));
940 if (rc==DS_OK && primary!=NULL) {
941 ref=IDirectSoundBuffer_Release(primary);
942 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
943 "should have 0\n",ref);
944 primary=NULL;
945 ZeroMemory(&bufdesc, sizeof(bufdesc));
946 bufdesc.dwSize=sizeof(bufdesc);
947 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
948 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
949 ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() "
950 "failed to create a 3D primary buffer: %s\n",DXGetErrorString8(rc));
951 if (rc==DS_OK && primary!=NULL) {
952 test_buffer(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
953 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0);
954 ref=IDirectSoundBuffer_Release(primary);
955 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
956 "should have 0\n",ref);
959 /* Set the CooperativeLevel back to normal */
960 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
961 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
962 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
963 DXGetErrorString8(rc));
965 EXIT:
966 ref=IDirectSound_Release(dso);
967 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
968 if (ref!=0)
969 return DSERR_GENERIC;
971 return rc;
974 static HRESULT test_primary_3d_with_listener(LPGUID lpGuid)
976 HRESULT rc;
977 LPDIRECTSOUND dso=NULL;
978 LPDIRECTSOUNDBUFFER primary=NULL;
979 DSBUFFERDESC bufdesc;
980 DSCAPS dscaps;
981 int ref;
983 /* Create the DirectSound object */
984 rc=DirectSoundCreate(lpGuid,&dso,NULL);
985 ok(rc==DS_OK,"DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
986 if (rc!=DS_OK)
987 return rc;
989 /* Get the device capabilities */
990 ZeroMemory(&dscaps, sizeof(dscaps));
991 dscaps.dwSize=sizeof(dscaps);
992 rc=IDirectSound_GetCaps(dso,&dscaps);
993 ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
994 if (rc!=DS_OK)
995 goto EXIT;
997 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
998 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
999 rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
1000 ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
1001 "%s\n",DXGetErrorString8(rc));
1002 if (rc!=DS_OK)
1003 goto EXIT;
1004 primary=NULL;
1005 ZeroMemory(&bufdesc, sizeof(bufdesc));
1006 bufdesc.dwSize=sizeof(bufdesc);
1007 bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
1008 rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
1009 ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() failed "
1010 "to create a 3D primary buffer: %s\n",DXGetErrorString8(rc));
1011 if (rc==DS_OK && primary!=NULL) {
1012 LPDIRECTSOUND3DLISTENER listener=NULL;
1013 rc=IDirectSoundBuffer_QueryInterface(primary,
1014 &IID_IDirectSound3DListener,(void **)&listener);
1015 ok(rc==DS_OK && listener!=NULL,"IDirectSoundBuffer_QueryInterface() "
1016 "failed to get a 3D listener: %s\n",DXGetErrorString8(rc));
1017 if (rc==DS_OK && listener!=NULL) {
1018 LPDIRECTSOUNDBUFFER temp_buffer=NULL;
1020 /* Checking the COM interface */
1021 rc=IDirectSoundBuffer_QueryInterface(primary,
1022 &IID_IDirectSoundBuffer,(LPVOID *)&temp_buffer);
1023 ok(rc==DS_OK && temp_buffer!=NULL,
1024 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
1025 DXGetErrorString8(rc));
1026 ok(temp_buffer==primary,
1027 "COM interface broken: 0x%08lx != 0x%08lx\n",
1028 (DWORD)temp_buffer,(DWORD)primary);
1029 if (rc==DS_OK && temp_buffer!=NULL) {
1030 ref=IDirectSoundBuffer_Release(temp_buffer);
1031 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, "
1032 "should have 1\n",ref);
1034 temp_buffer=NULL;
1035 rc=IDirectSound3DListener_QueryInterface(listener,
1036 &IID_IDirectSoundBuffer,(LPVOID *)&temp_buffer);
1037 ok(rc==DS_OK && temp_buffer!=NULL,
1038 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
1039 DXGetErrorString8(rc));
1040 ok(temp_buffer==primary,
1041 "COM interface broken: 0x%08lx != 0x%08lx\n",
1042 (DWORD)temp_buffer,(DWORD)primary);
1043 ref=IDirectSoundBuffer_Release(temp_buffer);
1044 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, "
1045 "should have 1\n",ref);
1047 /* Testing the buffer */
1048 test_buffer(dso,primary,1,FALSE,0,FALSE,0,
1049 winetest_interactive &&
1050 !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,
1051 listener,0,0);
1054 /* Testing the reference counting */
1055 ref=IDirectSound3DListener_Release(listener);
1056 ok(ref==0,"IDirectSound3DListener_Release() listener has %d "
1057 "references, should have 0\n",ref);
1060 /* Testing the reference counting */
1061 ref=IDirectSoundBuffer_Release(primary);
1062 ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
1063 "should have 0\n",ref);
1066 EXIT:
1067 ref=IDirectSound_Release(dso);
1068 ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
1069 if (ref!=0)
1070 return DSERR_GENERIC;
1072 return rc;
1075 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
1076 LPCSTR lpcstrModule, LPVOID lpContext)
1078 trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
1080 trace(" Testing the primary buffer\n");
1081 test_primary(lpGuid);
1083 trace(" Testing 3D primary buffer\n");
1084 test_primary_3d(lpGuid);
1086 trace(" Testing 3D primary buffer with listener\n");
1087 test_primary_3d_with_listener(lpGuid);
1089 /* Testing secondary buffers */
1090 test_secondary(lpGuid,winetest_interactive,0,0,0,0,0,0);
1091 test_secondary(lpGuid,winetest_interactive,0,0,0,1,0,0);
1093 /* Testing 3D secondary buffers */
1094 test_secondary(lpGuid,winetest_interactive,1,0,0,0,0,0);
1095 test_secondary(lpGuid,winetest_interactive,1,1,0,0,0,0);
1096 test_secondary(lpGuid,winetest_interactive,1,1,0,1,0,0);
1097 test_secondary(lpGuid,winetest_interactive,1,0,1,0,0,0);
1098 test_secondary(lpGuid,winetest_interactive,1,0,1,1,0,0);
1099 test_secondary(lpGuid,winetest_interactive,1,1,1,0,0,0);
1100 test_secondary(lpGuid,winetest_interactive,1,1,1,1,0,0);
1101 test_secondary(lpGuid,winetest_interactive,1,1,1,0,1,0);
1102 test_secondary(lpGuid,winetest_interactive,1,1,1,0,0,1);
1103 test_secondary(lpGuid,winetest_interactive,1,1,1,0,1,1);
1105 return 1;
1108 static void ds3d_tests()
1110 HRESULT rc;
1111 rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
1112 ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
1115 START_TEST(ds3d)
1117 ds3d_tests();