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"
33 #include "dsound_test.h"
35 #define PI 3.14159265358979323846
38 static HRESULT (WINAPI
*pDirectSoundEnumerateA
)(LPDSENUMCALLBACKA
,LPVOID
)=NULL
;
39 static HRESULT (WINAPI
*pDirectSoundCreate
)(LPCGUID
,LPDIRECTSOUND
*,
42 char* wave_generate_la(WAVEFORMATEX
* wfx
, double duration
, DWORD
* size
)
49 nb_samples
=(int)(duration
*wfx
->nSamplesPerSec
);
50 *size
=nb_samples
*wfx
->nBlockAlign
;
51 b
=buf
=HeapAlloc(GetProcessHeap(), 0, *size
);
52 for (i
=0;i
<nb_samples
;i
++) {
53 double y
=sin(440.0*2*PI
*i
/wfx
->nSamplesPerSec
);
54 if (wfx
->wBitsPerSample
==8) {
55 unsigned char sample
=(unsigned char)((double)127.5*(y
+1.0));
57 if (wfx
->nChannels
==2)
59 } else if (wfx
->wBitsPerSample
== 16) {
60 signed short sample
=(signed short)((double)32767.5*y
-0.5);
64 if (wfx
->nChannels
==2) {
69 } else if (wfx
->wBitsPerSample
== 24) {
70 signed int sample
=(signed int)((double)8388607.5*y
-0.5);
72 b
[1]=(sample
>> 8)&0xff;
75 if (wfx
->nChannels
==2) {
77 b
[1]=(sample
>> 8)&0xff;
81 } else if (wfx
->wBitsPerSample
== 32) {
82 signed int sample
=(signed int)((double)2147483647.5*y
-0.5);
84 b
[1]=(sample
>> 8)&0xff;
85 b
[2]=(sample
>> 16)&0xff;
88 if (wfx
->nChannels
==2) {
90 b
[1]=(sample
>> 8)&0xff;
91 b
[2]=(sample
>> 16)&0xff;
100 const char * getDSBCAPS(DWORD xmask
) {
105 #define FE(x) { x, #x },
106 FE(DSBCAPS_PRIMARYBUFFER
)
108 FE(DSBCAPS_LOCHARDWARE
)
109 FE(DSBCAPS_LOCSOFTWARE
)
111 FE(DSBCAPS_CTRLFREQUENCY
)
113 FE(DSBCAPS_CTRLVOLUME
)
114 FE(DSBCAPS_CTRLPOSITIONNOTIFY
)
115 FE(DSBCAPS_STICKYFOCUS
)
116 FE(DSBCAPS_GLOBALFOCUS
)
117 FE(DSBCAPS_GETCURRENTPOSITION2
)
118 FE(DSBCAPS_MUTE3DATMAXDISTANCE
)
121 static char buffer
[512];
127 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++) {
128 if ((flags
[i
].mask
& xmask
) == flags
[i
].mask
) {
133 strcat(buffer
, flags
[i
].name
);
142 HWND hwnd
=GetForegroundWindow();
144 hwnd
=GetDesktopWindow();
148 void init_format(WAVEFORMATEX
* wfx
, int format
, int rate
, int depth
,
151 wfx
->wFormatTag
=format
;
152 wfx
->nChannels
=channels
;
153 wfx
->wBitsPerSample
=depth
;
154 wfx
->nSamplesPerSec
=rate
;
155 wfx
->nBlockAlign
=wfx
->nChannels
*wfx
->wBitsPerSample
/8;
156 /* FIXME: Shouldn't this test be if (format!=WAVE_FORMAT_PCM) */
157 if (wfx
->nBlockAlign
==0)
159 /* align compressed formats to byte boundary */
162 wfx
->nAvgBytesPerSec
=wfx
->nSamplesPerSec
*wfx
->nBlockAlign
;
170 LPDIRECTSOUNDBUFFER dsbo
;
178 static int buffer_refill(play_state_t
* state
, DWORD size
)
184 if (size
>state
->wave_len
-state
->written
)
185 size
=state
->wave_len
-state
->written
;
187 /* some broken apps like Navyfield mistakenly pass NULL for a ppValue */
188 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
189 &ptr1
,NULL
,&ptr2
,&len2
,0);
190 ok(rc
==DSERR_INVALIDPARAM
,"expected %08x got %08x\n",DSERR_INVALIDPARAM
, rc
);
191 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
192 &ptr1
,&len1
,&ptr2
,&len2
,0);
193 ok(rc
==DS_OK
,"IDirectSoundBuffer_Lock() failed: %08x\n", rc
);
197 memcpy(ptr1
,state
->wave
+state
->written
,len1
);
198 state
->written
+=len1
;
200 memcpy(ptr2
,state
->wave
+state
->written
,len2
);
201 state
->written
+=len2
;
203 state
->offset
=state
->written
% state
->buffer_size
;
204 /* some apps blindly pass &ptr1 instead of ptr1 */
205 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,&ptr1
,len1
,ptr2
,len2
);
206 ok(rc
==DSERR_INVALIDPARAM
, "IDDirectSoundBuffer_Unlock(): expected %08x got %08x, %p %p\n",DSERR_INVALIDPARAM
, rc
, &ptr1
, ptr1
);
207 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,ptr1
,len1
,ptr2
,len2
);
208 ok(rc
==DS_OK
,"IDirectSoundBuffer_Unlock() failed: %08x\n", rc
);
214 static int buffer_silence(play_state_t
* state
, DWORD size
)
221 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
222 &ptr1
,&len1
,&ptr2
,&len2
,0);
223 ok(rc
==DS_OK
,"IDirectSoundBuffer_Lock() failed: %08x\n", rc
);
227 s
=(state
->wfx
->wBitsPerSample
==8?0x80:0);
232 state
->offset
=(state
->offset
+size
) % state
->buffer_size
;
233 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,ptr1
,len1
,ptr2
,len2
);
234 ok(rc
==DS_OK
,"IDirectSoundBuffer_Unlock() failed: %08x\n", rc
);
240 static int buffer_service(play_state_t
* state
)
242 DWORD last_play_pos
,play_pos
,buf_free
;
245 rc
=IDirectSoundBuffer_GetCurrentPosition(state
->dsbo
,&play_pos
,NULL
);
246 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCurrentPosition() failed: %08x\n", rc
);
251 /* Update the amount played */
252 last_play_pos
=state
->played
% state
->buffer_size
;
253 if (play_pos
<last_play_pos
)
254 state
->played
+=state
->buffer_size
-last_play_pos
+play_pos
;
256 state
->played
+=play_pos
-last_play_pos
;
258 if (winetest_debug
> 1)
259 trace("buf size=%d last_play_pos=%d play_pos=%d played=%d / %d\n",
260 state
->buffer_size
,last_play_pos
,play_pos
,state
->played
,
263 if (state
->played
>state
->wave_len
)
265 /* Everything has been played */
269 /* Refill the buffer */
270 if (state
->offset
<=play_pos
)
271 buf_free
=play_pos
-state
->offset
;
273 buf_free
=state
->buffer_size
-state
->offset
+play_pos
;
275 if (winetest_debug
> 1)
276 trace("offset=%d free=%d written=%d / %d\n",
277 state
->offset
,buf_free
,state
->written
,state
->wave_len
);
281 if (state
->written
<state
->wave_len
)
283 int w
=buffer_refill(state
,buf_free
);
287 if (state
->written
==state
->wave_len
&& winetest_debug
> 1)
288 trace("last sound byte at %d\n",
289 (state
->written
% state
->buffer_size
));
293 /* Fill with silence */
294 if (winetest_debug
> 1)
295 trace("writing %d bytes of silence\n",buf_free
);
296 if (buffer_silence(state
,buf_free
)==-1)
302 if (winetest_debug
> 1)
303 trace("stopping playback\n");
304 rc
=IDirectSoundBuffer_Stop(state
->dsbo
);
305 ok(rc
==DS_OK
,"IDirectSoundBuffer_Stop() failed: %08x\n", 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 %08x\n",rc
);
330 /* DSOUND: Error: Invalid caps pointer */
331 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,0);
332 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetCaps() should have "
333 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
335 ZeroMemory(&dsbcaps
, sizeof(dsbcaps
));
337 /* DSOUND: Error: Invalid caps pointer */
338 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&dsbcaps
);
339 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetCaps() should have "
340 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
342 dsbcaps
.dwSize
=sizeof(dsbcaps
);
343 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&dsbcaps
);
344 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() failed: %08x\n", rc
);
345 if (rc
==DS_OK
&& winetest_debug
> 1) {
346 trace(" Caps: flags=0x%08x size=%d\n",dsbcaps
.dwFlags
,
347 dsbcaps
.dwBufferBytes
);
350 /* Query the format size. */
352 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,NULL
,0,&size
);
353 ok(rc
==DS_OK
&& size
!=0,"IDirectSoundBuffer_GetFormat() should have "
354 "returned the needed size: rc=%08x size=%d\n",rc
,size
);
356 ok(size
== sizeof(WAVEFORMATEX
) || size
== sizeof(WAVEFORMATEXTENSIBLE
),
357 "Expected a correct structure size, got %d\n", size
);
359 if (size
== sizeof(WAVEFORMATEX
)) {
360 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,&wfx
,size
,NULL
);
362 else if (size
== sizeof(WAVEFORMATEXTENSIBLE
)) {
363 WAVEFORMATEXTENSIBLE wfxe
;
364 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,(WAVEFORMATEX
*)&wfxe
,size
,NULL
);
368 "IDirectSoundBuffer_GetFormat() failed: %08x\n", rc
);
369 if (rc
==DS_OK
&& winetest_debug
> 1) {
370 trace(" Format: %s tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
371 is_primary
? "Primary" : "Secondary",
372 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
373 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
376 /* DSOUND: Error: Invalid frequency buffer */
377 rc
=IDirectSoundBuffer_GetFrequency(*dsbo
,0);
378 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetFrequency() should have "
379 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
381 /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */
382 rc
=IDirectSoundBuffer_GetFrequency(*dsbo
,&freq
);
383 ok((rc
==DS_OK
&& !is_primary
) || (rc
==DSERR_CONTROLUNAVAIL
&&is_primary
) ||
384 (rc
==DSERR_CONTROLUNAVAIL
&&!(dsbcaps
.dwFlags
&DSBCAPS_CTRLFREQUENCY
)),
385 "IDirectSoundBuffer_GetFrequency() failed: %08x\n",rc
);
387 DWORD f
= set_frequency
?frequency
:wfx
.nSamplesPerSec
;
388 ok(freq
==f
,"The frequency returned by GetFrequency "
389 "%d does not match the format %d\n",freq
,f
);
392 /* DSOUND: Error: Invalid status pointer */
393 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,0);
394 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetStatus() should have "
395 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
397 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,&status
);
398 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetStatus() failed: %08x\n", rc
);
399 ok(status
==0,"status=0x%x instead of 0\n",status
);
403 /* We must call SetCooperativeLevel to be allowed to call SetFormat */
404 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
405 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
406 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc
);
410 /* DSOUND: Error: Invalid format pointer */
411 rc
=IDirectSoundBuffer_SetFormat(*dsbo
,0);
412 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_SetFormat() should have "
413 "returned DSERR_INVALIDPARAM, returned: %08x\n",rc
);
415 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
416 rc
=IDirectSoundBuffer_SetFormat(*dsbo
,&wfx2
);
417 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat(%s) failed: %08x\n",
418 format_string(&wfx2
), rc
);
420 /* There is no guarantee that SetFormat will actually change the
421 * format to what we asked for. It depends on what the soundcard
422 * supports. So we must re-query the format.
424 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,&wfx
,sizeof(wfx
),NULL
);
425 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc
);
427 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
428 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
429 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
430 wfx
.nChannels
!=wfx2
.nChannels
)) {
431 trace("Requested format tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
432 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
433 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
434 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
435 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
436 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
439 ZeroMemory(&new_dsbcaps
, sizeof(new_dsbcaps
));
440 new_dsbcaps
.dwSize
= sizeof(new_dsbcaps
);
441 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&new_dsbcaps
);
442 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() failed: %08x\n", rc
);
443 if (rc
==DS_OK
&& winetest_debug
> 1) {
444 trace(" new Caps: flags=0x%08x size=%d\n",new_dsbcaps
.dwFlags
,
445 new_dsbcaps
.dwBufferBytes
);
448 /* Check for primary buffer size change */
449 ok(new_dsbcaps
.dwBufferBytes
== dsbcaps
.dwBufferBytes
,
450 " buffer size changed after SetFormat() - "
451 "previous size was %u, current size is %u\n",
452 dsbcaps
.dwBufferBytes
, new_dsbcaps
.dwBufferBytes
);
453 dsbcaps
.dwBufferBytes
= new_dsbcaps
.dwBufferBytes
;
455 /* Check for primary buffer flags change */
456 ok(new_dsbcaps
.dwFlags
== dsbcaps
.dwFlags
,
457 " flags changed after SetFormat() - "
458 "previous flags were %08x, current flags are %08x\n",
459 dsbcaps
.dwFlags
, new_dsbcaps
.dwFlags
);
461 /* Set the CooperativeLevel back to normal */
462 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
463 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
464 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %08x\n",rc
);
469 DS3DLISTENER listener_param
;
470 LPDIRECTSOUND3DBUFFER buffer
=NULL
;
471 DS3DBUFFER buffer_param
;
472 DWORD start_time
,now
;
476 if (winetest_interactive
) {
478 trace(" Playing %g second 440Hz tone at %dx%dx%d with a "
479 "frequency of %d (%dHz)\n", duration
,
480 wfx
.nSamplesPerSec
, wfx
.wBitsPerSample
, wfx
.nChannels
,
481 frequency
, (440 * frequency
) / wfx
.nSamplesPerSec
);
483 trace(" Playing %g second 440Hz tone at %dx%dx%d\n", duration
,
484 wfx
.nSamplesPerSec
, wfx
.wBitsPerSample
, wfx
.nChannels
);
488 /* We must call SetCooperativeLevel to be allowed to call Lock */
489 /* DSOUND: Setting DirectSound cooperative level to
490 * DSSCL_WRITEPRIMARY */
491 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),
493 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_WRITEPRIMARY) "
494 "failed: %08x\n",rc
);
499 LPDIRECTSOUNDBUFFER temp_buffer
;
501 rc
=IDirectSoundBuffer_QueryInterface(*dsbo
,&IID_IDirectSound3DBuffer
,
503 ok(rc
==DS_OK
,"IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc
);
507 /* check the COM interface */
508 rc
=IDirectSoundBuffer_QueryInterface(*dsbo
, &IID_IDirectSoundBuffer
,
509 (LPVOID
*)&temp_buffer
);
510 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
511 "IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc
);
512 ok(temp_buffer
==*dsbo
,"COM interface broken: %p != %p\n",
514 ref
=IDirectSoundBuffer_Release(temp_buffer
);
515 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
516 "should have 1\n",ref
);
519 rc
=IDirectSound3DBuffer_QueryInterface(*dsbo
,
520 &IID_IDirectSoundBuffer
,
521 (LPVOID
*)&temp_buffer
);
522 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
523 "IDirectSound3DBuffer_QueryInterface() failed: %08x\n", rc
);
524 ok(temp_buffer
==*dsbo
,"COM interface broken: %p != %p\n",
526 ref
=IDirectSoundBuffer_Release(temp_buffer
);
527 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
528 "should have 1\n",ref
);
530 ref
=IDirectSoundBuffer_Release(*dsbo
);
531 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
532 "should have 0\n",ref
);
534 rc
=IDirectSound3DBuffer_QueryInterface(buffer
,
535 &IID_IDirectSoundBuffer
,
537 ok(rc
==DS_OK
&& *dsbo
!=NULL
,"IDirectSound3DBuffer_QueryInterface() "
538 "failed: %08x\n",rc
);
540 /* DSOUND: Error: Invalid buffer */
541 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,0);
542 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound3DBuffer_GetAllParameters() "
543 "failed: %08x\n",rc
);
545 ZeroMemory(&buffer_param
, sizeof(buffer_param
));
547 /* DSOUND: Error: Invalid buffer */
548 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,&buffer_param
);
549 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound3DBuffer_GetAllParameters() "
550 "failed: %08x\n",rc
);
552 buffer_param
.dwSize
=sizeof(buffer_param
);
553 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,&buffer_param
);
554 ok(rc
==DS_OK
,"IDirectSound3DBuffer_GetAllParameters() failed: %08x\n", rc
);
557 if (dsbcaps
.dwFlags
& DSBCAPS_CTRLVOLUME
) {
559 rc
=IDirectSoundBuffer_GetVolume(*dsbo
,&val
);
560 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc
);
562 rc
=IDirectSoundBuffer_SetVolume(*dsbo
,volume
);
563 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume() failed: %08x\n", rc
);
565 /* DSOUND: Error: Buffer does not have CTRLVOLUME */
566 rc
=IDirectSoundBuffer_GetVolume(*dsbo
,&volume
);
567 ok(rc
==DSERR_CONTROLUNAVAIL
,"IDirectSoundBuffer_GetVolume() "
568 "should have returned DSERR_CONTROLUNAVAIL, returned: %08x\n", rc
);
573 if (dsbcaps
.dwFlags
& DSBCAPS_CTRLPAN
) {
575 rc
=IDirectSoundBuffer_GetPan(*dsbo
,&val
);
576 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan() failed: %08x\n", rc
);
578 rc
=IDirectSoundBuffer_SetPan(*dsbo
,pan
);
579 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan() failed: %08x\n", rc
);
581 /* DSOUND: Error: Buffer does not have CTRLPAN */
582 rc
=IDirectSoundBuffer_GetPan(*dsbo
,&pan
);
583 ok(rc
==DSERR_CONTROLUNAVAIL
,"IDirectSoundBuffer_GetPan() "
584 "should have returned DSERR_CONTROLUNAVAIL, returned: %08x\n", rc
);
588 /* try an offset past the end of the buffer */
589 rc
= IDirectSoundBuffer_Lock(*dsbo
, dsbcaps
.dwBufferBytes
, 0, &buffer1
,
590 &length1
, NULL
, NULL
,
591 DSBLOCK_ENTIREBUFFER
);
592 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSoundBuffer_Lock() should have "
593 "returned DSERR_INVALIDPARAM, returned %08x\n", rc
);
595 /* try a size larger than the buffer */
596 rc
= IDirectSoundBuffer_Lock(*dsbo
, 0, dsbcaps
.dwBufferBytes
+ 1,
597 &buffer1
, &length1
, NULL
, NULL
,
598 DSBLOCK_FROMWRITECURSOR
);
599 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSoundBuffer_Lock() should have "
600 "returned DSERR_INVALIDPARAM, returned %08x\n", rc
);
603 state
.wave
=wave_generate_la(&wfx
,(duration
*frequency
)/wfx
.nSamplesPerSec
,&state
.wave_len
);
605 state
.wave
=wave_generate_la(&wfx
,duration
,&state
.wave_len
);
609 state
.buffer_size
=dsbcaps
.dwBufferBytes
;
610 state
.played
=state
.written
=state
.offset
=0;
611 buffer_refill(&state
,state
.buffer_size
);
613 rc
=IDirectSoundBuffer_Play(*dsbo
,0,0,DSBPLAY_LOOPING
);
614 ok(rc
==DS_OK
,"IDirectSoundBuffer_Play() failed: %08x\n", rc
);
616 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,&status
);
617 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetStatus() failed: %08x\n", rc
);
618 ok(status
==(DSBSTATUS_PLAYING
|DSBSTATUS_LOOPING
),
619 "GetStatus: bad status: %x\n",status
);
622 ZeroMemory(&listener_param
,sizeof(listener_param
));
623 listener_param
.dwSize
=sizeof(listener_param
);
624 rc
=IDirectSound3DListener_GetAllParameters(listener
,
626 ok(rc
==DS_OK
,"IDirectSound3dListener_GetAllParameters() "
627 "failed: %08x\n",rc
);
629 listener_param
.vPosition
.x
= -5.0f
;
630 listener_param
.vVelocity
.x
= (float)(10.0/duration
);
632 rc
=IDirectSound3DListener_SetAllParameters(listener
,
635 ok(rc
==DS_OK
,"IDirectSound3dListener_SetPosition() failed: %08x\n", rc
);
639 buffer_param
.vPosition
.x
= 100.0f
;
640 buffer_param
.vVelocity
.x
= (float)(-200.0/duration
);
642 buffer_param
.flMinDistance
= 10;
643 rc
=IDirectSound3DBuffer_SetAllParameters(buffer
,&buffer_param
,
645 ok(rc
==DS_OK
,"IDirectSound3dBuffer_SetPosition() failed: %08x\n", rc
);
648 start_time
=GetTickCount();
649 while (buffer_service(&state
)) {
650 WaitForSingleObject(GetCurrentProcess(),TIME_SLICE
);
652 if (listener
&& move_listener
) {
653 listener_param
.vPosition
.x
= (float)(-5.0+10.0*(now
-start_time
)/1000/duration
);
654 if (winetest_debug
>2)
655 trace("listener position=%g\n",listener_param
.vPosition
.x
);
656 rc
=IDirectSound3DListener_SetPosition(listener
,
657 listener_param
.vPosition
.x
,listener_param
.vPosition
.y
,
658 listener_param
.vPosition
.z
,DS3D_IMMEDIATE
);
659 ok(rc
==DS_OK
,"IDirectSound3dListener_SetPosition() failed: %08x\n",rc
);
661 if (buffer3d
&& move_sound
) {
662 buffer_param
.vPosition
.x
= (float)(100-200.0*(now
-start_time
)/1000/duration
);
663 if (winetest_debug
>2)
664 trace("sound position=%g\n",buffer_param
.vPosition
.x
);
665 rc
=IDirectSound3DBuffer_SetPosition(buffer
,
666 buffer_param
.vPosition
.x
,buffer_param
.vPosition
.y
,
667 buffer_param
.vPosition
.z
,DS3D_IMMEDIATE
);
668 ok(rc
==DS_OK
,"IDirectSound3dBuffer_SetPosition() failed: %08x\n", rc
);
671 /* Check the sound duration was within 10% of the expected value */
673 ok(fabs(1000*duration
-now
+start_time
)<=100*duration
,
674 "The sound played for %d ms instead of %g ms\n",
675 now
-start_time
,1000*duration
);
677 HeapFree(GetProcessHeap(), 0, state
.wave
);
679 /* Set the CooperativeLevel back to normal */
680 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
681 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
682 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) "
683 "failed: %08x\n",rc
);
686 ref
=IDirectSound3DBuffer_Release(buffer
);
687 ok(ref
==0,"IDirectSound3DBuffer_Release() has %d references, "
688 "should have 0\n",ref
);
693 static HRESULT
test_secondary(LPGUID lpGuid
, int play
,
694 int has_3d
, int has_3dbuffer
,
695 int has_listener
, int has_duplicate
,
696 int move_listener
, int move_sound
)
699 LPDIRECTSOUND dso
=NULL
;
700 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
701 LPDIRECTSOUND3DLISTENER listener
=NULL
;
702 DSBUFFERDESC bufdesc
;
703 WAVEFORMATEX wfx
, wfx1
;
706 /* Create the DirectSound object */
707 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
708 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %08x\n", rc
);
712 /* We must call SetCooperativeLevel before creating primary buffer */
713 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
714 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
715 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc
);
719 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
720 bufdesc
.dwSize
=sizeof(bufdesc
);
721 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
723 bufdesc
.dwFlags
|=DSBCAPS_CTRL3D
;
725 bufdesc
.dwFlags
|=(DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
);
726 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
727 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
728 "IDirectSound_CreateSoundBuffer() failed to create a %sprimary buffer: %08x\n",has_3d
?"3D ":"", rc
);
729 if (rc
==DSERR_CONTROLUNAVAIL
)
730 trace(" No Primary\n");
731 else if (rc
==DS_OK
&& primary
!=NULL
) {
732 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
733 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc
);
738 rc
=IDirectSoundBuffer_QueryInterface(primary
,
739 &IID_IDirectSound3DListener
,
741 ok(rc
==DS_OK
&& listener
!=NULL
,
742 "IDirectSoundBuffer_QueryInterface() failed to get a 3D listener: %08x\n",rc
);
743 ref
=IDirectSoundBuffer_Release(primary
);
744 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
745 "should have 0\n",ref
);
746 if (rc
==DS_OK
&& listener
!=NULL
) {
747 DS3DLISTENER listener_param
;
748 ZeroMemory(&listener_param
,sizeof(listener_param
));
749 /* DSOUND: Error: Invalid buffer */
750 rc
=IDirectSound3DListener_GetAllParameters(listener
,0);
751 ok(rc
==DSERR_INVALIDPARAM
,
752 "IDirectSound3dListener_GetAllParameters() should have "
753 "returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
755 /* DSOUND: Error: Invalid buffer */
756 rc
=IDirectSound3DListener_GetAllParameters(listener
,
758 ok(rc
==DSERR_INVALIDPARAM
,
759 "IDirectSound3dListener_GetAllParameters() should have "
760 "returned DSERR_INVALIDPARAM, returned: %08x\n", rc
);
762 listener_param
.dwSize
=sizeof(listener_param
);
763 rc
=IDirectSound3DListener_GetAllParameters(listener
,
765 ok(rc
==DS_OK
,"IDirectSound3dListener_GetAllParameters() "
766 "failed: %08x\n",rc
);
768 ok(listener
==NULL
, "IDirectSoundBuffer_QueryInterface() "
769 "failed but returned a listener anyway\n");
770 ok(rc
!=DS_OK
, "IDirectSoundBuffer_QueryInterface() succeeded "
771 "but returned a NULL listener\n");
773 ref
=IDirectSound3DListener_Release(listener
);
774 ok(ref
==0,"IDirectSound3dListener_Release() listener has "
775 "%d references, should have 0\n",ref
);
781 init_format(&wfx
,WAVE_FORMAT_PCM
,22050,16,2);
783 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
784 bufdesc
.dwSize
=sizeof(bufdesc
);
785 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
787 bufdesc
.dwFlags
|=DSBCAPS_CTRL3D
;
790 (DSBCAPS_CTRLFREQUENCY
|DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
);
791 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
793 bufdesc
.lpwfxFormat
=&wfx
;
794 if (winetest_interactive
) {
795 trace(" Testing a %s%ssecondary buffer %s%s%s%sat %dx%dx%d "
796 "with a primary buffer at %dx%dx%d\n",
797 has_3dbuffer
?"3D ":"",
798 has_duplicate
?"duplicated ":"",
799 listener
!=NULL
||move_sound
?"with ":"",
800 move_listener
?"moving ":"",
801 listener
!=NULL
?"listener ":"",
802 listener
&&move_sound
?"and moving sound ":move_sound
?
804 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
805 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
807 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
808 ok(rc
==DS_OK
&& secondary
!=NULL
,"IDirectSound_CreateSoundBuffer() "
809 "failed to create a %s%ssecondary buffer %s%s%s%sat %dx%dx%d (%s): %08x\n",
810 has_3dbuffer
?"3D ":"", has_duplicate
?"duplicated ":"",
811 listener
!=NULL
||move_sound
?"with ":"", move_listener
?"moving ":"",
812 listener
!=NULL
?"listener ":"",
813 listener
&&move_sound
?"and moving sound ":move_sound
?
815 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
816 getDSBCAPS(bufdesc
.dwFlags
),rc
);
817 if (rc
==DS_OK
&& secondary
!=NULL
) {
819 LONG refvol
,vol
,refpan
,pan
;
821 /* Check the initial secondary buffer's volume and pan */
822 rc
=IDirectSoundBuffer_GetVolume(secondary
,&vol
);
823 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(secondary) failed: %08x\n",rc
);
824 ok(vol
==0,"wrong volume for a new secondary buffer: %d\n",vol
);
825 rc
=IDirectSoundBuffer_GetPan(secondary
,&pan
);
826 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(secondary) failed: %08x\n",rc
);
827 ok(pan
==0,"wrong pan for a new secondary buffer: %d\n",pan
);
829 /* Check that changing the secondary buffer's volume and pan
830 * does not impact the primary buffer's volume and pan
832 rc
=IDirectSoundBuffer_GetVolume(primary
,&refvol
);
833 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(primary) failed: %08x\n",rc
);
834 rc
=IDirectSoundBuffer_GetPan(primary
,&refpan
);
835 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(primary) failed: %08x\n", rc
);
837 rc
=IDirectSoundBuffer_SetVolume(secondary
,-1000);
838 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: %08x\n",rc
);
839 rc
=IDirectSoundBuffer_GetVolume(secondary
,&vol
);
840 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: %08x\n",rc
);
841 ok(vol
==-1000,"secondary: wrong volume %d instead of -1000\n",
843 rc
=IDirectSoundBuffer_SetPan(secondary
,-1000);
844 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: %08x\n",rc
);
845 rc
=IDirectSoundBuffer_GetPan(secondary
,&pan
);
846 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: %08x\n",rc
);
847 ok(pan
==-1000,"secondary: wrong pan %d instead of -1000\n",
850 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
851 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(primary) failed: %08x\n",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: %08x\n", rc
);
856 ok(pan
==refpan
,"The primary pan changed from %d to %d\n",
859 rc
=IDirectSoundBuffer_SetVolume(secondary
,0);
860 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: %08x\n",rc
);
861 rc
=IDirectSoundBuffer_SetPan(secondary
,0);
862 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: %08x\n",rc
);
865 LPDIRECTSOUNDBUFFER duplicated
=NULL
;
867 /* DSOUND: Error: Invalid source buffer */
868 rc
=IDirectSound_DuplicateSoundBuffer(dso
,0,0);
869 ok(rc
==DSERR_INVALIDPARAM
,
870 "IDirectSound_DuplicateSoundBuffer() should have returned "
871 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
873 /* DSOUND: Error: Invalid dest buffer */
874 rc
=IDirectSound_DuplicateSoundBuffer(dso
,secondary
,0);
875 ok(rc
==DSERR_INVALIDPARAM
,
876 "IDirectSound_DuplicateSoundBuffer() should have returned "
877 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
879 /* DSOUND: Error: Invalid source buffer */
880 rc
=IDirectSound_DuplicateSoundBuffer(dso
,0,&duplicated
);
881 ok(rc
==DSERR_INVALIDPARAM
,
882 "IDirectSound_DuplicateSoundBuffer() should have returned "
883 "DSERR_INVALIDPARAM, returned: %08x\n",rc
);
886 rc
=IDirectSound_DuplicateSoundBuffer(dso
,secondary
,
888 ok(rc
==DS_OK
&& duplicated
!=NULL
,
889 "IDirectSound_DuplicateSoundBuffer() failed to duplicate "
890 "a secondary buffer: %08x\n",rc
);
892 if (rc
==DS_OK
&& duplicated
!=NULL
) {
893 ref
=IDirectSoundBuffer_Release(secondary
);
894 ok(ref
==0,"IDirectSoundBuffer_Release() secondary has %d "
895 "references, should have 0\n",ref
);
896 secondary
=duplicated
;
900 if (rc
==DS_OK
&& secondary
!=NULL
) {
902 duration
=(move_listener
|| move_sound
?4.0:1.0);
903 test_buffer(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
904 winetest_interactive
,duration
,has_3dbuffer
,
905 listener
,move_listener
,move_sound
,FALSE
,0);
906 ref
=IDirectSoundBuffer_Release(secondary
);
907 ok(ref
==0,"IDirectSoundBuffer_Release() %s has %d references, "
908 "should have 0\n",has_duplicate
?"duplicated":"secondary",
914 ref
=IDirectSound3DListener_Release(listener
);
915 ok(ref
==0,"IDirectSound3dListener_Release() listener has %d "
916 "references, should have 0\n",ref
);
918 ref
=IDirectSoundBuffer_Release(primary
);
919 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
920 "should have 0\n",ref
);
923 ok(primary
==NULL
,"IDirectSound_CreateSoundBuffer(primary) failed "
924 "but primary created anyway\n");
925 ok(rc
!=DS_OK
,"IDirectSound_CreateSoundBuffer(primary) succeeded "
926 "but primary not created\n");
928 ref
=IDirectSoundBuffer_Release(primary
);
929 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
930 "should have 0\n",ref
);
934 /* Set the CooperativeLevel back to normal */
935 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
936 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
937 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %08x\n", rc
);
940 ref
=IDirectSound_Release(dso
);
941 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
943 return DSERR_GENERIC
;
948 static HRESULT
test_for_driver(LPGUID lpGuid
)
951 LPDIRECTSOUND dso
=NULL
;
954 /* Create the DirectSound object */
955 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
956 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
957 "DirectSoundCreate() failed: %08x\n",rc
);
961 ref
=IDirectSound_Release(dso
);
962 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
964 return DSERR_GENERIC
;
969 static HRESULT
test_primary(LPGUID lpGuid
)
972 LPDIRECTSOUND dso
=NULL
;
973 LPDIRECTSOUNDBUFFER primary
=NULL
;
974 DSBUFFERDESC bufdesc
;
978 /* Create the DirectSound object */
979 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
980 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %08x\n", rc
);
984 /* Get the device capabilities */
985 ZeroMemory(&dscaps
, sizeof(dscaps
));
986 dscaps
.dwSize
=sizeof(dscaps
);
987 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
988 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %08x\n",rc
);
992 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
993 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
994 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
995 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc
);
999 /* Testing the primary buffer */
1001 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1002 bufdesc
.dwSize
=sizeof(bufdesc
);
1003 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
;
1004 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1005 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
1006 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: %08x\n",rc
);
1007 if (rc
==DSERR_CONTROLUNAVAIL
)
1008 trace(" No Primary\n");
1009 else if (rc
==DS_OK
&& primary
!=NULL
) {
1010 test_buffer(dso
,&primary
,1,TRUE
,0,TRUE
,0,winetest_interactive
&&
1011 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,NULL
,0,0,
1013 if (winetest_interactive
) {
1016 volume
= DSBVOLUME_MAX
;
1017 for (i
= 0; i
< 6; i
++) {
1018 test_buffer(dso
,&primary
,1,TRUE
,volume
,TRUE
,0,
1019 winetest_interactive
&&
1020 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),
1021 1.0,0,NULL
,0,0,FALSE
,0);
1022 volume
-= ((DSBVOLUME_MAX
-DSBVOLUME_MIN
) / 40);
1026 for (i
= 0; i
< 7; i
++) {
1027 test_buffer(dso
,&primary
,1,TRUE
,0,TRUE
,pan
,
1028 winetest_interactive
&&
1029 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,0,0,0,FALSE
,0);
1030 pan
+= ((DSBPAN_RIGHT
-DSBPAN_LEFT
) / 6);
1033 ref
=IDirectSoundBuffer_Release(primary
);
1034 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1035 "should have 0\n",ref
);
1038 /* Set the CooperativeLevel back to normal */
1039 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1040 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1041 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %08x\n", rc
);
1044 ref
=IDirectSound_Release(dso
);
1045 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1047 return DSERR_GENERIC
;
1052 static HRESULT
test_primary_3d(LPGUID lpGuid
)
1055 LPDIRECTSOUND dso
=NULL
;
1056 LPDIRECTSOUNDBUFFER primary
=NULL
;
1057 DSBUFFERDESC bufdesc
;
1061 /* Create the DirectSound object */
1062 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1063 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %08x\n", rc
);
1067 /* Get the device capabilities */
1068 ZeroMemory(&dscaps
, sizeof(dscaps
));
1069 dscaps
.dwSize
=sizeof(dscaps
);
1070 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1071 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %08x\n",rc
);
1075 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1076 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1077 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1078 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc
);
1083 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1084 bufdesc
.dwSize
=sizeof(bufdesc
);
1085 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
1086 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1087 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1088 "to create a primary buffer: %08x\n",rc
);
1089 if (rc
==DS_OK
&& primary
!=NULL
) {
1090 ref
=IDirectSoundBuffer_Release(primary
);
1091 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1092 "should have 0\n",ref
);
1094 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1095 bufdesc
.dwSize
=sizeof(bufdesc
);
1096 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRL3D
;
1097 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1098 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() "
1099 "failed to create a 3D primary buffer: %08x\n",rc
);
1100 if (rc
==DS_OK
&& primary
!=NULL
) {
1101 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
1102 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,0,0,0,
1104 ref
=IDirectSoundBuffer_Release(primary
);
1105 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1106 "should have 0\n",ref
);
1109 /* Set the CooperativeLevel back to normal */
1110 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1111 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1112 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %08x\n", rc
);
1115 ref
=IDirectSound_Release(dso
);
1116 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1118 return DSERR_GENERIC
;
1123 static HRESULT
test_primary_3d_with_listener(LPGUID lpGuid
)
1126 LPDIRECTSOUND dso
=NULL
;
1127 LPDIRECTSOUNDBUFFER primary
=NULL
;
1128 DSBUFFERDESC bufdesc
;
1132 /* Create the DirectSound object */
1133 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1134 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %08x\n", rc
);
1138 /* Get the device capabilities */
1139 ZeroMemory(&dscaps
, sizeof(dscaps
));
1140 dscaps
.dwSize
=sizeof(dscaps
);
1141 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1142 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %08x\n",rc
);
1146 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1147 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1148 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1149 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: %08x\n",rc
);
1153 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1154 bufdesc
.dwSize
=sizeof(bufdesc
);
1155 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRL3D
;
1156 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1157 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1158 "to create a 3D primary buffer: %08x\n",rc
);
1159 if (rc
==DS_OK
&& primary
!=NULL
) {
1160 LPDIRECTSOUND3DLISTENER listener
=NULL
;
1161 LPDIRECTSOUNDBUFFER temp_buffer
=NULL
;
1162 rc
=IDirectSoundBuffer_QueryInterface(primary
,
1163 &IID_IDirectSound3DListener
,(void **)&listener
);
1164 ok(rc
==DS_OK
&& listener
!=NULL
,"IDirectSoundBuffer_QueryInterface() "
1165 "failed to get a 3D listener: %08x\n",rc
);
1166 if (rc
==DS_OK
&& listener
!=NULL
) {
1167 /* Checking the COM interface */
1168 rc
=IDirectSoundBuffer_QueryInterface(primary
,
1169 &IID_IDirectSoundBuffer
,(LPVOID
*)&temp_buffer
);
1170 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1171 "IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc
);
1172 ok(temp_buffer
==primary
,
1173 "COM interface broken: %p != %p\n",
1174 temp_buffer
,primary
);
1175 if (rc
==DS_OK
&& temp_buffer
!=NULL
) {
1176 ref
=IDirectSoundBuffer_Release(temp_buffer
);
1177 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
1178 "should have 1\n",ref
);
1181 rc
=IDirectSound3DListener_QueryInterface(listener
,
1182 &IID_IDirectSoundBuffer
,(LPVOID
*)&temp_buffer
);
1183 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1184 "IDirectSoundBuffer_QueryInterface() failed: %08x\n", rc
);
1185 ok(temp_buffer
==primary
,
1186 "COM interface broken: %p != %p\n",
1187 temp_buffer
,primary
);
1188 ref
=IDirectSoundBuffer_Release(temp_buffer
);
1189 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
1190 "should have 1\n",ref
);
1192 /* Testing the buffer */
1193 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,
1194 winetest_interactive
&&
1195 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,
1196 listener
,0,0,FALSE
,0);
1200 rc
=IDirectSound3DListener_QueryInterface(listener
,
1201 &IID_IKsPropertySet
,(LPVOID
*)&temp_buffer
);
1202 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1203 "IDirectSound3DListener_QueryInterface didn't handle IKsPropertySet: ret = %08x\n", rc
);
1205 IKsPropertySet_Release(temp_buffer
);
1209 /* Testing the reference counting */
1210 ref
=IDirectSound3DListener_Release(listener
);
1211 ok(ref
==0,"IDirectSound3DListener_Release() listener has %d "
1212 "references, should have 0\n",ref
);
1217 rc
=IDirectSoundBuffer_QueryInterface(primary
,
1218 &IID_IKsPropertySet
,(LPVOID
*)&temp_buffer
);
1219 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1220 "IDirectSoundBuffer_QueryInterface didn't handle IKsPropertySet on primary buffer: ret = %08x\n", rc
);
1222 IKsPropertySet_Release(temp_buffer
);
1225 /* Testing the reference counting */
1226 ref
=IDirectSoundBuffer_Release(primary
);
1227 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1228 "should have 0\n",ref
);
1232 ref
=IDirectSound_Release(dso
);
1233 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1235 return DSERR_GENERIC
;
1240 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
1241 LPCSTR lpcstrModule
, LPVOID lpContext
)
1244 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
1246 rc
= test_for_driver(lpGuid
);
1247 if (rc
== DSERR_NODRIVER
) {
1248 trace(" No Driver\n");
1250 } else if (rc
== DSERR_ALLOCATED
) {
1251 trace(" Already In Use\n");
1253 } else if (rc
== E_FAIL
) {
1254 trace(" No Device\n");
1258 trace(" Testing the primary buffer\n");
1259 test_primary(lpGuid
);
1261 trace(" Testing 3D primary buffer\n");
1262 test_primary_3d(lpGuid
);
1264 trace(" Testing 3D primary buffer with listener\n");
1265 test_primary_3d_with_listener(lpGuid
);
1267 /* Testing secondary buffers */
1268 test_secondary(lpGuid
,winetest_interactive
,0,0,0,0,0,0);
1269 test_secondary(lpGuid
,winetest_interactive
,0,0,0,1,0,0);
1271 /* Testing 3D secondary buffers */
1272 test_secondary(lpGuid
,winetest_interactive
,1,0,0,0,0,0);
1273 test_secondary(lpGuid
,winetest_interactive
,1,1,0,0,0,0);
1274 test_secondary(lpGuid
,winetest_interactive
,1,1,0,1,0,0);
1275 test_secondary(lpGuid
,winetest_interactive
,1,0,1,0,0,0);
1276 test_secondary(lpGuid
,winetest_interactive
,1,0,1,1,0,0);
1277 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,0,0);
1278 test_secondary(lpGuid
,winetest_interactive
,1,1,1,1,0,0);
1279 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,1,0);
1280 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,0,1);
1281 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,1,1);
1286 static void ds3d_tests(void)
1289 rc
=pDirectSoundEnumerateA(&dsenum_callback
,NULL
);
1290 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %08x\n",rc
);
1299 hDsound
= LoadLibrary("dsound.dll");
1303 pDirectSoundEnumerateA
= (void*)GetProcAddress(hDsound
,
1304 "DirectSoundEnumerateA");
1305 pDirectSoundCreate
= (void*)GetProcAddress(hDsound
,
1306 "DirectSoundCreate");
1310 FreeLibrary(hDsound
);
1313 skip("dsound.dll not found!\n");