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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
26 #define NONAMELESSSTRUCT
27 #define NONAMELESSUNION
32 #include "wine/test.h"
36 #include "dsound_test.h"
38 #define PI 3.14159265358979323846
39 char* wave_generate_la(WAVEFORMATEX
* wfx
, double duration
, DWORD
* size
)
46 nb_samples
=(int)(duration
*wfx
->nSamplesPerSec
);
47 *size
=nb_samples
*wfx
->nBlockAlign
;
49 for (i
=0;i
<nb_samples
;i
++) {
50 double y
=sin(440.0*2*PI
*i
/wfx
->nSamplesPerSec
);
51 if (wfx
->wBitsPerSample
==8) {
52 unsigned char sample
=(unsigned char)((double)127.5*(y
+1.0));
54 if (wfx
->nChannels
==2)
57 signed short sample
=(signed short)((double)32767.5*y
-0.5);
61 if (wfx
->nChannels
==2) {
71 const char * getDSBCAPS(DWORD xmask
) {
76 #define FE(x) { x, #x },
77 FE(DSBCAPS_PRIMARYBUFFER
)
79 FE(DSBCAPS_LOCHARDWARE
)
80 FE(DSBCAPS_LOCSOFTWARE
)
82 FE(DSBCAPS_CTRLFREQUENCY
)
84 FE(DSBCAPS_CTRLVOLUME
)
85 FE(DSBCAPS_CTRLPOSITIONNOTIFY
)
86 FE(DSBCAPS_STICKYFOCUS
)
87 FE(DSBCAPS_GLOBALFOCUS
)
88 FE(DSBCAPS_GETCURRENTPOSITION2
)
89 FE(DSBCAPS_MUTE3DATMAXDISTANCE
)
92 static char buffer
[512];
98 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++) {
99 if ((flags
[i
].mask
& xmask
) == flags
[i
].mask
) {
104 strcat(buffer
, flags
[i
].name
);
113 HWND hwnd
=GetForegroundWindow();
115 hwnd
=GetDesktopWindow();
119 void init_format(WAVEFORMATEX
* wfx
, int format
, int rate
, int depth
,
122 wfx
->wFormatTag
=format
;
123 wfx
->nChannels
=channels
;
124 wfx
->wBitsPerSample
=depth
;
125 wfx
->nSamplesPerSec
=rate
;
126 wfx
->nBlockAlign
=wfx
->nChannels
*wfx
->wBitsPerSample
/8;
127 /* FIXME: Shouldn't this test be if (format!=WAVE_FORMAT_PCM) */
128 if (wfx
->nBlockAlign
==0)
130 /* align compressed formats to byte boundary */
133 wfx
->nAvgBytesPerSec
=wfx
->nSamplesPerSec
*wfx
->nBlockAlign
;
141 LPDIRECTSOUNDBUFFER dsbo
;
149 static int buffer_refill(play_state_t
* state
, DWORD size
)
155 if (size
>state
->wave_len
-state
->written
)
156 size
=state
->wave_len
-state
->written
;
158 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
159 &ptr1
,&len1
,&ptr2
,&len2
,0);
160 ok(rc
==DS_OK
,"IDirectSoundBuffer_Lock() failed: %s\n",
161 DXGetErrorString8(rc
));
165 memcpy(ptr1
,state
->wave
+state
->written
,len1
);
166 state
->written
+=len1
;
168 memcpy(ptr2
,state
->wave
+state
->written
,len2
);
169 state
->written
+=len2
;
171 state
->offset
=state
->written
% state
->buffer_size
;
172 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,ptr1
,len1
,ptr2
,len2
);
173 ok(rc
==DS_OK
,"IDirectSoundBuffer_Unlock() failed: %s\n",
174 DXGetErrorString8(rc
));
180 static int buffer_silence(play_state_t
* state
, DWORD size
)
187 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
188 &ptr1
,&len1
,&ptr2
,&len2
,0);
189 ok(rc
==DS_OK
,"IDirectSoundBuffer_Lock() failed: %s\n",
190 DXGetErrorString8(rc
));
194 s
=(state
->wfx
->wBitsPerSample
==8?0x80:0);
199 state
->offset
=(state
->offset
+size
) % state
->buffer_size
;
200 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,ptr1
,len1
,ptr2
,len2
);
201 ok(rc
==DS_OK
,"IDirectSoundBuffer_Unlock() failed: %s\n",
202 DXGetErrorString8(rc
));
208 static int buffer_service(play_state_t
* state
)
210 DWORD last_play_pos
,play_pos
,buf_free
;
213 rc
=IDirectSoundBuffer_GetCurrentPosition(state
->dsbo
,&play_pos
,NULL
);
214 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCurrentPosition() failed: %s\n",
215 DXGetErrorString8(rc
));
220 /* Update the amount played */
221 last_play_pos
=state
->played
% state
->buffer_size
;
222 if (play_pos
<last_play_pos
)
223 state
->played
+=state
->buffer_size
-last_play_pos
+play_pos
;
225 state
->played
+=play_pos
-last_play_pos
;
227 if (winetest_debug
> 1)
228 trace("buf size=%d last_play_pos=%d play_pos=%d played=%d / %d\n",
229 state
->buffer_size
,last_play_pos
,play_pos
,state
->played
,
232 if (state
->played
>state
->wave_len
)
234 /* Everything has been played */
238 /* Refill the buffer */
239 if (state
->offset
<=play_pos
)
240 buf_free
=play_pos
-state
->offset
;
242 buf_free
=state
->buffer_size
-state
->offset
+play_pos
;
244 if (winetest_debug
> 1)
245 trace("offset=%d free=%d written=%d / %d\n",
246 state
->offset
,buf_free
,state
->written
,state
->wave_len
);
250 if (state
->written
<state
->wave_len
)
252 int w
=buffer_refill(state
,buf_free
);
256 if (state
->written
==state
->wave_len
&& winetest_debug
> 1)
257 trace("last sound byte at %d\n",
258 (state
->written
% state
->buffer_size
));
262 /* Fill with silence */
263 if (winetest_debug
> 1)
264 trace("writing %d bytes of silence\n",buf_free
);
265 if (buffer_silence(state
,buf_free
)==-1)
271 if (winetest_debug
> 1)
272 trace("stopping playback\n");
273 rc
=IDirectSoundBuffer_Stop(state
->dsbo
);
274 ok(rc
==DS_OK
,"IDirectSoundBuffer_Stop() failed: %s\n",
275 DXGetErrorString8(rc
));
279 void test_buffer(LPDIRECTSOUND dso
, LPDIRECTSOUNDBUFFER
*dsbo
,
280 BOOL is_primary
, BOOL set_volume
, LONG volume
,
281 BOOL set_pan
, LONG pan
, BOOL play
, double duration
,
282 BOOL buffer3d
, LPDIRECTSOUND3DLISTENER listener
,
283 BOOL move_listener
, BOOL move_sound
,
284 BOOL set_frequency
, DWORD frequency
)
288 WAVEFORMATEX wfx
,wfx2
;
289 DWORD size
,status
,freq
;
293 rc
=IDirectSoundBuffer_SetFrequency(*dsbo
,frequency
);
294 ok(rc
==DS_OK
||rc
==DSERR_CONTROLUNAVAIL
,
295 "IDirectSoundBuffer_SetFrequency() failed to set frequency "
296 "%s\n",DXGetErrorString8(rc
));
301 /* DSOUND: Error: Invalid caps pointer */
302 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,0);
303 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetCaps() should have "
304 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
306 ZeroMemory(&dsbcaps
, sizeof(dsbcaps
));
308 /* DSOUND: Error: Invalid caps pointer */
309 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&dsbcaps
);
310 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetCaps() should have "
311 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
313 dsbcaps
.dwSize
=sizeof(dsbcaps
);
314 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&dsbcaps
);
315 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() failed: %s\n",
316 DXGetErrorString8(rc
));
317 if (rc
==DS_OK
&& winetest_debug
> 1) {
318 trace(" Caps: flags=0x%08x size=%d\n",dsbcaps
.dwFlags
,
319 dsbcaps
.dwBufferBytes
);
322 /* Query the format size. Note that it may not match sizeof(wfx) */
324 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,NULL
,0,&size
);
325 ok(rc
==DS_OK
&& size
!=0,"IDirectSoundBuffer_GetFormat() should have "
326 "returned the needed size: rc=%s size=%d\n",DXGetErrorString8(rc
),size
);
328 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,&wfx
,sizeof(wfx
),NULL
);
329 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %s\n",
330 DXGetErrorString8(rc
));
331 if (rc
==DS_OK
&& winetest_debug
> 1) {
332 trace(" Format: %s tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
333 is_primary
? "Primary" : "Secondary",
334 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
335 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
338 /* DSOUND: Error: Invalid frequency buffer */
339 rc
=IDirectSoundBuffer_GetFrequency(*dsbo
,0);
340 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetFrequency() should have "
341 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
343 /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */
344 rc
=IDirectSoundBuffer_GetFrequency(*dsbo
,&freq
);
345 ok((rc
==DS_OK
&& !is_primary
) || (rc
==DSERR_CONTROLUNAVAIL
&&is_primary
) ||
346 (rc
==DSERR_CONTROLUNAVAIL
&&!(dsbcaps
.dwFlags
&DSBCAPS_CTRLFREQUENCY
)),
347 "IDirectSoundBuffer_GetFrequency() failed: %s\n",DXGetErrorString8(rc
));
349 DWORD f
= set_frequency
?frequency
:wfx
.nSamplesPerSec
;
350 ok(freq
==f
,"The frequency returned by GetFrequency "
351 "%d does not match the format %d\n",freq
,f
);
354 /* DSOUND: Error: Invalid status pointer */
355 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,0);
356 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetStatus() should have "
357 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
359 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,&status
);
360 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetStatus() failed: %s\n",
361 DXGetErrorString8(rc
));
362 ok(status
==0,"status=0x%x instead of 0\n",status
);
366 /* We must call SetCooperativeLevel to be allowed to call SetFormat */
367 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
368 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
369 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
370 "%s\n",DXGetErrorString8(rc
));
374 /* DSOUND: Error: Invalid format pointer */
375 rc
=IDirectSoundBuffer_SetFormat(*dsbo
,0);
376 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_SetFormat() should have "
377 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
379 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
380 rc
=IDirectSoundBuffer_SetFormat(*dsbo
,&wfx2
);
381 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat(%s) failed: %s\n",
382 format_string(&wfx2
), DXGetErrorString8(rc
));
384 /* There is no garantee that SetFormat will actually change the
385 * format to what we asked for. It depends on what the soundcard
386 * supports. So we must re-query the format.
388 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,&wfx
,sizeof(wfx
),NULL
);
389 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %s\n",
390 DXGetErrorString8(rc
));
392 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
393 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
394 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
395 wfx
.nChannels
!=wfx2
.nChannels
)) {
396 trace("Requested format tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
397 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
398 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
399 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
400 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
401 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
404 ZeroMemory(&new_dsbcaps
, sizeof(new_dsbcaps
));
405 new_dsbcaps
.dwSize
= sizeof(new_dsbcaps
);
406 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&new_dsbcaps
);
407 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() failed: %s\n",
408 DXGetErrorString8(rc
));
409 if (rc
==DS_OK
&& winetest_debug
> 1) {
410 trace(" new Caps: flags=0x%08x size=%d\n",new_dsbcaps
.dwFlags
,
411 new_dsbcaps
.dwBufferBytes
);
414 /* Check for primary buffer size change */
415 ok(new_dsbcaps
.dwBufferBytes
== dsbcaps
.dwBufferBytes
,
416 " buffer size changed after SetFormat() - "
417 "previous size was %u, current size is %u\n",
418 dsbcaps
.dwBufferBytes
, new_dsbcaps
.dwBufferBytes
);
420 /* Check for primary buffer flags change */
421 ok(new_dsbcaps
.dwFlags
== dsbcaps
.dwFlags
,
422 " flags changed after SetFormat() - "
423 "previous flags were %08x, current flags are %08x\n",
424 dsbcaps
.dwFlags
, new_dsbcaps
.dwFlags
);
426 /* Set the CooperativeLevel back to normal */
427 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
428 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
429 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: "
430 "%s\n",DXGetErrorString8(rc
));
435 DS3DLISTENER listener_param
;
436 LPDIRECTSOUND3DBUFFER buffer
=NULL
;
437 DS3DBUFFER buffer_param
;
438 DWORD start_time
,now
;
442 if (winetest_interactive
) {
444 trace(" Playing %g second 440Hz tone at %dx%dx%d with a "
445 "frequency of %d (%dHz)\n", duration
,
446 wfx
.nSamplesPerSec
, wfx
.wBitsPerSample
, wfx
.nChannels
,
447 frequency
, (440 * frequency
) / wfx
.nSamplesPerSec
);
449 trace(" Playing %g second 440Hz tone at %dx%dx%d\n", duration
,
450 wfx
.nSamplesPerSec
, wfx
.wBitsPerSample
, wfx
.nChannels
);
454 /* We must call SetCooperativeLevel to be allowed to call Lock */
455 /* DSOUND: Setting DirectSound cooperative level to
456 * DSSCL_WRITEPRIMARY */
457 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),
459 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_WRITEPRIMARY) "
460 "failed: %s\n",DXGetErrorString8(rc
));
465 LPDIRECTSOUNDBUFFER temp_buffer
;
467 rc
=IDirectSoundBuffer_QueryInterface(*dsbo
,&IID_IDirectSound3DBuffer
,
469 ok(rc
==DS_OK
,"IDirectSoundBuffer_QueryInterface() failed: %s\n",
470 DXGetErrorString8(rc
));
474 /* check the COM interface */
475 rc
=IDirectSoundBuffer_QueryInterface(*dsbo
, &IID_IDirectSoundBuffer
,
476 (LPVOID
*)&temp_buffer
);
477 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
478 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
479 DXGetErrorString8(rc
));
480 ok(temp_buffer
==*dsbo
,"COM interface broken: %p != %p\n",
482 ref
=IDirectSoundBuffer_Release(temp_buffer
);
483 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
484 "should have 1\n",ref
);
487 rc
=IDirectSound3DBuffer_QueryInterface(*dsbo
,
488 &IID_IDirectSoundBuffer
,
489 (LPVOID
*)&temp_buffer
);
490 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
491 "IDirectSound3DBuffer_QueryInterface() failed: %s\n",
492 DXGetErrorString8(rc
));
493 ok(temp_buffer
==*dsbo
,"COM interface broken: %p != %p\n",
495 ref
=IDirectSoundBuffer_Release(temp_buffer
);
496 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
497 "should have 1\n",ref
);
499 ref
=IDirectSoundBuffer_Release(*dsbo
);
500 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
501 "should have 0\n",ref
);
503 rc
=IDirectSound3DBuffer_QueryInterface(buffer
,
504 &IID_IDirectSoundBuffer
,
506 ok(rc
==DS_OK
&& *dsbo
!=NULL
,"IDirectSound3DBuffer_QueryInterface() "
507 "failed: %s\n",DXGetErrorString8(rc
));
509 /* DSOUND: Error: Invalid buffer */
510 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,0);
511 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound3DBuffer_GetAllParameters() "
512 "failed: %s\n",DXGetErrorString8(rc
));
514 ZeroMemory(&buffer_param
, sizeof(buffer_param
));
516 /* DSOUND: Error: Invalid buffer */
517 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,&buffer_param
);
518 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound3DBuffer_GetAllParameters() "
519 "failed: %s\n",DXGetErrorString8(rc
));
521 buffer_param
.dwSize
=sizeof(buffer_param
);
522 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,&buffer_param
);
523 ok(rc
==DS_OK
,"IDirectSound3DBuffer_GetAllParameters() failed: %s\n",
524 DXGetErrorString8(rc
));
527 if (dsbcaps
.dwFlags
& DSBCAPS_CTRLVOLUME
) {
529 rc
=IDirectSoundBuffer_GetVolume(*dsbo
,&val
);
530 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %s\n",
531 DXGetErrorString8(rc
));
533 rc
=IDirectSoundBuffer_SetVolume(*dsbo
,volume
);
534 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume() failed: %s\n",
535 DXGetErrorString8(rc
));
537 /* DSOUND: Error: Buffer does not have CTRLVOLUME */
538 rc
=IDirectSoundBuffer_GetVolume(*dsbo
,&volume
);
539 ok(rc
==DSERR_CONTROLUNAVAIL
,"IDirectSoundBuffer_GetVolume() "
540 "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
541 DXGetErrorString8(rc
));
546 if (dsbcaps
.dwFlags
& DSBCAPS_CTRLPAN
) {
548 rc
=IDirectSoundBuffer_GetPan(*dsbo
,&val
);
549 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan() failed: %s\n",
550 DXGetErrorString8(rc
));
552 rc
=IDirectSoundBuffer_SetPan(*dsbo
,pan
);
553 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan() failed: %s\n",
554 DXGetErrorString8(rc
));
556 /* DSOUND: Error: Buffer does not have CTRLPAN */
557 rc
=IDirectSoundBuffer_GetPan(*dsbo
,&pan
);
558 ok(rc
==DSERR_CONTROLUNAVAIL
,"IDirectSoundBuffer_GetPan() "
559 "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
560 DXGetErrorString8(rc
));
564 /* try an offset past the end of the buffer */
565 rc
= IDirectSoundBuffer_Lock(*dsbo
, dsbcaps
.dwBufferBytes
, 0, &buffer1
,
566 &length1
, NULL
, NULL
,
567 DSBLOCK_ENTIREBUFFER
);
568 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSoundBuffer_Lock() should have "
569 "returned DSERR_INVALIDPARAM, returned %s\n", DXGetErrorString8(rc
));
571 /* try a size larger than the buffer */
572 rc
= IDirectSoundBuffer_Lock(*dsbo
, 0, dsbcaps
.dwBufferBytes
+ 1,
573 &buffer1
, &length1
, NULL
, NULL
,
574 DSBLOCK_FROMWRITECURSOR
);
575 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSoundBuffer_Lock() should have "
576 "returned DSERR_INVALIDPARAM, returned %s\n", DXGetErrorString8(rc
));
579 state
.wave
=wave_generate_la(&wfx
,(duration
*frequency
)/wfx
.nSamplesPerSec
,&state
.wave_len
);
581 state
.wave
=wave_generate_la(&wfx
,duration
,&state
.wave_len
);
585 state
.buffer_size
=dsbcaps
.dwBufferBytes
;
586 state
.played
=state
.written
=state
.offset
=0;
587 buffer_refill(&state
,state
.buffer_size
);
589 rc
=IDirectSoundBuffer_Play(*dsbo
,0,0,DSBPLAY_LOOPING
);
590 ok(rc
==DS_OK
,"IDirectSoundBuffer_Play() failed: %s\n",
591 DXGetErrorString8(rc
));
593 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,&status
);
594 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetStatus() failed: %s\n",
595 DXGetErrorString8(rc
));
596 ok(status
==(DSBSTATUS_PLAYING
|DSBSTATUS_LOOPING
),
597 "GetStatus: bad status: %x\n",status
);
600 ZeroMemory(&listener_param
,sizeof(listener_param
));
601 listener_param
.dwSize
=sizeof(listener_param
);
602 rc
=IDirectSound3DListener_GetAllParameters(listener
,
604 ok(rc
==DS_OK
,"IDirectSound3dListener_GetAllParameters() "
605 "failed: %s\n",DXGetErrorString8(rc
));
607 listener_param
.vPosition
.x
= -5.0;
608 listener_param
.vVelocity
.x
= 10.0/duration
;
610 rc
=IDirectSound3DListener_SetAllParameters(listener
,
613 ok(rc
==DS_OK
,"IDirectSound3dListener_SetPosition() failed: %s\n",
614 DXGetErrorString8(rc
));
618 buffer_param
.vPosition
.x
= 100.0;
619 buffer_param
.vVelocity
.x
= -200.0/duration
;
621 buffer_param
.flMinDistance
= 10;
622 rc
=IDirectSound3DBuffer_SetAllParameters(buffer
,&buffer_param
,
624 ok(rc
==DS_OK
,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
625 DXGetErrorString8(rc
));
628 start_time
=GetTickCount();
629 while (buffer_service(&state
)) {
630 WaitForSingleObject(GetCurrentProcess(),TIME_SLICE
);
632 if (listener
&& move_listener
) {
633 listener_param
.vPosition
.x
= -5.0+10.0*(now
-start_time
)/
635 if (winetest_debug
>2)
636 trace("listener position=%g\n",listener_param
.vPosition
.x
);
637 rc
=IDirectSound3DListener_SetPosition(listener
,
638 listener_param
.vPosition
.x
,listener_param
.vPosition
.y
,
639 listener_param
.vPosition
.z
,DS3D_IMMEDIATE
);
640 ok(rc
==DS_OK
,"IDirectSound3dListener_SetPosition() failed: "
641 "%s\n",DXGetErrorString8(rc
));
643 if (buffer3d
&& move_sound
) {
644 buffer_param
.vPosition
.x
= 100-200.0*(now
-start_time
)/
646 if (winetest_debug
>2)
647 trace("sound position=%g\n",buffer_param
.vPosition
.x
);
648 rc
=IDirectSound3DBuffer_SetPosition(buffer
,
649 buffer_param
.vPosition
.x
,buffer_param
.vPosition
.y
,
650 buffer_param
.vPosition
.z
,DS3D_IMMEDIATE
);
651 ok(rc
==DS_OK
,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
652 DXGetErrorString8(rc
));
655 /* Check the sound duration was within 10% of the expected value */
657 ok(fabs(1000*duration
-now
+start_time
)<=100*duration
,
658 "The sound played for %d ms instead of %g ms\n",
659 now
-start_time
,1000*duration
);
663 /* Set the CooperativeLevel back to normal */
664 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
665 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
666 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) "
667 "failed: %s\n",DXGetErrorString8(rc
));
670 ref
=IDirectSound3DBuffer_Release(buffer
);
671 ok(ref
==0,"IDirectSound3DBuffer_Release() has %d references, "
672 "should have 0\n",ref
);
677 static HRESULT
test_secondary(LPGUID lpGuid
, int play
,
678 int has_3d
, int has_3dbuffer
,
679 int has_listener
, int has_duplicate
,
680 int move_listener
, int move_sound
)
683 LPDIRECTSOUND dso
=NULL
;
684 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
685 LPDIRECTSOUND3DLISTENER listener
=NULL
;
686 DSBUFFERDESC bufdesc
;
687 WAVEFORMATEX wfx
, wfx1
;
690 /* Create the DirectSound object */
691 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
692 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
693 DXGetErrorString8(rc
));
697 /* We must call SetCooperativeLevel before creating primary buffer */
698 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
699 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
700 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
701 "%s\n",DXGetErrorString8(rc
));
705 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
706 bufdesc
.dwSize
=sizeof(bufdesc
);
707 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
709 bufdesc
.dwFlags
|=DSBCAPS_CTRL3D
;
711 bufdesc
.dwFlags
|=(DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
);
712 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
713 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
714 "IDirectSound_CreateSoundBuffer() failed to create a %sprimary buffer: "
715 "%s\n",has_3d
?"3D ":"", DXGetErrorString8(rc
));
716 if (rc
==DSERR_CONTROLUNAVAIL
)
717 trace(" No Primary\n");
718 else if (rc
==DS_OK
&& primary
!=NULL
) {
719 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
720 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %s\n",
721 DXGetErrorString8(rc
));
726 rc
=IDirectSoundBuffer_QueryInterface(primary
,
727 &IID_IDirectSound3DListener
,
729 ok(rc
==DS_OK
&& listener
!=NULL
,
730 "IDirectSoundBuffer_QueryInterface() failed to get a 3D "
731 "listener: %s\n",DXGetErrorString8(rc
));
732 ref
=IDirectSoundBuffer_Release(primary
);
733 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
734 "should have 0\n",ref
);
735 if (rc
==DS_OK
&& listener
!=NULL
) {
736 DS3DLISTENER listener_param
;
737 ZeroMemory(&listener_param
,sizeof(listener_param
));
738 /* DSOUND: Error: Invalid buffer */
739 rc
=IDirectSound3DListener_GetAllParameters(listener
,0);
740 ok(rc
==DSERR_INVALIDPARAM
,
741 "IDirectSound3dListener_GetAllParameters() should have "
742 "returned DSERR_INVALIDPARAM, returned: %s\n",
743 DXGetErrorString8(rc
));
745 /* DSOUND: Error: Invalid buffer */
746 rc
=IDirectSound3DListener_GetAllParameters(listener
,
748 ok(rc
==DSERR_INVALIDPARAM
,
749 "IDirectSound3dListener_GetAllParameters() should have "
750 "returned DSERR_INVALIDPARAM, returned: %s\n",
751 DXGetErrorString8(rc
));
753 listener_param
.dwSize
=sizeof(listener_param
);
754 rc
=IDirectSound3DListener_GetAllParameters(listener
,
756 ok(rc
==DS_OK
,"IDirectSound3dListener_GetAllParameters() "
757 "failed: %s\n",DXGetErrorString8(rc
));
759 ok(listener
==NULL
, "IDirectSoundBuffer_QueryInterface() "
760 "failed but returned a listener anyway\n");
761 ok(rc
!=DS_OK
, "IDirectSoundBuffer_QueryInterface() succeeded "
762 "but returned a NULL listener\n");
764 ref
=IDirectSound3DListener_Release(listener
);
765 ok(ref
==0,"IDirectSound3dListener_Release() listener has "
766 "%d references, should have 0\n",ref
);
772 init_format(&wfx
,WAVE_FORMAT_PCM
,22050,16,2);
774 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
775 bufdesc
.dwSize
=sizeof(bufdesc
);
776 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
778 bufdesc
.dwFlags
|=DSBCAPS_CTRL3D
;
781 (DSBCAPS_CTRLFREQUENCY
|DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
);
782 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
784 bufdesc
.lpwfxFormat
=&wfx
;
785 if (winetest_interactive
) {
786 trace(" Testing a %s%ssecondary buffer %s%s%s%sat %dx%dx%d "
787 "with a primary buffer at %dx%dx%d\n",
788 has_3dbuffer
?"3D ":"",
789 has_duplicate
?"duplicated ":"",
790 listener
!=NULL
||move_sound
?"with ":"",
791 move_listener
?"moving ":"",
792 listener
!=NULL
?"listener ":"",
793 listener
&&move_sound
?"and moving sound ":move_sound
?
795 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
796 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
798 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
799 ok(rc
==DS_OK
&& secondary
!=NULL
,"IDirectSound_CreateSoundBuffer() "
800 "failed to create a %s%ssecondary buffer %s%s%s%sat %dx%dx%d (%s): %s\n",
801 has_3dbuffer
?"3D ":"", has_duplicate
?"duplicated ":"",
802 listener
!=NULL
||move_sound
?"with ":"", move_listener
?"moving ":"",
803 listener
!=NULL
?"listener ":"",
804 listener
&&move_sound
?"and moving sound ":move_sound
?
806 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
807 getDSBCAPS(bufdesc
.dwFlags
),DXGetErrorString8(rc
));
808 if (rc
==DS_OK
&& secondary
!=NULL
) {
810 LONG refvol
,vol
,refpan
,pan
;
812 /* Check the initial secondary buffer's volume and pan */
813 rc
=IDirectSoundBuffer_GetVolume(secondary
,&vol
);
814 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(secondary) failed: "
815 "%s\n",DXGetErrorString8(rc
));
816 ok(vol
==0,"wrong volume for a new secondary buffer: %d\n",vol
);
817 rc
=IDirectSoundBuffer_GetPan(secondary
,&pan
);
818 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(secondary) failed: "
819 "%s\n",DXGetErrorString8(rc
));
820 ok(pan
==0,"wrong pan for a new secondary buffer: %d\n",pan
);
822 /* Check that changing the secondary buffer's volume and pan
823 * does not impact the primary buffer's volume and pan
825 rc
=IDirectSoundBuffer_GetVolume(primary
,&refvol
);
826 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(primary) failed: "
827 "%s\n",DXGetErrorString8(rc
));
828 rc
=IDirectSoundBuffer_GetPan(primary
,&refpan
);
829 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
830 DXGetErrorString8(rc
));
832 rc
=IDirectSoundBuffer_SetVolume(secondary
,-1000);
833 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: "
834 "%s\n",DXGetErrorString8(rc
));
835 rc
=IDirectSoundBuffer_GetVolume(secondary
,&vol
);
836 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: "
837 "%s\n",DXGetErrorString8(rc
));
838 ok(vol
==-1000,"secondary: wrong volume %d instead of -1000\n",
840 rc
=IDirectSoundBuffer_SetPan(secondary
,-1000);
841 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: "
842 "%s\n",DXGetErrorString8(rc
));
843 rc
=IDirectSoundBuffer_GetPan(secondary
,&pan
);
844 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: "
845 "%s\n",DXGetErrorString8(rc
));
846 ok(pan
==-1000,"secondary: wrong pan %d instead of -1000\n",
849 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
850 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(primary) failed: "
851 "%s\n",DXGetErrorString8(rc
));
852 ok(vol
==refvol
,"The primary volume changed from %d to %d\n",
854 rc
=IDirectSoundBuffer_GetPan(primary
,&pan
);
855 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
856 DXGetErrorString8(rc
));
857 ok(pan
==refpan
,"The primary pan changed from %d to %d\n",
860 rc
=IDirectSoundBuffer_SetVolume(secondary
,0);
861 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: "
862 "%s\n",DXGetErrorString8(rc
));
863 rc
=IDirectSoundBuffer_SetPan(secondary
,0);
864 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: "
865 "%s\n",DXGetErrorString8(rc
));
868 LPDIRECTSOUNDBUFFER duplicated
=NULL
;
870 /* DSOUND: Error: Invalid source buffer */
871 rc
=IDirectSound_DuplicateSoundBuffer(dso
,0,0);
872 ok(rc
==DSERR_INVALIDPARAM
,
873 "IDirectSound_DuplicateSoundBuffer() should have returned "
874 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
876 /* DSOUND: Error: Invalid dest buffer */
877 rc
=IDirectSound_DuplicateSoundBuffer(dso
,secondary
,0);
878 ok(rc
==DSERR_INVALIDPARAM
,
879 "IDirectSound_DuplicateSoundBuffer() should have returned "
880 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
882 /* DSOUND: Error: Invalid source buffer */
883 rc
=IDirectSound_DuplicateSoundBuffer(dso
,0,&duplicated
);
884 ok(rc
==DSERR_INVALIDPARAM
,
885 "IDirectSound_DuplicateSoundBuffer() should have returned "
886 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
889 rc
=IDirectSound_DuplicateSoundBuffer(dso
,secondary
,
891 ok(rc
==DS_OK
&& duplicated
!=NULL
,
892 "IDirectSound_DuplicateSoundBuffer() failed to duplicate "
893 "a secondary buffer: %s\n",DXGetErrorString8(rc
));
895 if (rc
==DS_OK
&& duplicated
!=NULL
) {
896 ref
=IDirectSoundBuffer_Release(secondary
);
897 ok(ref
==0,"IDirectSoundBuffer_Release() secondary has %d "
898 "references, should have 0\n",ref
);
899 secondary
=duplicated
;
903 if (rc
==DS_OK
&& secondary
!=NULL
) {
905 duration
=(move_listener
|| move_sound
?4.0:1.0);
906 test_buffer(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
907 winetest_interactive
,duration
,has_3dbuffer
,
908 listener
,move_listener
,move_sound
,FALSE
,0);
909 ref
=IDirectSoundBuffer_Release(secondary
);
910 ok(ref
==0,"IDirectSoundBuffer_Release() %s has %d references, "
911 "should have 0\n",has_duplicate
?"duplicated":"secondary",
917 ref
=IDirectSound3DListener_Release(listener
);
918 ok(ref
==0,"IDirectSound3dListener_Release() listener has %d "
919 "references, should have 0\n",ref
);
921 ref
=IDirectSoundBuffer_Release(primary
);
922 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
923 "should have 0\n",ref
);
926 ok(primary
==NULL
,"IDirectSound_CreateSoundBuffer(primary) failed "
927 "but primary created anyway\n");
928 ok(rc
!=DS_OK
,"IDirectSound_CreateSoundBuffer(primary) succeeded "
929 "but primary not created\n");
931 ref
=IDirectSoundBuffer_Release(primary
);
932 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
933 "should have 0\n",ref
);
937 /* Set the CooperativeLevel back to normal */
938 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
939 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
940 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
941 DXGetErrorString8(rc
));
944 ref
=IDirectSound_Release(dso
);
945 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
947 return DSERR_GENERIC
;
952 static HRESULT
test_for_driver(LPGUID lpGuid
)
955 LPDIRECTSOUND dso
=NULL
;
958 /* Create the DirectSound object */
959 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
960 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
961 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
965 ref
=IDirectSound_Release(dso
);
966 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
968 return DSERR_GENERIC
;
973 static HRESULT
test_primary(LPGUID lpGuid
)
976 LPDIRECTSOUND dso
=NULL
;
977 LPDIRECTSOUNDBUFFER primary
=NULL
;
978 DSBUFFERDESC bufdesc
;
982 /* Create the DirectSound object */
983 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
984 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
985 DXGetErrorString8(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
));
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
));
1005 /* Testing the primary buffer */
1007 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1008 bufdesc
.dwSize
=sizeof(bufdesc
);
1009 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
;
1010 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1011 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
1012 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: "
1013 "%s\n",DXGetErrorString8(rc
));
1014 if (rc
==DSERR_CONTROLUNAVAIL
)
1015 trace(" No Primary\n");
1016 else if (rc
==DS_OK
&& primary
!=NULL
) {
1017 test_buffer(dso
,&primary
,1,TRUE
,0,TRUE
,0,winetest_interactive
&&
1018 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,NULL
,0,0,
1020 if (winetest_interactive
) {
1023 volume
= DSBVOLUME_MAX
;
1024 for (i
= 0; i
< 6; i
++) {
1025 test_buffer(dso
,&primary
,1,TRUE
,volume
,TRUE
,0,
1026 winetest_interactive
&&
1027 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),
1028 1.0,0,NULL
,0,0,FALSE
,0);
1029 volume
-= ((DSBVOLUME_MAX
-DSBVOLUME_MIN
) / 40);
1033 for (i
= 0; i
< 7; i
++) {
1034 test_buffer(dso
,&primary
,1,TRUE
,0,TRUE
,pan
,
1035 winetest_interactive
&&
1036 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,0,0,0,FALSE
,0);
1037 pan
+= ((DSBPAN_RIGHT
-DSBPAN_LEFT
) / 6);
1040 ref
=IDirectSoundBuffer_Release(primary
);
1041 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1042 "should have 0\n",ref
);
1045 /* Set the CooperativeLevel back to normal */
1046 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1047 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1048 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
1049 DXGetErrorString8(rc
));
1052 ref
=IDirectSound_Release(dso
);
1053 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1055 return DSERR_GENERIC
;
1060 static HRESULT
test_primary_3d(LPGUID lpGuid
)
1063 LPDIRECTSOUND dso
=NULL
;
1064 LPDIRECTSOUNDBUFFER primary
=NULL
;
1065 DSBUFFERDESC bufdesc
;
1069 /* Create the DirectSound object */
1070 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
1071 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
1072 DXGetErrorString8(rc
));
1076 /* Get the device capabilities */
1077 ZeroMemory(&dscaps
, sizeof(dscaps
));
1078 dscaps
.dwSize
=sizeof(dscaps
);
1079 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1080 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
1084 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1085 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1086 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1087 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
1088 "%s\n",DXGetErrorString8(rc
));
1093 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1094 bufdesc
.dwSize
=sizeof(bufdesc
);
1095 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
1096 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1097 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1098 "to create a primary buffer: %s\n",DXGetErrorString8(rc
));
1099 if (rc
==DS_OK
&& primary
!=NULL
) {
1100 ref
=IDirectSoundBuffer_Release(primary
);
1101 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1102 "should have 0\n",ref
);
1104 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1105 bufdesc
.dwSize
=sizeof(bufdesc
);
1106 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRL3D
;
1107 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1108 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() "
1109 "failed to create a 3D primary buffer: %s\n",DXGetErrorString8(rc
));
1110 if (rc
==DS_OK
&& primary
!=NULL
) {
1111 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
1112 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,0,0,0,
1114 ref
=IDirectSoundBuffer_Release(primary
);
1115 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1116 "should have 0\n",ref
);
1119 /* Set the CooperativeLevel back to normal */
1120 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1121 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1122 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
1123 DXGetErrorString8(rc
));
1126 ref
=IDirectSound_Release(dso
);
1127 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1129 return DSERR_GENERIC
;
1134 static HRESULT
test_primary_3d_with_listener(LPGUID lpGuid
)
1137 LPDIRECTSOUND dso
=NULL
;
1138 LPDIRECTSOUNDBUFFER primary
=NULL
;
1139 DSBUFFERDESC bufdesc
;
1143 /* Create the DirectSound object */
1144 rc
=DirectSoundCreate(lpGuid
,&dso
,NULL
);
1145 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
1146 DXGetErrorString8(rc
));
1150 /* Get the device capabilities */
1151 ZeroMemory(&dscaps
, sizeof(dscaps
));
1152 dscaps
.dwSize
=sizeof(dscaps
);
1153 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1154 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
1158 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1159 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1160 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1161 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
1162 "%s\n",DXGetErrorString8(rc
));
1166 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1167 bufdesc
.dwSize
=sizeof(bufdesc
);
1168 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRL3D
;
1169 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1170 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1171 "to create a 3D primary buffer: %s\n",DXGetErrorString8(rc
));
1172 if (rc
==DS_OK
&& primary
!=NULL
) {
1173 LPDIRECTSOUND3DLISTENER listener
=NULL
;
1174 rc
=IDirectSoundBuffer_QueryInterface(primary
,
1175 &IID_IDirectSound3DListener
,(void **)&listener
);
1176 ok(rc
==DS_OK
&& listener
!=NULL
,"IDirectSoundBuffer_QueryInterface() "
1177 "failed to get a 3D listener: %s\n",DXGetErrorString8(rc
));
1178 if (rc
==DS_OK
&& listener
!=NULL
) {
1179 LPDIRECTSOUNDBUFFER temp_buffer
=NULL
;
1181 /* Checking the COM interface */
1182 rc
=IDirectSoundBuffer_QueryInterface(primary
,
1183 &IID_IDirectSoundBuffer
,(LPVOID
*)&temp_buffer
);
1184 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1185 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
1186 DXGetErrorString8(rc
));
1187 ok(temp_buffer
==primary
,
1188 "COM interface broken: %p != %p\n",
1189 temp_buffer
,primary
);
1190 if (rc
==DS_OK
&& temp_buffer
!=NULL
) {
1191 ref
=IDirectSoundBuffer_Release(temp_buffer
);
1192 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
1193 "should have 1\n",ref
);
1196 rc
=IDirectSound3DListener_QueryInterface(listener
,
1197 &IID_IDirectSoundBuffer
,(LPVOID
*)&temp_buffer
);
1198 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1199 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
1200 DXGetErrorString8(rc
));
1201 ok(temp_buffer
==primary
,
1202 "COM interface broken: %p != %p\n",
1203 temp_buffer
,primary
);
1204 ref
=IDirectSoundBuffer_Release(temp_buffer
);
1205 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
1206 "should have 1\n",ref
);
1208 /* Testing the buffer */
1209 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,
1210 winetest_interactive
&&
1211 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,
1212 listener
,0,0,FALSE
,0);
1215 /* Testing the reference counting */
1216 ref
=IDirectSound3DListener_Release(listener
);
1217 ok(ref
==0,"IDirectSound3DListener_Release() listener has %d "
1218 "references, should have 0\n",ref
);
1221 /* Testing the reference counting */
1222 ref
=IDirectSoundBuffer_Release(primary
);
1223 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1224 "should have 0\n",ref
);
1228 ref
=IDirectSound_Release(dso
);
1229 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1231 return DSERR_GENERIC
;
1236 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
1237 LPCSTR lpcstrModule
, LPVOID lpContext
)
1240 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
1242 rc
= test_for_driver(lpGuid
);
1243 if (rc
== DSERR_NODRIVER
) {
1244 trace(" No Driver\n");
1246 } else if (rc
== DSERR_ALLOCATED
) {
1247 trace(" Already In Use\n");
1249 } else if (rc
== E_FAIL
) {
1250 trace(" No Device\n");
1254 trace(" Testing the primary buffer\n");
1255 test_primary(lpGuid
);
1257 trace(" Testing 3D primary buffer\n");
1258 test_primary_3d(lpGuid
);
1260 trace(" Testing 3D primary buffer with listener\n");
1261 test_primary_3d_with_listener(lpGuid
);
1263 /* Testing secondary buffers */
1264 test_secondary(lpGuid
,winetest_interactive
,0,0,0,0,0,0);
1265 test_secondary(lpGuid
,winetest_interactive
,0,0,0,1,0,0);
1267 /* Testing 3D secondary buffers */
1268 test_secondary(lpGuid
,winetest_interactive
,1,0,0,0,0,0);
1269 test_secondary(lpGuid
,winetest_interactive
,1,1,0,0,0,0);
1270 test_secondary(lpGuid
,winetest_interactive
,1,1,0,1,0,0);
1271 test_secondary(lpGuid
,winetest_interactive
,1,0,1,0,0,0);
1272 test_secondary(lpGuid
,winetest_interactive
,1,0,1,1,0,0);
1273 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,0,0);
1274 test_secondary(lpGuid
,winetest_interactive
,1,1,1,1,0,0);
1275 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,1,0);
1276 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,0,1);
1277 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,1,1);
1282 static void ds3d_tests(void)
1285 rc
=DirectSoundEnumerateA(&dsenum_callback
,NULL
);
1286 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc
));
1293 trace("DLL Version: %s\n", get_file_version("dsound.dll"));