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"
35 #include "dsound_test.h"
37 #define PI 3.14159265358979323846
40 static HRESULT (WINAPI
*pDirectSoundEnumerateA
)(LPDSENUMCALLBACKA
,LPVOID
)=NULL
;
41 static HRESULT (WINAPI
*pDirectSoundCreate
)(LPCGUID
,LPDIRECTSOUND
*,
44 char* wave_generate_la(WAVEFORMATEX
* wfx
, double duration
, DWORD
* size
, BOOL ieee
)
51 nb_samples
=(int)(duration
*wfx
->nSamplesPerSec
);
52 *size
=nb_samples
*wfx
->nBlockAlign
;
53 b
=buf
=HeapAlloc(GetProcessHeap(), 0, *size
);
54 for (i
=0;i
<nb_samples
;i
++) {
55 double y
=sin(440.0*2*PI
*i
/wfx
->nSamplesPerSec
);
56 if (wfx
->wBitsPerSample
==8) {
57 unsigned char sample
=127.5*(y
+1.0);
59 if (wfx
->nChannels
==2)
61 } else if (wfx
->wBitsPerSample
== 16) {
62 signed short sample
=32767.5*y
-0.5;
66 if (wfx
->nChannels
==2) {
71 } else if (wfx
->wBitsPerSample
== 24) {
72 signed int sample
=8388607.5*y
-0.5;
74 b
[1]=(sample
>> 8)&0xff;
77 if (wfx
->nChannels
==2) {
79 b
[1]=(sample
>> 8)&0xff;
83 } else if (wfx
->wBitsPerSample
== 32) {
85 float *ptr
= (float *) b
;
91 if (wfx
->nChannels
==2) {
96 signed int sample
=2147483647.5*y
-0.5;
98 b
[1]=(sample
>> 8)&0xff;
99 b
[2]=(sample
>> 16)&0xff;
102 if (wfx
->nChannels
==2) {
104 b
[1]=(sample
>> 8)&0xff;
105 b
[2]=(sample
>> 16)&0xff;
115 const char * getDSBCAPS(DWORD xmask
) {
120 #define FE(x) { x, #x },
121 FE(DSBCAPS_PRIMARYBUFFER
)
123 FE(DSBCAPS_LOCHARDWARE
)
124 FE(DSBCAPS_LOCSOFTWARE
)
126 FE(DSBCAPS_CTRLFREQUENCY
)
128 FE(DSBCAPS_CTRLVOLUME
)
129 FE(DSBCAPS_CTRLPOSITIONNOTIFY
)
130 FE(DSBCAPS_STICKYFOCUS
)
131 FE(DSBCAPS_GLOBALFOCUS
)
132 FE(DSBCAPS_GETCURRENTPOSITION2
)
133 FE(DSBCAPS_MUTE3DATMAXDISTANCE
)
136 static char buffer
[512];
142 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++) {
143 if ((flags
[i
].mask
& xmask
) == flags
[i
].mask
) {
148 strcat(buffer
, flags
[i
].name
);
157 HWND hwnd
=GetForegroundWindow();
159 hwnd
=GetDesktopWindow();
163 void init_format(WAVEFORMATEX
* wfx
, int format
, int rate
, int depth
,
166 wfx
->wFormatTag
=format
;
167 wfx
->nChannels
=channels
;
168 wfx
->wBitsPerSample
=depth
;
169 wfx
->nSamplesPerSec
=rate
;
170 wfx
->nBlockAlign
=wfx
->nChannels
*wfx
->wBitsPerSample
/8;
171 /* FIXME: Shouldn't this test be if (format!=WAVE_FORMAT_PCM) */
172 if (wfx
->nBlockAlign
==0)
174 /* align compressed formats to byte boundary */
177 wfx
->nAvgBytesPerSec
=wfx
->nSamplesPerSec
*wfx
->nBlockAlign
;
185 LPDIRECTSOUNDBUFFER dsbo
;
193 static int buffer_refill(play_state_t
* state
, DWORD size
)
199 if (size
>state
->wave_len
-state
->written
)
200 size
=state
->wave_len
-state
->written
;
202 /* some broken apps like Navyfield mistakenly pass NULL for a ppValue */
203 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
204 &ptr1
,NULL
,&ptr2
,&len2
,0);
205 ok(rc
==DSERR_INVALIDPARAM
,"expected %08x got %08x\n",DSERR_INVALIDPARAM
, rc
);
206 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
207 &ptr1
,&len1
,&ptr2
,&len2
,0);
208 ok(rc
==DS_OK
,"IDirectSoundBuffer_Lock() failed: %08x\n", rc
);
212 memcpy(ptr1
,state
->wave
+state
->written
,len1
);
213 state
->written
+=len1
;
215 memcpy(ptr2
,state
->wave
+state
->written
,len2
);
216 state
->written
+=len2
;
218 state
->offset
=state
->written
% state
->buffer_size
;
219 /* some apps blindly pass &ptr1 instead of ptr1 */
220 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,&ptr1
,len1
,ptr2
,len2
);
221 ok(rc
==DSERR_INVALIDPARAM
, "IDDirectSoundBuffer_Unlock(): expected %08x got %08x, %p %p\n",DSERR_INVALIDPARAM
, rc
, &ptr1
, ptr1
);
222 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,ptr1
,len1
,ptr2
,len2
);
223 ok(rc
==DS_OK
,"IDirectSoundBuffer_Unlock() failed: %08x\n", rc
);
229 static int buffer_silence(play_state_t
* state
, DWORD size
)
236 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
237 &ptr1
,&len1
,&ptr2
,&len2
,0);
238 ok(rc
==DS_OK
,"IDirectSoundBuffer_Lock() failed: %08x\n", rc
);
242 s
=(state
->wfx
->wBitsPerSample
==8?0x80:0);
247 state
->offset
=(state
->offset
+size
) % state
->buffer_size
;
248 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,ptr1
,len1
,ptr2
,len2
);
249 ok(rc
==DS_OK
,"IDirectSoundBuffer_Unlock() failed: %08x\n", rc
);
255 static int buffer_service(play_state_t
* state
)
257 DWORD last_play_pos
,play_pos
,buf_free
;
260 rc
=IDirectSoundBuffer_GetCurrentPosition(state
->dsbo
,&play_pos
,NULL
);
261 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCurrentPosition() failed: %08x\n", rc
);
266 /* Update the amount played */
267 last_play_pos
=state
->played
% state
->buffer_size
;
268 if (play_pos
<last_play_pos
)
269 state
->played
+=state
->buffer_size
-last_play_pos
+play_pos
;
271 state
->played
+=play_pos
-last_play_pos
;
273 if (winetest_debug
> 1)
274 trace("buf size=%d last_play_pos=%d play_pos=%d played=%d / %d\n",
275 state
->buffer_size
,last_play_pos
,play_pos
,state
->played
,
278 if (state
->played
>state
->wave_len
)
280 /* Everything has been played */
284 /* Refill the buffer */
285 if (state
->offset
<=play_pos
)
286 buf_free
=play_pos
-state
->offset
;
288 buf_free
=state
->buffer_size
-state
->offset
+play_pos
;
290 if (winetest_debug
> 1)
291 trace("offset=%d free=%d written=%d / %d\n",
292 state
->offset
,buf_free
,state
->written
,state
->wave_len
);
296 if (state
->written
<state
->wave_len
)
298 int w
=buffer_refill(state
,buf_free
);
302 if (state
->written
==state
->wave_len
&& winetest_debug
> 1)
303 trace("last sound byte at %d\n",
304 (state
->written
% state
->buffer_size
));
308 /* Fill with silence */
309 if (winetest_debug
> 1)
310 trace("writing %d bytes of silence\n",buf_free
);
311 if (buffer_silence(state
,buf_free
)==-1)
317 if (winetest_debug
> 1)
318 trace("stopping playback\n");
319 rc
=IDirectSoundBuffer_Stop(state
->dsbo
);
320 ok(rc
==DS_OK
,"IDirectSoundBuffer_Stop() failed: %08x\n", rc
);
324 void test_buffer(LPDIRECTSOUND dso
, LPDIRECTSOUNDBUFFER
*dsbo
,
325 BOOL is_primary
, BOOL set_volume
, LONG volume
,
326 BOOL set_pan
, LONG pan
, BOOL play
, double duration
,
327 BOOL buffer3d
, LPDIRECTSOUND3DLISTENER listener
,
328 BOOL move_listener
, BOOL move_sound
,
329 BOOL set_frequency
, DWORD frequency
)
333 WAVEFORMATEX wfx
,wfx2
;
334 DWORD size
,status
,freq
;
339 rc
=IDirectSoundBuffer_SetFrequency(*dsbo
,frequency
);
340 ok(rc
==DS_OK
||rc
==DSERR_CONTROLUNAVAIL
,
341 "IDirectSoundBuffer_SetFrequency() failed to set frequency %08x\n",rc
);
346 /* DSOUND: Error: Invalid caps pointer */
347 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,0);
348 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetCaps() should have "
349 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
351 ZeroMemory(&dsbcaps
, sizeof(dsbcaps
));
353 /* DSOUND: Error: Invalid caps pointer */
354 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&dsbcaps
);
355 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetCaps() should have "
356 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
358 dsbcaps
.dwSize
=sizeof(dsbcaps
);
359 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&dsbcaps
);
360 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() failed: %08x\n", rc
);
361 if (rc
==DS_OK
&& winetest_debug
> 1) {
362 trace(" Caps: flags=0x%08x size=%d\n",dsbcaps
.dwFlags
,
363 dsbcaps
.dwBufferBytes
);
366 /* Query the format size. */
368 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,NULL
,0,&size
);
369 ok(rc
==DS_OK
&& size
!=0,"IDirectSoundBuffer_GetFormat() should have "
370 "returned the needed size: rc=%08x size=%d\n",rc
,size
);
372 ok(size
== sizeof(WAVEFORMATEX
) || size
== sizeof(WAVEFORMATEXTENSIBLE
),
373 "Expected a correct structure size, got %d\n", size
);
375 if (size
== sizeof(WAVEFORMATEX
)) {
376 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,&wfx
,size
,NULL
);
377 ieee
= (wfx
.wFormatTag
== WAVE_FORMAT_IEEE_FLOAT
);
379 else if (size
== sizeof(WAVEFORMATEXTENSIBLE
)) {
380 WAVEFORMATEXTENSIBLE wfxe
;
381 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,(WAVEFORMATEX
*)&wfxe
,size
,NULL
);
383 ieee
= IsEqualGUID(&wfxe
.SubFormat
, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
);
388 "IDirectSoundBuffer_GetFormat() failed: %08x\n", rc
);
389 if (rc
==DS_OK
&& winetest_debug
> 1) {
390 trace(" Format: %s tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
391 is_primary
? "Primary" : "Secondary",
392 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
393 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
396 /* DSOUND: Error: Invalid frequency buffer */
397 rc
=IDirectSoundBuffer_GetFrequency(*dsbo
,0);
398 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetFrequency() should have "
399 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
401 /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */
402 rc
=IDirectSoundBuffer_GetFrequency(*dsbo
,&freq
);
403 ok((rc
==DS_OK
&& !is_primary
) || (rc
==DSERR_CONTROLUNAVAIL
&&is_primary
) ||
404 (rc
==DSERR_CONTROLUNAVAIL
&&!(dsbcaps
.dwFlags
&DSBCAPS_CTRLFREQUENCY
)),
405 "IDirectSoundBuffer_GetFrequency() failed: %08x\n",rc
);
407 DWORD f
= set_frequency
?frequency
:wfx
.nSamplesPerSec
;
408 ok(freq
==f
,"The frequency returned by GetFrequency "
409 "%d does not match the format %d\n",freq
,f
);
412 /* DSOUND: Error: Invalid status pointer */
413 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,0);
414 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetStatus() should have "
415 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
417 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,&status
);
418 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetStatus() failed: %08x\n", rc
);
419 ok(status
==0,"status=0x%x instead of 0\n",status
);
423 /* We must call SetCooperativeLevel to be allowed to call SetFormat */
424 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
425 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
426 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc
);
430 /* DSOUND: Error: Invalid format pointer */
431 rc
=IDirectSoundBuffer_SetFormat(*dsbo
,0);
432 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_SetFormat() should have "
433 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
435 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
436 rc
=IDirectSoundBuffer_SetFormat(*dsbo
,&wfx2
);
437 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat(%s) failed: %08x\n",
438 format_string(&wfx2
), rc
);
440 /* There is no guarantee that SetFormat will actually change the
441 * format to what we asked for. It depends on what the soundcard
442 * supports. So we must re-query the format.
444 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,&wfx
,sizeof(wfx
),NULL
);
445 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc
);
447 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
448 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
449 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
450 wfx
.nChannels
!=wfx2
.nChannels
)) {
451 trace("Requested format tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
452 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
453 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
454 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
455 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
456 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
459 ZeroMemory(&new_dsbcaps
, sizeof(new_dsbcaps
));
460 new_dsbcaps
.dwSize
= sizeof(new_dsbcaps
);
461 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&new_dsbcaps
);
462 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() failed: %08x\n", rc
);
463 if (rc
==DS_OK
&& winetest_debug
> 1) {
464 trace(" new Caps: flags=0x%08x size=%d\n",new_dsbcaps
.dwFlags
,
465 new_dsbcaps
.dwBufferBytes
);
468 /* Check for primary buffer size change */
469 ok(new_dsbcaps
.dwBufferBytes
== dsbcaps
.dwBufferBytes
,
470 " buffer size changed after SetFormat() - "
471 "previous size was %u, current size is %u\n",
472 dsbcaps
.dwBufferBytes
, new_dsbcaps
.dwBufferBytes
);
473 dsbcaps
.dwBufferBytes
= new_dsbcaps
.dwBufferBytes
;
475 /* Check for primary buffer flags change */
476 ok(new_dsbcaps
.dwFlags
== dsbcaps
.dwFlags
,
477 " flags changed after SetFormat() - "
478 "previous flags were %08x, current flags are %08x\n",
479 dsbcaps
.dwFlags
, new_dsbcaps
.dwFlags
);
481 /* Set the CooperativeLevel back to normal */
482 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
483 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
484 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %08x\n",rc
);
489 DS3DLISTENER listener_param
;
490 LPDIRECTSOUND3DBUFFER buffer
=NULL
;
491 DS3DBUFFER buffer_param
;
492 DWORD start_time
,now
;
496 if (winetest_interactive
) {
498 trace(" Playing %g second 440Hz tone at %dx%dx%d with a "
499 "frequency of %d (%dHz)\n", duration
,
500 wfx
.nSamplesPerSec
, wfx
.wBitsPerSample
, wfx
.nChannels
,
501 frequency
, (440 * frequency
) / wfx
.nSamplesPerSec
);
503 trace(" Playing %g second 440Hz tone at %dx%dx%d\n", duration
,
504 wfx
.nSamplesPerSec
, wfx
.wBitsPerSample
, wfx
.nChannels
);
508 /* We must call SetCooperativeLevel to be allowed to call Lock */
509 /* DSOUND: Setting DirectSound cooperative level to
510 * DSSCL_WRITEPRIMARY */
511 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),
513 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_WRITEPRIMARY) "
514 "failed: %08x\n",rc
);
519 LPDIRECTSOUNDBUFFER temp_buffer
;
521 rc
=IDirectSoundBuffer_QueryInterface(*dsbo
,&IID_IDirectSound3DBuffer
,
523 ok(rc
==DS_OK
,"IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc
);
527 /* check the COM interface */
528 rc
=IDirectSoundBuffer_QueryInterface(*dsbo
, &IID_IDirectSoundBuffer
,
529 (LPVOID
*)&temp_buffer
);
530 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
531 "IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc
);
532 ok(temp_buffer
==*dsbo
,"COM interface broken: %p != %p\n",
534 ref
=IDirectSoundBuffer_Release(temp_buffer
);
535 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
536 "should have 1\n",ref
);
539 rc
=IDirectSound3DBuffer_QueryInterface(*dsbo
,
540 &IID_IDirectSoundBuffer
,
541 (LPVOID
*)&temp_buffer
);
542 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
543 "IDirectSound3DBuffer_QueryInterface() failed: %08x\n", rc
);
544 ok(temp_buffer
==*dsbo
,"COM interface broken: %p != %p\n",
546 ref
=IDirectSoundBuffer_Release(temp_buffer
);
547 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
548 "should have 1\n",ref
);
550 ref
=IDirectSoundBuffer_Release(*dsbo
);
551 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
552 "should have 0\n",ref
);
554 rc
=IDirectSound3DBuffer_QueryInterface(buffer
,
555 &IID_IDirectSoundBuffer
,
557 ok(rc
==DS_OK
&& *dsbo
!=NULL
,"IDirectSound3DBuffer_QueryInterface() "
558 "failed: %08x\n",rc
);
560 /* DSOUND: Error: Invalid buffer */
561 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,0);
562 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound3DBuffer_GetAllParameters() "
563 "failed: %08x\n",rc
);
565 ZeroMemory(&buffer_param
, sizeof(buffer_param
));
567 /* DSOUND: Error: Invalid buffer */
568 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,&buffer_param
);
569 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound3DBuffer_GetAllParameters() "
570 "failed: %08x\n",rc
);
572 buffer_param
.dwSize
=sizeof(buffer_param
);
573 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,&buffer_param
);
574 ok(rc
==DS_OK
,"IDirectSound3DBuffer_GetAllParameters() failed: %08x\n", rc
);
577 if (dsbcaps
.dwFlags
& DSBCAPS_CTRLVOLUME
) {
579 rc
=IDirectSoundBuffer_GetVolume(*dsbo
,&val
);
580 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc
);
582 rc
=IDirectSoundBuffer_SetVolume(*dsbo
,volume
);
583 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume() failed: %08x\n", rc
);
585 /* DSOUND: Error: Buffer does not have CTRLVOLUME */
586 rc
=IDirectSoundBuffer_GetVolume(*dsbo
,&volume
);
587 ok(rc
==DSERR_CONTROLUNAVAIL
,"IDirectSoundBuffer_GetVolume() "
588 "should have returned DSERR_CONTROLUNAVAIL, returned: %08x\n", rc
);
593 if (dsbcaps
.dwFlags
& DSBCAPS_CTRLPAN
) {
595 rc
=IDirectSoundBuffer_GetPan(*dsbo
,&val
);
596 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan() failed: %08x\n", rc
);
598 rc
=IDirectSoundBuffer_SetPan(*dsbo
,pan
);
599 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan() failed: %08x\n", rc
);
601 /* DSOUND: Error: Buffer does not have CTRLPAN */
602 rc
=IDirectSoundBuffer_GetPan(*dsbo
,&pan
);
603 ok(rc
==DSERR_CONTROLUNAVAIL
,"IDirectSoundBuffer_GetPan() "
604 "should have returned DSERR_CONTROLUNAVAIL, returned: %08x\n", rc
);
608 /* try an offset past the end of the buffer */
609 rc
= IDirectSoundBuffer_Lock(*dsbo
, dsbcaps
.dwBufferBytes
, 0, &buffer1
,
610 &length1
, NULL
, NULL
,
611 DSBLOCK_ENTIREBUFFER
);
612 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSoundBuffer_Lock() should have "
613 "returned DSERR_INVALIDPARAM, returned %08x\n", rc
);
615 /* try a size larger than the buffer */
616 rc
= IDirectSoundBuffer_Lock(*dsbo
, 0, dsbcaps
.dwBufferBytes
+ 1,
617 &buffer1
, &length1
, NULL
, NULL
,
618 DSBLOCK_FROMWRITECURSOR
);
619 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSoundBuffer_Lock() should have "
620 "returned DSERR_INVALIDPARAM, returned %08x\n", rc
);
623 state
.wave
=wave_generate_la(&wfx
,(duration
*frequency
)/wfx
.nSamplesPerSec
,&state
.wave_len
,ieee
);
625 state
.wave
=wave_generate_la(&wfx
,duration
,&state
.wave_len
,ieee
);
629 state
.buffer_size
=dsbcaps
.dwBufferBytes
;
630 state
.played
=state
.written
=state
.offset
=0;
631 buffer_refill(&state
,state
.buffer_size
);
633 rc
=IDirectSoundBuffer_Play(*dsbo
,0,0,DSBPLAY_LOOPING
);
634 ok(rc
==DS_OK
,"IDirectSoundBuffer_Play() failed: %08x\n", rc
);
636 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,&status
);
637 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetStatus() failed: %08x\n", rc
);
638 ok(status
==(DSBSTATUS_PLAYING
|DSBSTATUS_LOOPING
),
639 "GetStatus: bad status: %x\n",status
);
642 ZeroMemory(&listener_param
,sizeof(listener_param
));
643 listener_param
.dwSize
=sizeof(listener_param
);
644 rc
=IDirectSound3DListener_GetAllParameters(listener
,
646 ok(rc
==DS_OK
,"IDirectSound3dListener_GetAllParameters() "
647 "failed: %08x\n",rc
);
649 listener_param
.vPosition
.x
= -5.0f
;
650 listener_param
.vVelocity
.x
= (float)(10.0/duration
);
652 rc
=IDirectSound3DListener_SetAllParameters(listener
,
655 ok(rc
==DS_OK
,"IDirectSound3dListener_SetPosition() failed: %08x\n", 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: %08x\n", rc
);
668 start_time
=GetTickCount();
669 while (buffer_service(&state
)) {
670 WaitForSingleObject(GetCurrentProcess(),TIME_SLICE
);
672 if (listener
&& move_listener
) {
673 listener_param
.vPosition
.x
= (float)(-5.0+10.0*(now
-start_time
)/1000/duration
);
674 if (winetest_debug
>2)
675 trace("listener position=%g\n",listener_param
.vPosition
.x
);
676 rc
=IDirectSound3DListener_SetPosition(listener
,
677 listener_param
.vPosition
.x
,listener_param
.vPosition
.y
,
678 listener_param
.vPosition
.z
,DS3D_IMMEDIATE
);
679 ok(rc
==DS_OK
,"IDirectSound3dListener_SetPosition() failed: %08x\n",rc
);
681 if (buffer3d
&& move_sound
) {
682 buffer_param
.vPosition
.x
= (float)(100-200.0*(now
-start_time
)/1000/duration
);
683 if (winetest_debug
>2)
684 trace("sound position=%g\n",buffer_param
.vPosition
.x
);
685 rc
=IDirectSound3DBuffer_SetPosition(buffer
,
686 buffer_param
.vPosition
.x
,buffer_param
.vPosition
.y
,
687 buffer_param
.vPosition
.z
,DS3D_IMMEDIATE
);
688 ok(rc
==DS_OK
,"IDirectSound3dBuffer_SetPosition() failed: %08x\n", rc
);
691 /* Check the sound duration was within 10% of the expected value */
693 ok(fabs(1000*duration
-now
+start_time
)<=100*duration
,
694 "The sound played for %d ms instead of %g ms\n",
695 now
-start_time
,1000*duration
);
697 HeapFree(GetProcessHeap(), 0, state
.wave
);
699 /* Set the CooperativeLevel back to normal */
700 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
701 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
702 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) "
703 "failed: %08x\n",rc
);
706 ref
=IDirectSound3DBuffer_Release(buffer
);
707 ok(ref
==0,"IDirectSound3DBuffer_Release() has %d references, "
708 "should have 0\n",ref
);
713 static HRESULT
test_secondary(LPGUID lpGuid
, int play
,
714 int has_3d
, int has_3dbuffer
,
715 int has_listener
, int has_duplicate
,
716 int move_listener
, int move_sound
)
719 LPDIRECTSOUND dso
=NULL
;
720 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
721 LPDIRECTSOUND3DLISTENER listener
=NULL
;
722 DSBUFFERDESC bufdesc
;
723 WAVEFORMATEX wfx
, wfx1
;
726 /* Create the DirectSound object */
727 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
728 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %08x\n", rc
);
732 /* We must call SetCooperativeLevel before creating primary buffer */
733 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
734 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
735 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc
);
739 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
740 bufdesc
.dwSize
=sizeof(bufdesc
);
741 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
743 bufdesc
.dwFlags
|=DSBCAPS_CTRL3D
;
745 bufdesc
.dwFlags
|=(DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
);
746 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
747 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
748 "IDirectSound_CreateSoundBuffer() failed to create a %sprimary buffer: %08x\n",has_3d
?"3D ":"", rc
);
749 if (rc
==DSERR_CONTROLUNAVAIL
)
750 trace(" No Primary\n");
751 else if (rc
==DS_OK
&& primary
!=NULL
) {
752 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
753 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc
);
758 rc
=IDirectSoundBuffer_QueryInterface(primary
,
759 &IID_IDirectSound3DListener
,
761 ok(rc
==DS_OK
&& listener
!=NULL
,
762 "IDirectSoundBuffer_QueryInterface() failed to get a 3D listener: %08x\n",rc
);
763 ref
=IDirectSoundBuffer_Release(primary
);
764 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
765 "should have 0\n",ref
);
766 if (rc
==DS_OK
&& listener
!=NULL
) {
767 DS3DLISTENER listener_param
;
768 ZeroMemory(&listener_param
,sizeof(listener_param
));
769 /* DSOUND: Error: Invalid buffer */
770 rc
=IDirectSound3DListener_GetAllParameters(listener
,0);
771 ok(rc
==DSERR_INVALIDPARAM
,
772 "IDirectSound3dListener_GetAllParameters() should have "
773 "returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
775 /* DSOUND: Error: Invalid buffer */
776 rc
=IDirectSound3DListener_GetAllParameters(listener
,
778 ok(rc
==DSERR_INVALIDPARAM
,
779 "IDirectSound3dListener_GetAllParameters() should have "
780 "returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
782 listener_param
.dwSize
=sizeof(listener_param
);
783 rc
=IDirectSound3DListener_GetAllParameters(listener
,
785 ok(rc
==DS_OK
,"IDirectSound3dListener_GetAllParameters() "
786 "failed: %08x\n",rc
);
788 ok(listener
==NULL
, "IDirectSoundBuffer_QueryInterface() "
789 "failed but returned a listener anyway\n");
790 ok(rc
!=DS_OK
, "IDirectSoundBuffer_QueryInterface() succeeded "
791 "but returned a NULL listener\n");
793 ref
=IDirectSound3DListener_Release(listener
);
794 ok(ref
==0,"IDirectSound3dListener_Release() listener has "
795 "%d references, should have 0\n",ref
);
801 init_format(&wfx
,WAVE_FORMAT_PCM
,22050,16,2);
803 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
804 bufdesc
.dwSize
=sizeof(bufdesc
);
805 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
807 bufdesc
.dwFlags
|=DSBCAPS_CTRL3D
;
810 (DSBCAPS_CTRLFREQUENCY
|DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
);
811 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
813 bufdesc
.lpwfxFormat
=&wfx
;
814 if (winetest_interactive
) {
815 trace(" Testing a %s%ssecondary buffer %s%s%s%sat %dx%dx%d "
816 "with a primary buffer at %dx%dx%d\n",
817 has_3dbuffer
?"3D ":"",
818 has_duplicate
?"duplicated ":"",
819 listener
!=NULL
||move_sound
?"with ":"",
820 move_listener
?"moving ":"",
821 listener
!=NULL
?"listener ":"",
822 listener
&&move_sound
?"and moving sound ":move_sound
?
824 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
825 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
827 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
828 ok((rc
==DS_OK
&& secondary
!=NULL
) || broken(rc
== DSERR_CONTROLUNAVAIL
), /* vmware drivers on w2k */
829 "IDirectSound_CreateSoundBuffer() failed to create a %s%ssecondary buffer %s%s%s%sat %dx%dx%d (%s): %08x\n",
830 has_3dbuffer
?"3D ":"", has_duplicate
?"duplicated ":"",
831 listener
!=NULL
||move_sound
?"with ":"", move_listener
?"moving ":"",
832 listener
!=NULL
?"listener ":"",
833 listener
&&move_sound
?"and moving sound ":move_sound
?
835 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
836 getDSBCAPS(bufdesc
.dwFlags
),rc
);
837 if (rc
==DS_OK
&& secondary
!=NULL
) {
838 IDirectSound3DBuffer
*ds3d
;
840 rc
=IDirectSoundBuffer_QueryInterface(secondary
, &IID_IDirectSound3DBuffer
, (void**)&ds3d
);
841 ok((has_3dbuffer
&& rc
==DS_OK
) || (!has_3dbuffer
&& rc
==E_NOINTERFACE
),
842 "Wrong return trying to get 3D buffer on %s3D secondary interface: %08x\n", has_3dbuffer
? "" : "non-", rc
);
844 IDirectSound3DBuffer_Release(ds3d
);
847 LONG refvol
,vol
,refpan
,pan
;
849 /* Check the initial secondary buffer's volume and pan */
850 rc
=IDirectSoundBuffer_GetVolume(secondary
,&vol
);
851 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(secondary) failed: %08x\n",rc
);
852 ok(vol
==0,"wrong volume for a new secondary buffer: %d\n",vol
);
853 rc
=IDirectSoundBuffer_GetPan(secondary
,&pan
);
854 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(secondary) failed: %08x\n",rc
);
855 ok(pan
==0,"wrong pan for a new secondary buffer: %d\n",pan
);
857 /* Check that changing the secondary buffer's volume and pan
858 * does not impact the primary buffer's volume and pan
860 rc
=IDirectSoundBuffer_GetVolume(primary
,&refvol
);
861 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(primary) failed: %08x\n",rc
);
862 rc
=IDirectSoundBuffer_GetPan(primary
,&refpan
);
863 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(primary) failed: %08x\n", rc
);
865 rc
=IDirectSoundBuffer_SetVolume(secondary
,-1000);
866 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: %08x\n",rc
);
867 rc
=IDirectSoundBuffer_GetVolume(secondary
,&vol
);
868 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: %08x\n",rc
);
869 ok(vol
==-1000,"secondary: wrong volume %d instead of -1000\n",
871 rc
=IDirectSoundBuffer_SetPan(secondary
,-1000);
872 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: %08x\n",rc
);
873 rc
=IDirectSoundBuffer_GetPan(secondary
,&pan
);
874 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: %08x\n",rc
);
875 ok(pan
==-1000,"secondary: wrong pan %d instead of -1000\n",
878 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
879 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(primary) failed: %08x\n",rc
);
880 ok(vol
==refvol
,"The primary volume changed from %d to %d\n",
882 rc
=IDirectSoundBuffer_GetPan(primary
,&pan
);
883 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(primary) failed: %08x\n", rc
);
884 ok(pan
==refpan
,"The primary pan changed from %d to %d\n",
887 rc
=IDirectSoundBuffer_SetVolume(secondary
,0);
888 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: %08x\n",rc
);
889 rc
=IDirectSoundBuffer_SetPan(secondary
,0);
890 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: %08x\n",rc
);
893 LPDIRECTSOUNDBUFFER duplicated
=NULL
;
895 /* DSOUND: Error: Invalid source buffer */
896 rc
=IDirectSound_DuplicateSoundBuffer(dso
,0,0);
897 ok(rc
==DSERR_INVALIDPARAM
,
898 "IDirectSound_DuplicateSoundBuffer() should have returned "
899 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
901 /* DSOUND: Error: Invalid dest buffer */
902 rc
=IDirectSound_DuplicateSoundBuffer(dso
,secondary
,0);
903 ok(rc
==DSERR_INVALIDPARAM
,
904 "IDirectSound_DuplicateSoundBuffer() should have returned "
905 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
907 /* DSOUND: Error: Invalid source buffer */
908 rc
=IDirectSound_DuplicateSoundBuffer(dso
,0,&duplicated
);
909 ok(rc
==DSERR_INVALIDPARAM
,
910 "IDirectSound_DuplicateSoundBuffer() should have returned "
911 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
914 rc
=IDirectSound_DuplicateSoundBuffer(dso
,secondary
,
916 ok(rc
==DS_OK
&& duplicated
!=NULL
,
917 "IDirectSound_DuplicateSoundBuffer() failed to duplicate "
918 "a secondary buffer: %08x\n",rc
);
920 if (rc
==DS_OK
&& duplicated
!=NULL
) {
921 ref
=IDirectSoundBuffer_Release(secondary
);
922 ok(ref
==0,"IDirectSoundBuffer_Release() secondary has %d "
923 "references, should have 0\n",ref
);
924 secondary
=duplicated
;
928 if (rc
==DS_OK
&& secondary
!=NULL
) {
930 duration
=(move_listener
|| move_sound
?4.0:1.0);
931 test_buffer(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
932 winetest_interactive
,duration
,has_3dbuffer
,
933 listener
,move_listener
,move_sound
,FALSE
,0);
934 ref
=IDirectSoundBuffer_Release(secondary
);
935 ok(ref
==0,"IDirectSoundBuffer_Release() %s has %d references, "
936 "should have 0\n",has_duplicate
?"duplicated":"secondary",
942 ref
=IDirectSound3DListener_Release(listener
);
943 ok(ref
==0,"IDirectSound3dListener_Release() listener has %d "
944 "references, should have 0\n",ref
);
946 ref
=IDirectSoundBuffer_Release(primary
);
947 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
948 "should have 0\n",ref
);
951 ok(primary
==NULL
,"IDirectSound_CreateSoundBuffer(primary) failed "
952 "but primary created anyway\n");
953 ok(rc
!=DS_OK
,"IDirectSound_CreateSoundBuffer(primary) succeeded "
954 "but primary not created\n");
956 ref
=IDirectSoundBuffer_Release(primary
);
957 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
958 "should have 0\n",ref
);
962 /* Set the CooperativeLevel back to normal */
963 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
964 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
965 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %08x\n", rc
);
968 ref
=IDirectSound_Release(dso
);
969 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
971 return DSERR_GENERIC
;
976 static HRESULT
test_for_driver(LPGUID lpGuid
)
979 LPDIRECTSOUND dso
=NULL
;
982 /* Create the DirectSound object */
983 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
984 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
985 "DirectSoundCreate() failed: %08x\n",rc
);
989 ref
=IDirectSound_Release(dso
);
990 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
992 return DSERR_GENERIC
;
997 static HRESULT
test_primary(LPGUID lpGuid
)
1000 LPDIRECTSOUND dso
=NULL
;
1001 LPDIRECTSOUNDBUFFER primary
=NULL
;
1002 DSBUFFERDESC bufdesc
;
1006 /* Create the DirectSound object */
1007 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1008 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %08x\n", rc
);
1012 /* Get the device capabilities */
1013 ZeroMemory(&dscaps
, sizeof(dscaps
));
1014 dscaps
.dwSize
=sizeof(dscaps
);
1015 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1016 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %08x\n",rc
);
1020 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1021 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1022 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1023 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc
);
1027 /* Testing the primary buffer */
1029 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1030 bufdesc
.dwSize
=sizeof(bufdesc
);
1031 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
;
1032 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1033 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
1034 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: %08x\n",rc
);
1035 if (rc
==DSERR_CONTROLUNAVAIL
)
1036 trace(" No Primary\n");
1037 else if (rc
==DS_OK
&& primary
!=NULL
) {
1038 test_buffer(dso
,&primary
,1,TRUE
,0,TRUE
,0,winetest_interactive
&&
1039 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,NULL
,0,0,
1041 if (winetest_interactive
) {
1044 volume
= DSBVOLUME_MAX
;
1045 for (i
= 0; i
< 6; i
++) {
1046 test_buffer(dso
,&primary
,1,TRUE
,volume
,TRUE
,0,
1047 winetest_interactive
&&
1048 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),
1049 1.0,0,NULL
,0,0,FALSE
,0);
1050 volume
-= ((DSBVOLUME_MAX
-DSBVOLUME_MIN
) / 40);
1054 for (i
= 0; i
< 7; i
++) {
1055 test_buffer(dso
,&primary
,1,TRUE
,0,TRUE
,pan
,
1056 winetest_interactive
&&
1057 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,0,0,0,FALSE
,0);
1058 pan
+= ((DSBPAN_RIGHT
-DSBPAN_LEFT
) / 6);
1061 ref
=IDirectSoundBuffer_Release(primary
);
1062 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1063 "should have 0\n",ref
);
1066 /* Set the CooperativeLevel back to normal */
1067 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1068 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1069 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %08x\n", rc
);
1072 ref
=IDirectSound_Release(dso
);
1073 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1075 return DSERR_GENERIC
;
1080 static HRESULT
test_primary_3d(LPGUID lpGuid
)
1083 LPDIRECTSOUND dso
=NULL
;
1084 LPDIRECTSOUNDBUFFER primary
=NULL
;
1085 DSBUFFERDESC bufdesc
;
1089 /* Create the DirectSound object */
1090 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1091 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %08x\n", rc
);
1095 /* Get the device capabilities */
1096 ZeroMemory(&dscaps
, sizeof(dscaps
));
1097 dscaps
.dwSize
=sizeof(dscaps
);
1098 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1099 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %08x\n",rc
);
1103 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1104 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1105 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1106 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc
);
1111 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1112 bufdesc
.dwSize
=sizeof(bufdesc
);
1113 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
1114 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1115 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1116 "to create a primary buffer: %08x\n",rc
);
1117 if (rc
==DS_OK
&& primary
!=NULL
) {
1118 ref
=IDirectSoundBuffer_Release(primary
);
1119 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1120 "should have 0\n",ref
);
1122 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1123 bufdesc
.dwSize
=sizeof(bufdesc
);
1124 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRL3D
;
1125 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1126 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() "
1127 "failed to create a 3D primary buffer: %08x\n",rc
);
1128 if (rc
==DS_OK
&& primary
!=NULL
) {
1129 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
1130 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,0,0,0,
1132 ref
=IDirectSoundBuffer_Release(primary
);
1133 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1134 "should have 0\n",ref
);
1137 /* Set the CooperativeLevel back to normal */
1138 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1139 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1140 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %08x\n", rc
);
1143 ref
=IDirectSound_Release(dso
);
1144 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1146 return DSERR_GENERIC
;
1151 static HRESULT
test_primary_3d_with_listener(LPGUID lpGuid
)
1154 LPDIRECTSOUND dso
=NULL
;
1155 LPDIRECTSOUNDBUFFER primary
=NULL
;
1156 DSBUFFERDESC bufdesc
;
1160 /* Create the DirectSound object */
1161 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1162 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %08x\n", rc
);
1166 /* Get the device capabilities */
1167 ZeroMemory(&dscaps
, sizeof(dscaps
));
1168 dscaps
.dwSize
=sizeof(dscaps
);
1169 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1170 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %08x\n",rc
);
1174 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1175 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1176 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1177 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc
);
1181 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1182 bufdesc
.dwSize
=sizeof(bufdesc
);
1183 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRL3D
;
1184 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1185 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1186 "to create a 3D primary buffer: %08x\n",rc
);
1187 if (rc
==DS_OK
&& primary
!=NULL
) {
1188 LPDIRECTSOUND3DLISTENER listener
=NULL
;
1189 LPDIRECTSOUNDBUFFER temp_buffer
=NULL
;
1190 rc
=IDirectSoundBuffer_QueryInterface(primary
,
1191 &IID_IDirectSound3DListener
,(void **)&listener
);
1192 ok(rc
==DS_OK
&& listener
!=NULL
,"IDirectSoundBuffer_QueryInterface() "
1193 "failed to get a 3D listener: %08x\n",rc
);
1194 if (rc
==DS_OK
&& listener
!=NULL
) {
1195 /* Checking the COM interface */
1196 rc
=IDirectSoundBuffer_QueryInterface(primary
,
1197 &IID_IDirectSoundBuffer
,(LPVOID
*)&temp_buffer
);
1198 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1199 "IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc
);
1200 ok(temp_buffer
==primary
,
1201 "COM interface broken: %p != %p\n",
1202 temp_buffer
,primary
);
1203 if (rc
==DS_OK
&& temp_buffer
!=NULL
) {
1204 ref
=IDirectSoundBuffer_Release(temp_buffer
);
1205 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
1206 "should have 1\n",ref
);
1209 rc
=IDirectSound3DListener_QueryInterface(listener
,
1210 &IID_IDirectSoundBuffer
,(LPVOID
*)&temp_buffer
);
1211 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1212 "IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc
);
1213 ok(temp_buffer
==primary
,
1214 "COM interface broken: %p != %p\n",
1215 temp_buffer
,primary
);
1216 ref
=IDirectSoundBuffer_Release(temp_buffer
);
1217 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
1218 "should have 1\n",ref
);
1220 /* Testing the buffer */
1221 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,
1222 winetest_interactive
&&
1223 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,
1224 listener
,0,0,FALSE
,0);
1227 rc
= IDirectSound3DListener_QueryInterface(listener
, &IID_IKsPropertySet
,
1228 (void **)&temp_buffer
);
1229 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1230 "IDirectSound3DListener_QueryInterface didn't handle IKsPropertySet: ret = %08x\n", rc
);
1232 IKsPropertySet_Release(temp_buffer
);
1235 /* Testing the reference counting */
1236 ref
=IDirectSound3DListener_Release(listener
);
1237 ok(ref
==0,"IDirectSound3DListener_Release() listener has %d "
1238 "references, should have 0\n",ref
);
1242 rc
= IDirectSoundBuffer_QueryInterface(primary
, &IID_IKsPropertySet
, (void **)&temp_buffer
);
1243 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1244 "IDirectSoundBuffer_QueryInterface didn't handle IKsPropertySet on primary buffer: ret = %08x\n", rc
);
1246 IKsPropertySet_Release(temp_buffer
);
1248 /* Testing the reference counting */
1249 ref
=IDirectSoundBuffer_Release(primary
);
1250 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1251 "should have 0\n",ref
);
1255 ref
=IDirectSound_Release(dso
);
1256 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1258 return DSERR_GENERIC
;
1263 static unsigned driver_count
= 0;
1265 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
1266 LPCSTR lpcstrModule
, LPVOID lpContext
)
1269 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
1272 rc
= test_for_driver(lpGuid
);
1273 if (rc
== DSERR_NODRIVER
) {
1274 trace(" No Driver\n");
1276 } else if (rc
== DSERR_ALLOCATED
) {
1277 trace(" Already In Use\n");
1279 } else if (rc
== E_FAIL
) {
1280 trace(" No Device\n");
1284 trace(" Testing the primary buffer\n");
1285 test_primary(lpGuid
);
1287 trace(" Testing 3D primary buffer\n");
1288 test_primary_3d(lpGuid
);
1290 trace(" Testing 3D primary buffer with listener\n");
1291 test_primary_3d_with_listener(lpGuid
);
1293 /* Testing secondary buffers */
1294 test_secondary(lpGuid
,winetest_interactive
,0,0,0,0,0,0);
1295 test_secondary(lpGuid
,winetest_interactive
,0,0,0,1,0,0);
1297 /* Testing 3D secondary buffers */
1298 test_secondary(lpGuid
,winetest_interactive
,1,0,0,0,0,0);
1299 test_secondary(lpGuid
,winetest_interactive
,1,1,0,0,0,0);
1300 test_secondary(lpGuid
,winetest_interactive
,1,1,0,1,0,0);
1301 test_secondary(lpGuid
,winetest_interactive
,1,0,1,0,0,0);
1302 test_secondary(lpGuid
,winetest_interactive
,1,0,1,1,0,0);
1303 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,0,0);
1304 test_secondary(lpGuid
,winetest_interactive
,1,1,1,1,0,0);
1305 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,1,0);
1306 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,0,1);
1307 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,1,1);
1312 static void ds3d_tests(void)
1315 rc
=pDirectSoundEnumerateA(&dsenum_callback
,NULL
);
1316 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %08x\n",rc
);
1317 trace("tested %u DirectSound drivers\n", driver_count
);
1326 hDsound
= LoadLibrary("dsound.dll");
1330 pDirectSoundEnumerateA
= (void*)GetProcAddress(hDsound
,
1331 "DirectSoundEnumerateA");
1332 pDirectSoundCreate
= (void*)GetProcAddress(hDsound
,
1333 "DirectSoundCreate");
1337 FreeLibrary(hDsound
);
1340 skip("dsound.dll not found - skipping all tests\n");