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
30 #include "wine/test.h"
34 #include "dsound_test.h"
36 #define PI 3.14159265358979323846
39 static HRESULT (WINAPI
*pDirectSoundEnumerateA
)(LPDSENUMCALLBACKA
,LPVOID
)=NULL
;
40 static HRESULT (WINAPI
*pDirectSoundCreate
)(LPCGUID
,LPDIRECTSOUND
*,
43 char* wave_generate_la(WAVEFORMATEX
* wfx
, double duration
, DWORD
* size
)
50 nb_samples
=(int)(duration
*wfx
->nSamplesPerSec
);
51 *size
=nb_samples
*wfx
->nBlockAlign
;
53 for (i
=0;i
<nb_samples
;i
++) {
54 double y
=sin(440.0*2*PI
*i
/wfx
->nSamplesPerSec
);
55 if (wfx
->wBitsPerSample
==8) {
56 unsigned char sample
=(unsigned char)((double)127.5*(y
+1.0));
58 if (wfx
->nChannels
==2)
60 } else if (wfx
->wBitsPerSample
== 16) {
61 signed short sample
=(signed short)((double)32767.5*y
-0.5);
65 if (wfx
->nChannels
==2) {
70 } else if (wfx
->wBitsPerSample
== 24) {
71 signed int sample
=(signed int)((double)8388607.5*y
-0.5);
73 b
[1]=(sample
>> 8)&0xff;
76 if (wfx
->nChannels
==2) {
78 b
[1]=(sample
>> 8)&0xff;
82 } else if (wfx
->wBitsPerSample
== 32) {
83 signed int sample
=(signed int)((double)2147483647.5*y
-0.5);
85 b
[1]=(sample
>> 8)&0xff;
86 b
[2]=(sample
>> 16)&0xff;
89 if (wfx
->nChannels
==2) {
91 b
[1]=(sample
>> 8)&0xff;
92 b
[2]=(sample
>> 16)&0xff;
101 const char * getDSBCAPS(DWORD xmask
) {
106 #define FE(x) { x, #x },
107 FE(DSBCAPS_PRIMARYBUFFER
)
109 FE(DSBCAPS_LOCHARDWARE
)
110 FE(DSBCAPS_LOCSOFTWARE
)
112 FE(DSBCAPS_CTRLFREQUENCY
)
114 FE(DSBCAPS_CTRLVOLUME
)
115 FE(DSBCAPS_CTRLPOSITIONNOTIFY
)
116 FE(DSBCAPS_STICKYFOCUS
)
117 FE(DSBCAPS_GLOBALFOCUS
)
118 FE(DSBCAPS_GETCURRENTPOSITION2
)
119 FE(DSBCAPS_MUTE3DATMAXDISTANCE
)
122 static char buffer
[512];
128 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++) {
129 if ((flags
[i
].mask
& xmask
) == flags
[i
].mask
) {
134 strcat(buffer
, flags
[i
].name
);
143 HWND hwnd
=GetForegroundWindow();
145 hwnd
=GetDesktopWindow();
149 void init_format(WAVEFORMATEX
* wfx
, int format
, int rate
, int depth
,
152 wfx
->wFormatTag
=format
;
153 wfx
->nChannels
=channels
;
154 wfx
->wBitsPerSample
=depth
;
155 wfx
->nSamplesPerSec
=rate
;
156 wfx
->nBlockAlign
=wfx
->nChannels
*wfx
->wBitsPerSample
/8;
157 /* FIXME: Shouldn't this test be if (format!=WAVE_FORMAT_PCM) */
158 if (wfx
->nBlockAlign
==0)
160 /* align compressed formats to byte boundary */
163 wfx
->nAvgBytesPerSec
=wfx
->nSamplesPerSec
*wfx
->nBlockAlign
;
171 LPDIRECTSOUNDBUFFER dsbo
;
179 static int buffer_refill(play_state_t
* state
, DWORD size
)
185 if (size
>state
->wave_len
-state
->written
)
186 size
=state
->wave_len
-state
->written
;
188 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
189 &ptr1
,&len1
,&ptr2
,&len2
,0);
190 ok(rc
==DS_OK
,"IDirectSoundBuffer_Lock() failed: %s\n",
191 DXGetErrorString8(rc
));
195 memcpy(ptr1
,state
->wave
+state
->written
,len1
);
196 state
->written
+=len1
;
198 memcpy(ptr2
,state
->wave
+state
->written
,len2
);
199 state
->written
+=len2
;
201 state
->offset
=state
->written
% state
->buffer_size
;
202 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,ptr1
,len1
,ptr2
,len2
);
203 ok(rc
==DS_OK
,"IDirectSoundBuffer_Unlock() failed: %s\n",
204 DXGetErrorString8(rc
));
210 static int buffer_silence(play_state_t
* state
, DWORD size
)
217 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
218 &ptr1
,&len1
,&ptr2
,&len2
,0);
219 ok(rc
==DS_OK
,"IDirectSoundBuffer_Lock() failed: %s\n",
220 DXGetErrorString8(rc
));
224 s
=(state
->wfx
->wBitsPerSample
==8?0x80:0);
229 state
->offset
=(state
->offset
+size
) % state
->buffer_size
;
230 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,ptr1
,len1
,ptr2
,len2
);
231 ok(rc
==DS_OK
,"IDirectSoundBuffer_Unlock() failed: %s\n",
232 DXGetErrorString8(rc
));
238 static int buffer_service(play_state_t
* state
)
240 DWORD last_play_pos
,play_pos
,buf_free
;
243 rc
=IDirectSoundBuffer_GetCurrentPosition(state
->dsbo
,&play_pos
,NULL
);
244 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCurrentPosition() failed: %s\n",
245 DXGetErrorString8(rc
));
250 /* Update the amount played */
251 last_play_pos
=state
->played
% state
->buffer_size
;
252 if (play_pos
<last_play_pos
)
253 state
->played
+=state
->buffer_size
-last_play_pos
+play_pos
;
255 state
->played
+=play_pos
-last_play_pos
;
257 if (winetest_debug
> 1)
258 trace("buf size=%d last_play_pos=%d play_pos=%d played=%d / %d\n",
259 state
->buffer_size
,last_play_pos
,play_pos
,state
->played
,
262 if (state
->played
>state
->wave_len
)
264 /* Everything has been played */
268 /* Refill the buffer */
269 if (state
->offset
<=play_pos
)
270 buf_free
=play_pos
-state
->offset
;
272 buf_free
=state
->buffer_size
-state
->offset
+play_pos
;
274 if (winetest_debug
> 1)
275 trace("offset=%d free=%d written=%d / %d\n",
276 state
->offset
,buf_free
,state
->written
,state
->wave_len
);
280 if (state
->written
<state
->wave_len
)
282 int w
=buffer_refill(state
,buf_free
);
286 if (state
->written
==state
->wave_len
&& winetest_debug
> 1)
287 trace("last sound byte at %d\n",
288 (state
->written
% state
->buffer_size
));
292 /* Fill with silence */
293 if (winetest_debug
> 1)
294 trace("writing %d bytes of silence\n",buf_free
);
295 if (buffer_silence(state
,buf_free
)==-1)
301 if (winetest_debug
> 1)
302 trace("stopping playback\n");
303 rc
=IDirectSoundBuffer_Stop(state
->dsbo
);
304 ok(rc
==DS_OK
,"IDirectSoundBuffer_Stop() failed: %s\n",
305 DXGetErrorString8(rc
));
309 void test_buffer(LPDIRECTSOUND dso
, LPDIRECTSOUNDBUFFER
*dsbo
,
310 BOOL is_primary
, BOOL set_volume
, LONG volume
,
311 BOOL set_pan
, LONG pan
, BOOL play
, double duration
,
312 BOOL buffer3d
, LPDIRECTSOUND3DLISTENER listener
,
313 BOOL move_listener
, BOOL move_sound
,
314 BOOL set_frequency
, DWORD frequency
)
318 WAVEFORMATEX wfx
,wfx2
;
319 DWORD size
,status
,freq
;
323 rc
=IDirectSoundBuffer_SetFrequency(*dsbo
,frequency
);
324 ok(rc
==DS_OK
||rc
==DSERR_CONTROLUNAVAIL
,
325 "IDirectSoundBuffer_SetFrequency() failed to set frequency "
326 "%s\n",DXGetErrorString8(rc
));
331 /* DSOUND: Error: Invalid caps pointer */
332 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,0);
333 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetCaps() should have "
334 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
336 ZeroMemory(&dsbcaps
, sizeof(dsbcaps
));
338 /* DSOUND: Error: Invalid caps pointer */
339 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&dsbcaps
);
340 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetCaps() should have "
341 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
343 dsbcaps
.dwSize
=sizeof(dsbcaps
);
344 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&dsbcaps
);
345 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() failed: %s\n",
346 DXGetErrorString8(rc
));
347 if (rc
==DS_OK
&& winetest_debug
> 1) {
348 trace(" Caps: flags=0x%08x size=%d\n",dsbcaps
.dwFlags
,
349 dsbcaps
.dwBufferBytes
);
352 /* Query the format size. */
354 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,NULL
,0,&size
);
355 ok(rc
==DS_OK
&& size
!=0,"IDirectSoundBuffer_GetFormat() should have "
356 "returned the needed size: rc=%s size=%d\n",DXGetErrorString8(rc
),size
);
358 ok(size
== sizeof(WAVEFORMATEX
) || size
== sizeof(WAVEFORMATEXTENSIBLE
),
359 "Expected a correct structure size, got %d\n", size
);
361 if (size
== sizeof(WAVEFORMATEX
)) {
362 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,&wfx
,size
,NULL
);
364 else if (size
== sizeof(WAVEFORMATEXTENSIBLE
)) {
365 WAVEFORMATEXTENSIBLE wfxe
;
366 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,(WAVEFORMATEX
*)&wfxe
,size
,NULL
);
370 "IDirectSoundBuffer_GetFormat() failed: %s\n", DXGetErrorString8(rc
));
371 if (rc
==DS_OK
&& winetest_debug
> 1) {
372 trace(" Format: %s tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
373 is_primary
? "Primary" : "Secondary",
374 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
375 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
378 /* DSOUND: Error: Invalid frequency buffer */
379 rc
=IDirectSoundBuffer_GetFrequency(*dsbo
,0);
380 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetFrequency() should have "
381 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
383 /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */
384 rc
=IDirectSoundBuffer_GetFrequency(*dsbo
,&freq
);
385 ok((rc
==DS_OK
&& !is_primary
) || (rc
==DSERR_CONTROLUNAVAIL
&&is_primary
) ||
386 (rc
==DSERR_CONTROLUNAVAIL
&&!(dsbcaps
.dwFlags
&DSBCAPS_CTRLFREQUENCY
)),
387 "IDirectSoundBuffer_GetFrequency() failed: %s\n",DXGetErrorString8(rc
));
389 DWORD f
= set_frequency
?frequency
:wfx
.nSamplesPerSec
;
390 ok(freq
==f
,"The frequency returned by GetFrequency "
391 "%d does not match the format %d\n",freq
,f
);
394 /* DSOUND: Error: Invalid status pointer */
395 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,0);
396 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetStatus() should have "
397 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
399 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,&status
);
400 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetStatus() failed: %s\n",
401 DXGetErrorString8(rc
));
402 ok(status
==0,"status=0x%x instead of 0\n",status
);
406 /* We must call SetCooperativeLevel to be allowed to call SetFormat */
407 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
408 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
409 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
410 "%s\n",DXGetErrorString8(rc
));
414 /* DSOUND: Error: Invalid format pointer */
415 rc
=IDirectSoundBuffer_SetFormat(*dsbo
,0);
416 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_SetFormat() should have "
417 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
419 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
420 rc
=IDirectSoundBuffer_SetFormat(*dsbo
,&wfx2
);
421 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat(%s) failed: %s\n",
422 format_string(&wfx2
), DXGetErrorString8(rc
));
424 /* There is no guarantee that SetFormat will actually change the
425 * format to what we asked for. It depends on what the soundcard
426 * supports. So we must re-query the format.
428 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,&wfx
,sizeof(wfx
),NULL
);
429 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %s\n",
430 DXGetErrorString8(rc
));
432 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
433 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
434 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
435 wfx
.nChannels
!=wfx2
.nChannels
)) {
436 trace("Requested format tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
437 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
438 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
439 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
440 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
441 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
444 ZeroMemory(&new_dsbcaps
, sizeof(new_dsbcaps
));
445 new_dsbcaps
.dwSize
= sizeof(new_dsbcaps
);
446 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&new_dsbcaps
);
447 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() failed: %s\n",
448 DXGetErrorString8(rc
));
449 if (rc
==DS_OK
&& winetest_debug
> 1) {
450 trace(" new Caps: flags=0x%08x size=%d\n",new_dsbcaps
.dwFlags
,
451 new_dsbcaps
.dwBufferBytes
);
454 /* Check for primary buffer size change */
455 ok(new_dsbcaps
.dwBufferBytes
== dsbcaps
.dwBufferBytes
,
456 " buffer size changed after SetFormat() - "
457 "previous size was %u, current size is %u\n",
458 dsbcaps
.dwBufferBytes
, new_dsbcaps
.dwBufferBytes
);
459 dsbcaps
.dwBufferBytes
= new_dsbcaps
.dwBufferBytes
;
461 /* Check for primary buffer flags change */
462 ok(new_dsbcaps
.dwFlags
== dsbcaps
.dwFlags
,
463 " flags changed after SetFormat() - "
464 "previous flags were %08x, current flags are %08x\n",
465 dsbcaps
.dwFlags
, new_dsbcaps
.dwFlags
);
467 /* Set the CooperativeLevel back to normal */
468 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
469 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
470 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: "
471 "%s\n",DXGetErrorString8(rc
));
476 DS3DLISTENER listener_param
;
477 LPDIRECTSOUND3DBUFFER buffer
=NULL
;
478 DS3DBUFFER buffer_param
;
479 DWORD start_time
,now
;
483 if (winetest_interactive
) {
485 trace(" Playing %g second 440Hz tone at %dx%dx%d with a "
486 "frequency of %d (%dHz)\n", duration
,
487 wfx
.nSamplesPerSec
, wfx
.wBitsPerSample
, wfx
.nChannels
,
488 frequency
, (440 * frequency
) / wfx
.nSamplesPerSec
);
490 trace(" Playing %g second 440Hz tone at %dx%dx%d\n", duration
,
491 wfx
.nSamplesPerSec
, wfx
.wBitsPerSample
, wfx
.nChannels
);
495 /* We must call SetCooperativeLevel to be allowed to call Lock */
496 /* DSOUND: Setting DirectSound cooperative level to
497 * DSSCL_WRITEPRIMARY */
498 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),
500 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_WRITEPRIMARY) "
501 "failed: %s\n",DXGetErrorString8(rc
));
506 LPDIRECTSOUNDBUFFER temp_buffer
;
508 rc
=IDirectSoundBuffer_QueryInterface(*dsbo
,&IID_IDirectSound3DBuffer
,
510 ok(rc
==DS_OK
,"IDirectSoundBuffer_QueryInterface() failed: %s\n",
511 DXGetErrorString8(rc
));
515 /* check the COM interface */
516 rc
=IDirectSoundBuffer_QueryInterface(*dsbo
, &IID_IDirectSoundBuffer
,
517 (LPVOID
*)&temp_buffer
);
518 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
519 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
520 DXGetErrorString8(rc
));
521 ok(temp_buffer
==*dsbo
,"COM interface broken: %p != %p\n",
523 ref
=IDirectSoundBuffer_Release(temp_buffer
);
524 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
525 "should have 1\n",ref
);
528 rc
=IDirectSound3DBuffer_QueryInterface(*dsbo
,
529 &IID_IDirectSoundBuffer
,
530 (LPVOID
*)&temp_buffer
);
531 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
532 "IDirectSound3DBuffer_QueryInterface() failed: %s\n",
533 DXGetErrorString8(rc
));
534 ok(temp_buffer
==*dsbo
,"COM interface broken: %p != %p\n",
536 ref
=IDirectSoundBuffer_Release(temp_buffer
);
537 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
538 "should have 1\n",ref
);
540 ref
=IDirectSoundBuffer_Release(*dsbo
);
541 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
542 "should have 0\n",ref
);
544 rc
=IDirectSound3DBuffer_QueryInterface(buffer
,
545 &IID_IDirectSoundBuffer
,
547 ok(rc
==DS_OK
&& *dsbo
!=NULL
,"IDirectSound3DBuffer_QueryInterface() "
548 "failed: %s\n",DXGetErrorString8(rc
));
550 /* DSOUND: Error: Invalid buffer */
551 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,0);
552 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound3DBuffer_GetAllParameters() "
553 "failed: %s\n",DXGetErrorString8(rc
));
555 ZeroMemory(&buffer_param
, sizeof(buffer_param
));
557 /* DSOUND: Error: Invalid buffer */
558 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,&buffer_param
);
559 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound3DBuffer_GetAllParameters() "
560 "failed: %s\n",DXGetErrorString8(rc
));
562 buffer_param
.dwSize
=sizeof(buffer_param
);
563 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,&buffer_param
);
564 ok(rc
==DS_OK
,"IDirectSound3DBuffer_GetAllParameters() failed: %s\n",
565 DXGetErrorString8(rc
));
568 if (dsbcaps
.dwFlags
& DSBCAPS_CTRLVOLUME
) {
570 rc
=IDirectSoundBuffer_GetVolume(*dsbo
,&val
);
571 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %s\n",
572 DXGetErrorString8(rc
));
574 rc
=IDirectSoundBuffer_SetVolume(*dsbo
,volume
);
575 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume() failed: %s\n",
576 DXGetErrorString8(rc
));
578 /* DSOUND: Error: Buffer does not have CTRLVOLUME */
579 rc
=IDirectSoundBuffer_GetVolume(*dsbo
,&volume
);
580 ok(rc
==DSERR_CONTROLUNAVAIL
,"IDirectSoundBuffer_GetVolume() "
581 "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
582 DXGetErrorString8(rc
));
587 if (dsbcaps
.dwFlags
& DSBCAPS_CTRLPAN
) {
589 rc
=IDirectSoundBuffer_GetPan(*dsbo
,&val
);
590 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan() failed: %s\n",
591 DXGetErrorString8(rc
));
593 rc
=IDirectSoundBuffer_SetPan(*dsbo
,pan
);
594 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan() failed: %s\n",
595 DXGetErrorString8(rc
));
597 /* DSOUND: Error: Buffer does not have CTRLPAN */
598 rc
=IDirectSoundBuffer_GetPan(*dsbo
,&pan
);
599 ok(rc
==DSERR_CONTROLUNAVAIL
,"IDirectSoundBuffer_GetPan() "
600 "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
601 DXGetErrorString8(rc
));
605 /* try an offset past the end of the buffer */
606 rc
= IDirectSoundBuffer_Lock(*dsbo
, dsbcaps
.dwBufferBytes
, 0, &buffer1
,
607 &length1
, NULL
, NULL
,
608 DSBLOCK_ENTIREBUFFER
);
609 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSoundBuffer_Lock() should have "
610 "returned DSERR_INVALIDPARAM, returned %s\n", DXGetErrorString8(rc
));
612 /* try a size larger than the buffer */
613 rc
= IDirectSoundBuffer_Lock(*dsbo
, 0, dsbcaps
.dwBufferBytes
+ 1,
614 &buffer1
, &length1
, NULL
, NULL
,
615 DSBLOCK_FROMWRITECURSOR
);
616 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSoundBuffer_Lock() should have "
617 "returned DSERR_INVALIDPARAM, returned %s\n", DXGetErrorString8(rc
));
620 state
.wave
=wave_generate_la(&wfx
,(duration
*frequency
)/wfx
.nSamplesPerSec
,&state
.wave_len
);
622 state
.wave
=wave_generate_la(&wfx
,duration
,&state
.wave_len
);
626 state
.buffer_size
=dsbcaps
.dwBufferBytes
;
627 state
.played
=state
.written
=state
.offset
=0;
628 buffer_refill(&state
,state
.buffer_size
);
630 rc
=IDirectSoundBuffer_Play(*dsbo
,0,0,DSBPLAY_LOOPING
);
631 ok(rc
==DS_OK
,"IDirectSoundBuffer_Play() failed: %s\n",
632 DXGetErrorString8(rc
));
634 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,&status
);
635 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetStatus() failed: %s\n",
636 DXGetErrorString8(rc
));
637 ok(status
==(DSBSTATUS_PLAYING
|DSBSTATUS_LOOPING
),
638 "GetStatus: bad status: %x\n",status
);
641 ZeroMemory(&listener_param
,sizeof(listener_param
));
642 listener_param
.dwSize
=sizeof(listener_param
);
643 rc
=IDirectSound3DListener_GetAllParameters(listener
,
645 ok(rc
==DS_OK
,"IDirectSound3dListener_GetAllParameters() "
646 "failed: %s\n",DXGetErrorString8(rc
));
648 listener_param
.vPosition
.x
= -5.0f
;
649 listener_param
.vVelocity
.x
= (float)(10.0/duration
);
651 rc
=IDirectSound3DListener_SetAllParameters(listener
,
654 ok(rc
==DS_OK
,"IDirectSound3dListener_SetPosition() failed: %s\n",
655 DXGetErrorString8(rc
));
659 buffer_param
.vPosition
.x
= 100.0f
;
660 buffer_param
.vVelocity
.x
= (float)(-200.0/duration
);
662 buffer_param
.flMinDistance
= 10;
663 rc
=IDirectSound3DBuffer_SetAllParameters(buffer
,&buffer_param
,
665 ok(rc
==DS_OK
,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
666 DXGetErrorString8(rc
));
669 start_time
=GetTickCount();
670 while (buffer_service(&state
)) {
671 WaitForSingleObject(GetCurrentProcess(),TIME_SLICE
);
673 if (listener
&& move_listener
) {
674 listener_param
.vPosition
.x
= (float)(-5.0+10.0*(now
-start_time
)/1000/duration
);
675 if (winetest_debug
>2)
676 trace("listener position=%g\n",listener_param
.vPosition
.x
);
677 rc
=IDirectSound3DListener_SetPosition(listener
,
678 listener_param
.vPosition
.x
,listener_param
.vPosition
.y
,
679 listener_param
.vPosition
.z
,DS3D_IMMEDIATE
);
680 ok(rc
==DS_OK
,"IDirectSound3dListener_SetPosition() failed: "
681 "%s\n",DXGetErrorString8(rc
));
683 if (buffer3d
&& move_sound
) {
684 buffer_param
.vPosition
.x
= (float)(100-200.0*(now
-start_time
)/1000/duration
);
685 if (winetest_debug
>2)
686 trace("sound position=%g\n",buffer_param
.vPosition
.x
);
687 rc
=IDirectSound3DBuffer_SetPosition(buffer
,
688 buffer_param
.vPosition
.x
,buffer_param
.vPosition
.y
,
689 buffer_param
.vPosition
.z
,DS3D_IMMEDIATE
);
690 ok(rc
==DS_OK
,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
691 DXGetErrorString8(rc
));
694 /* Check the sound duration was within 10% of the expected value */
696 ok(fabs(1000*duration
-now
+start_time
)<=100*duration
,
697 "The sound played for %d ms instead of %g ms\n",
698 now
-start_time
,1000*duration
);
702 /* Set the CooperativeLevel back to normal */
703 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
704 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
705 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) "
706 "failed: %s\n",DXGetErrorString8(rc
));
709 ref
=IDirectSound3DBuffer_Release(buffer
);
710 ok(ref
==0,"IDirectSound3DBuffer_Release() has %d references, "
711 "should have 0\n",ref
);
716 static HRESULT
test_secondary(LPGUID lpGuid
, int play
,
717 int has_3d
, int has_3dbuffer
,
718 int has_listener
, int has_duplicate
,
719 int move_listener
, int move_sound
)
722 LPDIRECTSOUND dso
=NULL
;
723 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
724 LPDIRECTSOUND3DLISTENER listener
=NULL
;
725 DSBUFFERDESC bufdesc
;
726 WAVEFORMATEX wfx
, wfx1
;
729 /* Create the DirectSound object */
730 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
731 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
732 DXGetErrorString8(rc
));
736 /* We must call SetCooperativeLevel before creating primary buffer */
737 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
738 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
739 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
740 "%s\n",DXGetErrorString8(rc
));
744 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
745 bufdesc
.dwSize
=sizeof(bufdesc
);
746 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
748 bufdesc
.dwFlags
|=DSBCAPS_CTRL3D
;
750 bufdesc
.dwFlags
|=(DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
);
751 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
752 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
753 "IDirectSound_CreateSoundBuffer() failed to create a %sprimary buffer: "
754 "%s\n",has_3d
?"3D ":"", DXGetErrorString8(rc
));
755 if (rc
==DSERR_CONTROLUNAVAIL
)
756 trace(" No Primary\n");
757 else if (rc
==DS_OK
&& primary
!=NULL
) {
758 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
759 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %s\n",
760 DXGetErrorString8(rc
));
765 rc
=IDirectSoundBuffer_QueryInterface(primary
,
766 &IID_IDirectSound3DListener
,
768 ok(rc
==DS_OK
&& listener
!=NULL
,
769 "IDirectSoundBuffer_QueryInterface() failed to get a 3D "
770 "listener: %s\n",DXGetErrorString8(rc
));
771 ref
=IDirectSoundBuffer_Release(primary
);
772 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
773 "should have 0\n",ref
);
774 if (rc
==DS_OK
&& listener
!=NULL
) {
775 DS3DLISTENER listener_param
;
776 ZeroMemory(&listener_param
,sizeof(listener_param
));
777 /* DSOUND: Error: Invalid buffer */
778 rc
=IDirectSound3DListener_GetAllParameters(listener
,0);
779 ok(rc
==DSERR_INVALIDPARAM
,
780 "IDirectSound3dListener_GetAllParameters() should have "
781 "returned DSERR_INVALIDPARAM, returned: %s\n",
782 DXGetErrorString8(rc
));
784 /* DSOUND: Error: Invalid buffer */
785 rc
=IDirectSound3DListener_GetAllParameters(listener
,
787 ok(rc
==DSERR_INVALIDPARAM
,
788 "IDirectSound3dListener_GetAllParameters() should have "
789 "returned DSERR_INVALIDPARAM, returned: %s\n",
790 DXGetErrorString8(rc
));
792 listener_param
.dwSize
=sizeof(listener_param
);
793 rc
=IDirectSound3DListener_GetAllParameters(listener
,
795 ok(rc
==DS_OK
,"IDirectSound3dListener_GetAllParameters() "
796 "failed: %s\n",DXGetErrorString8(rc
));
798 ok(listener
==NULL
, "IDirectSoundBuffer_QueryInterface() "
799 "failed but returned a listener anyway\n");
800 ok(rc
!=DS_OK
, "IDirectSoundBuffer_QueryInterface() succeeded "
801 "but returned a NULL listener\n");
803 ref
=IDirectSound3DListener_Release(listener
);
804 ok(ref
==0,"IDirectSound3dListener_Release() listener has "
805 "%d references, should have 0\n",ref
);
811 init_format(&wfx
,WAVE_FORMAT_PCM
,22050,16,2);
813 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
814 bufdesc
.dwSize
=sizeof(bufdesc
);
815 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
817 bufdesc
.dwFlags
|=DSBCAPS_CTRL3D
;
820 (DSBCAPS_CTRLFREQUENCY
|DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
);
821 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
823 bufdesc
.lpwfxFormat
=&wfx
;
824 if (winetest_interactive
) {
825 trace(" Testing a %s%ssecondary buffer %s%s%s%sat %dx%dx%d "
826 "with a primary buffer at %dx%dx%d\n",
827 has_3dbuffer
?"3D ":"",
828 has_duplicate
?"duplicated ":"",
829 listener
!=NULL
||move_sound
?"with ":"",
830 move_listener
?"moving ":"",
831 listener
!=NULL
?"listener ":"",
832 listener
&&move_sound
?"and moving sound ":move_sound
?
834 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
835 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
837 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
838 ok(rc
==DS_OK
&& secondary
!=NULL
,"IDirectSound_CreateSoundBuffer() "
839 "failed to create a %s%ssecondary buffer %s%s%s%sat %dx%dx%d (%s): %s\n",
840 has_3dbuffer
?"3D ":"", has_duplicate
?"duplicated ":"",
841 listener
!=NULL
||move_sound
?"with ":"", move_listener
?"moving ":"",
842 listener
!=NULL
?"listener ":"",
843 listener
&&move_sound
?"and moving sound ":move_sound
?
845 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
846 getDSBCAPS(bufdesc
.dwFlags
),DXGetErrorString8(rc
));
847 if (rc
==DS_OK
&& secondary
!=NULL
) {
849 LONG refvol
,vol
,refpan
,pan
;
851 /* Check the initial secondary buffer's volume and pan */
852 rc
=IDirectSoundBuffer_GetVolume(secondary
,&vol
);
853 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(secondary) failed: "
854 "%s\n",DXGetErrorString8(rc
));
855 ok(vol
==0,"wrong volume for a new secondary buffer: %d\n",vol
);
856 rc
=IDirectSoundBuffer_GetPan(secondary
,&pan
);
857 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(secondary) failed: "
858 "%s\n",DXGetErrorString8(rc
));
859 ok(pan
==0,"wrong pan for a new secondary buffer: %d\n",pan
);
861 /* Check that changing the secondary buffer's volume and pan
862 * does not impact the primary buffer's volume and pan
864 rc
=IDirectSoundBuffer_GetVolume(primary
,&refvol
);
865 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(primary) failed: "
866 "%s\n",DXGetErrorString8(rc
));
867 rc
=IDirectSoundBuffer_GetPan(primary
,&refpan
);
868 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
869 DXGetErrorString8(rc
));
871 rc
=IDirectSoundBuffer_SetVolume(secondary
,-1000);
872 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: "
873 "%s\n",DXGetErrorString8(rc
));
874 rc
=IDirectSoundBuffer_GetVolume(secondary
,&vol
);
875 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: "
876 "%s\n",DXGetErrorString8(rc
));
877 ok(vol
==-1000,"secondary: wrong volume %d instead of -1000\n",
879 rc
=IDirectSoundBuffer_SetPan(secondary
,-1000);
880 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: "
881 "%s\n",DXGetErrorString8(rc
));
882 rc
=IDirectSoundBuffer_GetPan(secondary
,&pan
);
883 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: "
884 "%s\n",DXGetErrorString8(rc
));
885 ok(pan
==-1000,"secondary: wrong pan %d instead of -1000\n",
888 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
889 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(primary) failed: "
890 "%s\n",DXGetErrorString8(rc
));
891 ok(vol
==refvol
,"The primary volume changed from %d to %d\n",
893 rc
=IDirectSoundBuffer_GetPan(primary
,&pan
);
894 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
895 DXGetErrorString8(rc
));
896 ok(pan
==refpan
,"The primary pan changed from %d to %d\n",
899 rc
=IDirectSoundBuffer_SetVolume(secondary
,0);
900 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: "
901 "%s\n",DXGetErrorString8(rc
));
902 rc
=IDirectSoundBuffer_SetPan(secondary
,0);
903 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: "
904 "%s\n",DXGetErrorString8(rc
));
907 LPDIRECTSOUNDBUFFER duplicated
=NULL
;
909 /* DSOUND: Error: Invalid source buffer */
910 rc
=IDirectSound_DuplicateSoundBuffer(dso
,0,0);
911 ok(rc
==DSERR_INVALIDPARAM
,
912 "IDirectSound_DuplicateSoundBuffer() should have returned "
913 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
915 /* DSOUND: Error: Invalid dest buffer */
916 rc
=IDirectSound_DuplicateSoundBuffer(dso
,secondary
,0);
917 ok(rc
==DSERR_INVALIDPARAM
,
918 "IDirectSound_DuplicateSoundBuffer() should have returned "
919 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
921 /* DSOUND: Error: Invalid source buffer */
922 rc
=IDirectSound_DuplicateSoundBuffer(dso
,0,&duplicated
);
923 ok(rc
==DSERR_INVALIDPARAM
,
924 "IDirectSound_DuplicateSoundBuffer() should have returned "
925 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
928 rc
=IDirectSound_DuplicateSoundBuffer(dso
,secondary
,
930 ok(rc
==DS_OK
&& duplicated
!=NULL
,
931 "IDirectSound_DuplicateSoundBuffer() failed to duplicate "
932 "a secondary buffer: %s\n",DXGetErrorString8(rc
));
934 if (rc
==DS_OK
&& duplicated
!=NULL
) {
935 ref
=IDirectSoundBuffer_Release(secondary
);
936 ok(ref
==0,"IDirectSoundBuffer_Release() secondary has %d "
937 "references, should have 0\n",ref
);
938 secondary
=duplicated
;
942 if (rc
==DS_OK
&& secondary
!=NULL
) {
944 duration
=(move_listener
|| move_sound
?4.0:1.0);
945 test_buffer(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
946 winetest_interactive
,duration
,has_3dbuffer
,
947 listener
,move_listener
,move_sound
,FALSE
,0);
948 ref
=IDirectSoundBuffer_Release(secondary
);
949 ok(ref
==0,"IDirectSoundBuffer_Release() %s has %d references, "
950 "should have 0\n",has_duplicate
?"duplicated":"secondary",
956 ref
=IDirectSound3DListener_Release(listener
);
957 ok(ref
==0,"IDirectSound3dListener_Release() listener has %d "
958 "references, should have 0\n",ref
);
960 ref
=IDirectSoundBuffer_Release(primary
);
961 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
962 "should have 0\n",ref
);
965 ok(primary
==NULL
,"IDirectSound_CreateSoundBuffer(primary) failed "
966 "but primary created anyway\n");
967 ok(rc
!=DS_OK
,"IDirectSound_CreateSoundBuffer(primary) succeeded "
968 "but primary not created\n");
970 ref
=IDirectSoundBuffer_Release(primary
);
971 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
972 "should have 0\n",ref
);
976 /* Set the CooperativeLevel back to normal */
977 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
978 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
979 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
980 DXGetErrorString8(rc
));
983 ref
=IDirectSound_Release(dso
);
984 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
986 return DSERR_GENERIC
;
991 static HRESULT
test_for_driver(LPGUID lpGuid
)
994 LPDIRECTSOUND dso
=NULL
;
997 /* Create the DirectSound object */
998 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
999 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
1000 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
1004 ref
=IDirectSound_Release(dso
);
1005 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1007 return DSERR_GENERIC
;
1012 static HRESULT
test_primary(LPGUID lpGuid
)
1015 LPDIRECTSOUND dso
=NULL
;
1016 LPDIRECTSOUNDBUFFER primary
=NULL
;
1017 DSBUFFERDESC bufdesc
;
1021 /* Create the DirectSound object */
1022 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1023 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
1024 DXGetErrorString8(rc
));
1028 /* Get the device capabilities */
1029 ZeroMemory(&dscaps
, sizeof(dscaps
));
1030 dscaps
.dwSize
=sizeof(dscaps
);
1031 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1032 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
1036 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1037 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1038 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1039 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
1040 "%s\n",DXGetErrorString8(rc
));
1044 /* Testing the primary buffer */
1046 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1047 bufdesc
.dwSize
=sizeof(bufdesc
);
1048 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
;
1049 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1050 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
1051 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: "
1052 "%s\n",DXGetErrorString8(rc
));
1053 if (rc
==DSERR_CONTROLUNAVAIL
)
1054 trace(" No Primary\n");
1055 else if (rc
==DS_OK
&& primary
!=NULL
) {
1056 test_buffer(dso
,&primary
,1,TRUE
,0,TRUE
,0,winetest_interactive
&&
1057 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,NULL
,0,0,
1059 if (winetest_interactive
) {
1062 volume
= DSBVOLUME_MAX
;
1063 for (i
= 0; i
< 6; i
++) {
1064 test_buffer(dso
,&primary
,1,TRUE
,volume
,TRUE
,0,
1065 winetest_interactive
&&
1066 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),
1067 1.0,0,NULL
,0,0,FALSE
,0);
1068 volume
-= ((DSBVOLUME_MAX
-DSBVOLUME_MIN
) / 40);
1072 for (i
= 0; i
< 7; i
++) {
1073 test_buffer(dso
,&primary
,1,TRUE
,0,TRUE
,pan
,
1074 winetest_interactive
&&
1075 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,0,0,0,FALSE
,0);
1076 pan
+= ((DSBPAN_RIGHT
-DSBPAN_LEFT
) / 6);
1079 ref
=IDirectSoundBuffer_Release(primary
);
1080 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1081 "should have 0\n",ref
);
1084 /* Set the CooperativeLevel back to normal */
1085 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1086 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1087 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
1088 DXGetErrorString8(rc
));
1091 ref
=IDirectSound_Release(dso
);
1092 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1094 return DSERR_GENERIC
;
1099 static HRESULT
test_primary_3d(LPGUID lpGuid
)
1102 LPDIRECTSOUND dso
=NULL
;
1103 LPDIRECTSOUNDBUFFER primary
=NULL
;
1104 DSBUFFERDESC bufdesc
;
1108 /* Create the DirectSound object */
1109 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1110 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
1111 DXGetErrorString8(rc
));
1115 /* Get the device capabilities */
1116 ZeroMemory(&dscaps
, sizeof(dscaps
));
1117 dscaps
.dwSize
=sizeof(dscaps
);
1118 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1119 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
1123 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1124 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1125 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1126 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
1127 "%s\n",DXGetErrorString8(rc
));
1132 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1133 bufdesc
.dwSize
=sizeof(bufdesc
);
1134 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
1135 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1136 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1137 "to create a primary buffer: %s\n",DXGetErrorString8(rc
));
1138 if (rc
==DS_OK
&& primary
!=NULL
) {
1139 ref
=IDirectSoundBuffer_Release(primary
);
1140 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1141 "should have 0\n",ref
);
1143 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1144 bufdesc
.dwSize
=sizeof(bufdesc
);
1145 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRL3D
;
1146 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1147 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() "
1148 "failed to create a 3D primary buffer: %s\n",DXGetErrorString8(rc
));
1149 if (rc
==DS_OK
&& primary
!=NULL
) {
1150 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
1151 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,0,0,0,
1153 ref
=IDirectSoundBuffer_Release(primary
);
1154 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1155 "should have 0\n",ref
);
1158 /* Set the CooperativeLevel back to normal */
1159 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1160 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1161 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
1162 DXGetErrorString8(rc
));
1165 ref
=IDirectSound_Release(dso
);
1166 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1168 return DSERR_GENERIC
;
1173 static HRESULT
test_primary_3d_with_listener(LPGUID lpGuid
)
1176 LPDIRECTSOUND dso
=NULL
;
1177 LPDIRECTSOUNDBUFFER primary
=NULL
;
1178 DSBUFFERDESC bufdesc
;
1182 /* Create the DirectSound object */
1183 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1184 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
1185 DXGetErrorString8(rc
));
1189 /* Get the device capabilities */
1190 ZeroMemory(&dscaps
, sizeof(dscaps
));
1191 dscaps
.dwSize
=sizeof(dscaps
);
1192 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1193 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
1197 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1198 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1199 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1200 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
1201 "%s\n",DXGetErrorString8(rc
));
1205 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1206 bufdesc
.dwSize
=sizeof(bufdesc
);
1207 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRL3D
;
1208 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1209 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1210 "to create a 3D primary buffer: %s\n",DXGetErrorString8(rc
));
1211 if (rc
==DS_OK
&& primary
!=NULL
) {
1212 LPDIRECTSOUND3DLISTENER listener
=NULL
;
1213 rc
=IDirectSoundBuffer_QueryInterface(primary
,
1214 &IID_IDirectSound3DListener
,(void **)&listener
);
1215 ok(rc
==DS_OK
&& listener
!=NULL
,"IDirectSoundBuffer_QueryInterface() "
1216 "failed to get a 3D listener: %s\n",DXGetErrorString8(rc
));
1217 if (rc
==DS_OK
&& listener
!=NULL
) {
1218 LPDIRECTSOUNDBUFFER temp_buffer
=NULL
;
1220 /* Checking the COM interface */
1221 rc
=IDirectSoundBuffer_QueryInterface(primary
,
1222 &IID_IDirectSoundBuffer
,(LPVOID
*)&temp_buffer
);
1223 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1224 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
1225 DXGetErrorString8(rc
));
1226 ok(temp_buffer
==primary
,
1227 "COM interface broken: %p != %p\n",
1228 temp_buffer
,primary
);
1229 if (rc
==DS_OK
&& temp_buffer
!=NULL
) {
1230 ref
=IDirectSoundBuffer_Release(temp_buffer
);
1231 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
1232 "should have 1\n",ref
);
1235 rc
=IDirectSound3DListener_QueryInterface(listener
,
1236 &IID_IDirectSoundBuffer
,(LPVOID
*)&temp_buffer
);
1237 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1238 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
1239 DXGetErrorString8(rc
));
1240 ok(temp_buffer
==primary
,
1241 "COM interface broken: %p != %p\n",
1242 temp_buffer
,primary
);
1243 ref
=IDirectSoundBuffer_Release(temp_buffer
);
1244 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
1245 "should have 1\n",ref
);
1247 /* Testing the buffer */
1248 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,
1249 winetest_interactive
&&
1250 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,
1251 listener
,0,0,FALSE
,0);
1254 /* Testing the reference counting */
1255 ref
=IDirectSound3DListener_Release(listener
);
1256 ok(ref
==0,"IDirectSound3DListener_Release() listener has %d "
1257 "references, should have 0\n",ref
);
1260 /* Testing the reference counting */
1261 ref
=IDirectSoundBuffer_Release(primary
);
1262 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1263 "should have 0\n",ref
);
1267 ref
=IDirectSound_Release(dso
);
1268 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1270 return DSERR_GENERIC
;
1275 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
1276 LPCSTR lpcstrModule
, LPVOID lpContext
)
1279 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
1281 rc
= test_for_driver(lpGuid
);
1282 if (rc
== DSERR_NODRIVER
) {
1283 trace(" No Driver\n");
1285 } else if (rc
== DSERR_ALLOCATED
) {
1286 trace(" Already In Use\n");
1288 } else if (rc
== E_FAIL
) {
1289 trace(" No Device\n");
1293 trace(" Testing the primary buffer\n");
1294 test_primary(lpGuid
);
1296 trace(" Testing 3D primary buffer\n");
1297 test_primary_3d(lpGuid
);
1299 trace(" Testing 3D primary buffer with listener\n");
1300 test_primary_3d_with_listener(lpGuid
);
1302 /* Testing secondary buffers */
1303 test_secondary(lpGuid
,winetest_interactive
,0,0,0,0,0,0);
1304 test_secondary(lpGuid
,winetest_interactive
,0,0,0,1,0,0);
1306 /* Testing 3D secondary buffers */
1307 test_secondary(lpGuid
,winetest_interactive
,1,0,0,0,0,0);
1308 test_secondary(lpGuid
,winetest_interactive
,1,1,0,0,0,0);
1309 test_secondary(lpGuid
,winetest_interactive
,1,1,0,1,0,0);
1310 test_secondary(lpGuid
,winetest_interactive
,1,0,1,0,0,0);
1311 test_secondary(lpGuid
,winetest_interactive
,1,0,1,1,0,0);
1312 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,0,0);
1313 test_secondary(lpGuid
,winetest_interactive
,1,1,1,1,0,0);
1314 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,1,0);
1315 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,0,1);
1316 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,1,1);
1321 static void ds3d_tests(void)
1324 rc
=pDirectSoundEnumerateA(&dsenum_callback
,NULL
);
1325 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc
));
1334 hDsound
= LoadLibrary("dsound.dll");
1337 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
1339 pDirectSoundEnumerateA
= (void*)GetProcAddress(hDsound
,
1340 "DirectSoundEnumerateA");
1341 pDirectSoundCreate
= (void*)GetProcAddress(hDsound
,
1342 "DirectSoundCreate");
1346 FreeLibrary(hDsound
);
1349 skip("dsound.dll not found!\n");