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)
61 signed short sample
=(signed short)((double)32767.5*y
-0.5);
65 if (wfx
->nChannels
==2) {
75 const char * getDSBCAPS(DWORD xmask
) {
80 #define FE(x) { x, #x },
81 FE(DSBCAPS_PRIMARYBUFFER
)
83 FE(DSBCAPS_LOCHARDWARE
)
84 FE(DSBCAPS_LOCSOFTWARE
)
86 FE(DSBCAPS_CTRLFREQUENCY
)
88 FE(DSBCAPS_CTRLVOLUME
)
89 FE(DSBCAPS_CTRLPOSITIONNOTIFY
)
90 FE(DSBCAPS_STICKYFOCUS
)
91 FE(DSBCAPS_GLOBALFOCUS
)
92 FE(DSBCAPS_GETCURRENTPOSITION2
)
93 FE(DSBCAPS_MUTE3DATMAXDISTANCE
)
96 static char buffer
[512];
102 for (i
=0;i
<sizeof(flags
)/sizeof(flags
[0]);i
++) {
103 if ((flags
[i
].mask
& xmask
) == flags
[i
].mask
) {
108 strcat(buffer
, flags
[i
].name
);
117 HWND hwnd
=GetForegroundWindow();
119 hwnd
=GetDesktopWindow();
123 void init_format(WAVEFORMATEX
* wfx
, int format
, int rate
, int depth
,
126 wfx
->wFormatTag
=format
;
127 wfx
->nChannels
=channels
;
128 wfx
->wBitsPerSample
=depth
;
129 wfx
->nSamplesPerSec
=rate
;
130 wfx
->nBlockAlign
=wfx
->nChannels
*wfx
->wBitsPerSample
/8;
131 /* FIXME: Shouldn't this test be if (format!=WAVE_FORMAT_PCM) */
132 if (wfx
->nBlockAlign
==0)
134 /* align compressed formats to byte boundary */
137 wfx
->nAvgBytesPerSec
=wfx
->nSamplesPerSec
*wfx
->nBlockAlign
;
145 LPDIRECTSOUNDBUFFER dsbo
;
153 static int buffer_refill(play_state_t
* state
, DWORD size
)
159 if (size
>state
->wave_len
-state
->written
)
160 size
=state
->wave_len
-state
->written
;
162 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
163 &ptr1
,&len1
,&ptr2
,&len2
,0);
164 ok(rc
==DS_OK
,"IDirectSoundBuffer_Lock() failed: %s\n",
165 DXGetErrorString8(rc
));
169 memcpy(ptr1
,state
->wave
+state
->written
,len1
);
170 state
->written
+=len1
;
172 memcpy(ptr2
,state
->wave
+state
->written
,len2
);
173 state
->written
+=len2
;
175 state
->offset
=state
->written
% state
->buffer_size
;
176 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,ptr1
,len1
,ptr2
,len2
);
177 ok(rc
==DS_OK
,"IDirectSoundBuffer_Unlock() failed: %s\n",
178 DXGetErrorString8(rc
));
184 static int buffer_silence(play_state_t
* state
, DWORD size
)
191 rc
=IDirectSoundBuffer_Lock(state
->dsbo
,state
->offset
,size
,
192 &ptr1
,&len1
,&ptr2
,&len2
,0);
193 ok(rc
==DS_OK
,"IDirectSoundBuffer_Lock() failed: %s\n",
194 DXGetErrorString8(rc
));
198 s
=(state
->wfx
->wBitsPerSample
==8?0x80:0);
203 state
->offset
=(state
->offset
+size
) % state
->buffer_size
;
204 rc
=IDirectSoundBuffer_Unlock(state
->dsbo
,ptr1
,len1
,ptr2
,len2
);
205 ok(rc
==DS_OK
,"IDirectSoundBuffer_Unlock() failed: %s\n",
206 DXGetErrorString8(rc
));
212 static int buffer_service(play_state_t
* state
)
214 DWORD last_play_pos
,play_pos
,buf_free
;
217 rc
=IDirectSoundBuffer_GetCurrentPosition(state
->dsbo
,&play_pos
,NULL
);
218 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCurrentPosition() failed: %s\n",
219 DXGetErrorString8(rc
));
224 /* Update the amount played */
225 last_play_pos
=state
->played
% state
->buffer_size
;
226 if (play_pos
<last_play_pos
)
227 state
->played
+=state
->buffer_size
-last_play_pos
+play_pos
;
229 state
->played
+=play_pos
-last_play_pos
;
231 if (winetest_debug
> 1)
232 trace("buf size=%d last_play_pos=%d play_pos=%d played=%d / %d\n",
233 state
->buffer_size
,last_play_pos
,play_pos
,state
->played
,
236 if (state
->played
>state
->wave_len
)
238 /* Everything has been played */
242 /* Refill the buffer */
243 if (state
->offset
<=play_pos
)
244 buf_free
=play_pos
-state
->offset
;
246 buf_free
=state
->buffer_size
-state
->offset
+play_pos
;
248 if (winetest_debug
> 1)
249 trace("offset=%d free=%d written=%d / %d\n",
250 state
->offset
,buf_free
,state
->written
,state
->wave_len
);
254 if (state
->written
<state
->wave_len
)
256 int w
=buffer_refill(state
,buf_free
);
260 if (state
->written
==state
->wave_len
&& winetest_debug
> 1)
261 trace("last sound byte at %d\n",
262 (state
->written
% state
->buffer_size
));
266 /* Fill with silence */
267 if (winetest_debug
> 1)
268 trace("writing %d bytes of silence\n",buf_free
);
269 if (buffer_silence(state
,buf_free
)==-1)
275 if (winetest_debug
> 1)
276 trace("stopping playback\n");
277 rc
=IDirectSoundBuffer_Stop(state
->dsbo
);
278 ok(rc
==DS_OK
,"IDirectSoundBuffer_Stop() failed: %s\n",
279 DXGetErrorString8(rc
));
283 void test_buffer(LPDIRECTSOUND dso
, LPDIRECTSOUNDBUFFER
*dsbo
,
284 BOOL is_primary
, BOOL set_volume
, LONG volume
,
285 BOOL set_pan
, LONG pan
, BOOL play
, double duration
,
286 BOOL buffer3d
, LPDIRECTSOUND3DLISTENER listener
,
287 BOOL move_listener
, BOOL move_sound
,
288 BOOL set_frequency
, DWORD frequency
)
292 WAVEFORMATEX wfx
,wfx2
;
293 DWORD size
,status
,freq
;
297 rc
=IDirectSoundBuffer_SetFrequency(*dsbo
,frequency
);
298 ok(rc
==DS_OK
||rc
==DSERR_CONTROLUNAVAIL
,
299 "IDirectSoundBuffer_SetFrequency() failed to set frequency "
300 "%s\n",DXGetErrorString8(rc
));
305 /* DSOUND: Error: Invalid caps pointer */
306 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,0);
307 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetCaps() should have "
308 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
310 ZeroMemory(&dsbcaps
, sizeof(dsbcaps
));
312 /* DSOUND: Error: Invalid caps pointer */
313 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&dsbcaps
);
314 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetCaps() should have "
315 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
317 dsbcaps
.dwSize
=sizeof(dsbcaps
);
318 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&dsbcaps
);
319 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() failed: %s\n",
320 DXGetErrorString8(rc
));
321 if (rc
==DS_OK
&& winetest_debug
> 1) {
322 trace(" Caps: flags=0x%08x size=%d\n",dsbcaps
.dwFlags
,
323 dsbcaps
.dwBufferBytes
);
326 /* Query the format size. Note that it may not match sizeof(wfx) */
328 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,NULL
,0,&size
);
329 ok(rc
==DS_OK
&& size
!=0,"IDirectSoundBuffer_GetFormat() should have "
330 "returned the needed size: rc=%s size=%d\n",DXGetErrorString8(rc
),size
);
332 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,&wfx
,sizeof(wfx
),NULL
);
333 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %s\n",
334 DXGetErrorString8(rc
));
335 if (rc
==DS_OK
&& winetest_debug
> 1) {
336 trace(" Format: %s tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
337 is_primary
? "Primary" : "Secondary",
338 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
339 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
342 /* DSOUND: Error: Invalid frequency buffer */
343 rc
=IDirectSoundBuffer_GetFrequency(*dsbo
,0);
344 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetFrequency() should have "
345 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
347 /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */
348 rc
=IDirectSoundBuffer_GetFrequency(*dsbo
,&freq
);
349 ok((rc
==DS_OK
&& !is_primary
) || (rc
==DSERR_CONTROLUNAVAIL
&&is_primary
) ||
350 (rc
==DSERR_CONTROLUNAVAIL
&&!(dsbcaps
.dwFlags
&DSBCAPS_CTRLFREQUENCY
)),
351 "IDirectSoundBuffer_GetFrequency() failed: %s\n",DXGetErrorString8(rc
));
353 DWORD f
= set_frequency
?frequency
:wfx
.nSamplesPerSec
;
354 ok(freq
==f
,"The frequency returned by GetFrequency "
355 "%d does not match the format %d\n",freq
,f
);
358 /* DSOUND: Error: Invalid status pointer */
359 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,0);
360 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_GetStatus() should have "
361 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
363 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,&status
);
364 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetStatus() failed: %s\n",
365 DXGetErrorString8(rc
));
366 ok(status
==0,"status=0x%x instead of 0\n",status
);
370 /* We must call SetCooperativeLevel to be allowed to call SetFormat */
371 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
372 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
373 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
374 "%s\n",DXGetErrorString8(rc
));
378 /* DSOUND: Error: Invalid format pointer */
379 rc
=IDirectSoundBuffer_SetFormat(*dsbo
,0);
380 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSoundBuffer_SetFormat() should have "
381 "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
383 init_format(&wfx2
,WAVE_FORMAT_PCM
,11025,16,2);
384 rc
=IDirectSoundBuffer_SetFormat(*dsbo
,&wfx2
);
385 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetFormat(%s) failed: %s\n",
386 format_string(&wfx2
), DXGetErrorString8(rc
));
388 /* There is no guarantee that SetFormat will actually change the
389 * format to what we asked for. It depends on what the soundcard
390 * supports. So we must re-query the format.
392 rc
=IDirectSoundBuffer_GetFormat(*dsbo
,&wfx
,sizeof(wfx
),NULL
);
393 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetFormat() failed: %s\n",
394 DXGetErrorString8(rc
));
396 (wfx
.wFormatTag
!=wfx2
.wFormatTag
||
397 wfx
.nSamplesPerSec
!=wfx2
.nSamplesPerSec
||
398 wfx
.wBitsPerSample
!=wfx2
.wBitsPerSample
||
399 wfx
.nChannels
!=wfx2
.nChannels
)) {
400 trace("Requested format tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
401 wfx2
.wFormatTag
,wfx2
.nSamplesPerSec
,wfx2
.wBitsPerSample
,
402 wfx2
.nChannels
,wfx2
.nAvgBytesPerSec
,wfx2
.nBlockAlign
);
403 trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n",
404 wfx
.wFormatTag
,wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,
405 wfx
.nChannels
,wfx
.nAvgBytesPerSec
,wfx
.nBlockAlign
);
408 ZeroMemory(&new_dsbcaps
, sizeof(new_dsbcaps
));
409 new_dsbcaps
.dwSize
= sizeof(new_dsbcaps
);
410 rc
=IDirectSoundBuffer_GetCaps(*dsbo
,&new_dsbcaps
);
411 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetCaps() failed: %s\n",
412 DXGetErrorString8(rc
));
413 if (rc
==DS_OK
&& winetest_debug
> 1) {
414 trace(" new Caps: flags=0x%08x size=%d\n",new_dsbcaps
.dwFlags
,
415 new_dsbcaps
.dwBufferBytes
);
418 /* Check for primary buffer size change */
419 ok(new_dsbcaps
.dwBufferBytes
== dsbcaps
.dwBufferBytes
,
420 " buffer size changed after SetFormat() - "
421 "previous size was %u, current size is %u\n",
422 dsbcaps
.dwBufferBytes
, new_dsbcaps
.dwBufferBytes
);
424 /* Check for primary buffer flags change */
425 ok(new_dsbcaps
.dwFlags
== dsbcaps
.dwFlags
,
426 " flags changed after SetFormat() - "
427 "previous flags were %08x, current flags are %08x\n",
428 dsbcaps
.dwFlags
, new_dsbcaps
.dwFlags
);
430 /* Set the CooperativeLevel back to normal */
431 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
432 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
433 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: "
434 "%s\n",DXGetErrorString8(rc
));
439 DS3DLISTENER listener_param
;
440 LPDIRECTSOUND3DBUFFER buffer
=NULL
;
441 DS3DBUFFER buffer_param
;
442 DWORD start_time
,now
;
446 if (winetest_interactive
) {
448 trace(" Playing %g second 440Hz tone at %dx%dx%d with a "
449 "frequency of %d (%dHz)\n", duration
,
450 wfx
.nSamplesPerSec
, wfx
.wBitsPerSample
, wfx
.nChannels
,
451 frequency
, (440 * frequency
) / wfx
.nSamplesPerSec
);
453 trace(" Playing %g second 440Hz tone at %dx%dx%d\n", duration
,
454 wfx
.nSamplesPerSec
, wfx
.wBitsPerSample
, wfx
.nChannels
);
458 /* We must call SetCooperativeLevel to be allowed to call Lock */
459 /* DSOUND: Setting DirectSound cooperative level to
460 * DSSCL_WRITEPRIMARY */
461 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),
463 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_WRITEPRIMARY) "
464 "failed: %s\n",DXGetErrorString8(rc
));
469 LPDIRECTSOUNDBUFFER temp_buffer
;
471 rc
=IDirectSoundBuffer_QueryInterface(*dsbo
,&IID_IDirectSound3DBuffer
,
473 ok(rc
==DS_OK
,"IDirectSoundBuffer_QueryInterface() failed: %s\n",
474 DXGetErrorString8(rc
));
478 /* check the COM interface */
479 rc
=IDirectSoundBuffer_QueryInterface(*dsbo
, &IID_IDirectSoundBuffer
,
480 (LPVOID
*)&temp_buffer
);
481 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
482 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
483 DXGetErrorString8(rc
));
484 ok(temp_buffer
==*dsbo
,"COM interface broken: %p != %p\n",
486 ref
=IDirectSoundBuffer_Release(temp_buffer
);
487 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
488 "should have 1\n",ref
);
491 rc
=IDirectSound3DBuffer_QueryInterface(*dsbo
,
492 &IID_IDirectSoundBuffer
,
493 (LPVOID
*)&temp_buffer
);
494 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
495 "IDirectSound3DBuffer_QueryInterface() failed: %s\n",
496 DXGetErrorString8(rc
));
497 ok(temp_buffer
==*dsbo
,"COM interface broken: %p != %p\n",
499 ref
=IDirectSoundBuffer_Release(temp_buffer
);
500 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
501 "should have 1\n",ref
);
503 ref
=IDirectSoundBuffer_Release(*dsbo
);
504 ok(ref
==0,"IDirectSoundBuffer_Release() has %d references, "
505 "should have 0\n",ref
);
507 rc
=IDirectSound3DBuffer_QueryInterface(buffer
,
508 &IID_IDirectSoundBuffer
,
510 ok(rc
==DS_OK
&& *dsbo
!=NULL
,"IDirectSound3DBuffer_QueryInterface() "
511 "failed: %s\n",DXGetErrorString8(rc
));
513 /* DSOUND: Error: Invalid buffer */
514 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,0);
515 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound3DBuffer_GetAllParameters() "
516 "failed: %s\n",DXGetErrorString8(rc
));
518 ZeroMemory(&buffer_param
, sizeof(buffer_param
));
520 /* DSOUND: Error: Invalid buffer */
521 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,&buffer_param
);
522 ok(rc
==DSERR_INVALIDPARAM
,"IDirectSound3DBuffer_GetAllParameters() "
523 "failed: %s\n",DXGetErrorString8(rc
));
525 buffer_param
.dwSize
=sizeof(buffer_param
);
526 rc
=IDirectSound3DBuffer_GetAllParameters(buffer
,&buffer_param
);
527 ok(rc
==DS_OK
,"IDirectSound3DBuffer_GetAllParameters() failed: %s\n",
528 DXGetErrorString8(rc
));
531 if (dsbcaps
.dwFlags
& DSBCAPS_CTRLVOLUME
) {
533 rc
=IDirectSoundBuffer_GetVolume(*dsbo
,&val
);
534 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume() failed: %s\n",
535 DXGetErrorString8(rc
));
537 rc
=IDirectSoundBuffer_SetVolume(*dsbo
,volume
);
538 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume() failed: %s\n",
539 DXGetErrorString8(rc
));
541 /* DSOUND: Error: Buffer does not have CTRLVOLUME */
542 rc
=IDirectSoundBuffer_GetVolume(*dsbo
,&volume
);
543 ok(rc
==DSERR_CONTROLUNAVAIL
,"IDirectSoundBuffer_GetVolume() "
544 "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
545 DXGetErrorString8(rc
));
550 if (dsbcaps
.dwFlags
& DSBCAPS_CTRLPAN
) {
552 rc
=IDirectSoundBuffer_GetPan(*dsbo
,&val
);
553 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan() failed: %s\n",
554 DXGetErrorString8(rc
));
556 rc
=IDirectSoundBuffer_SetPan(*dsbo
,pan
);
557 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan() failed: %s\n",
558 DXGetErrorString8(rc
));
560 /* DSOUND: Error: Buffer does not have CTRLPAN */
561 rc
=IDirectSoundBuffer_GetPan(*dsbo
,&pan
);
562 ok(rc
==DSERR_CONTROLUNAVAIL
,"IDirectSoundBuffer_GetPan() "
563 "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
564 DXGetErrorString8(rc
));
568 /* try an offset past the end of the buffer */
569 rc
= IDirectSoundBuffer_Lock(*dsbo
, dsbcaps
.dwBufferBytes
, 0, &buffer1
,
570 &length1
, NULL
, NULL
,
571 DSBLOCK_ENTIREBUFFER
);
572 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSoundBuffer_Lock() should have "
573 "returned DSERR_INVALIDPARAM, returned %s\n", DXGetErrorString8(rc
));
575 /* try a size larger than the buffer */
576 rc
= IDirectSoundBuffer_Lock(*dsbo
, 0, dsbcaps
.dwBufferBytes
+ 1,
577 &buffer1
, &length1
, NULL
, NULL
,
578 DSBLOCK_FROMWRITECURSOR
);
579 ok(rc
==DSERR_INVALIDPARAM
, "IDirectSoundBuffer_Lock() should have "
580 "returned DSERR_INVALIDPARAM, returned %s\n", DXGetErrorString8(rc
));
583 state
.wave
=wave_generate_la(&wfx
,(duration
*frequency
)/wfx
.nSamplesPerSec
,&state
.wave_len
);
585 state
.wave
=wave_generate_la(&wfx
,duration
,&state
.wave_len
);
589 state
.buffer_size
=dsbcaps
.dwBufferBytes
;
590 state
.played
=state
.written
=state
.offset
=0;
591 buffer_refill(&state
,state
.buffer_size
);
593 rc
=IDirectSoundBuffer_Play(*dsbo
,0,0,DSBPLAY_LOOPING
);
594 ok(rc
==DS_OK
,"IDirectSoundBuffer_Play() failed: %s\n",
595 DXGetErrorString8(rc
));
597 rc
=IDirectSoundBuffer_GetStatus(*dsbo
,&status
);
598 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetStatus() failed: %s\n",
599 DXGetErrorString8(rc
));
600 ok(status
==(DSBSTATUS_PLAYING
|DSBSTATUS_LOOPING
),
601 "GetStatus: bad status: %x\n",status
);
604 ZeroMemory(&listener_param
,sizeof(listener_param
));
605 listener_param
.dwSize
=sizeof(listener_param
);
606 rc
=IDirectSound3DListener_GetAllParameters(listener
,
608 ok(rc
==DS_OK
,"IDirectSound3dListener_GetAllParameters() "
609 "failed: %s\n",DXGetErrorString8(rc
));
611 listener_param
.vPosition
.x
= -5.0f
;
612 listener_param
.vVelocity
.x
= (float)(10.0/duration
);
614 rc
=IDirectSound3DListener_SetAllParameters(listener
,
617 ok(rc
==DS_OK
,"IDirectSound3dListener_SetPosition() failed: %s\n",
618 DXGetErrorString8(rc
));
622 buffer_param
.vPosition
.x
= 100.0f
;
623 buffer_param
.vVelocity
.x
= (float)(-200.0/duration
);
625 buffer_param
.flMinDistance
= 10;
626 rc
=IDirectSound3DBuffer_SetAllParameters(buffer
,&buffer_param
,
628 ok(rc
==DS_OK
,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
629 DXGetErrorString8(rc
));
632 start_time
=GetTickCount();
633 while (buffer_service(&state
)) {
634 WaitForSingleObject(GetCurrentProcess(),TIME_SLICE
);
636 if (listener
&& move_listener
) {
637 listener_param
.vPosition
.x
= (float)(-5.0+10.0*(now
-start_time
)/1000/duration
);
638 if (winetest_debug
>2)
639 trace("listener position=%g\n",listener_param
.vPosition
.x
);
640 rc
=IDirectSound3DListener_SetPosition(listener
,
641 listener_param
.vPosition
.x
,listener_param
.vPosition
.y
,
642 listener_param
.vPosition
.z
,DS3D_IMMEDIATE
);
643 ok(rc
==DS_OK
,"IDirectSound3dListener_SetPosition() failed: "
644 "%s\n",DXGetErrorString8(rc
));
646 if (buffer3d
&& move_sound
) {
647 buffer_param
.vPosition
.x
= (float)(100-200.0*(now
-start_time
)/1000/duration
);
648 if (winetest_debug
>2)
649 trace("sound position=%g\n",buffer_param
.vPosition
.x
);
650 rc
=IDirectSound3DBuffer_SetPosition(buffer
,
651 buffer_param
.vPosition
.x
,buffer_param
.vPosition
.y
,
652 buffer_param
.vPosition
.z
,DS3D_IMMEDIATE
);
653 ok(rc
==DS_OK
,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
654 DXGetErrorString8(rc
));
657 /* Check the sound duration was within 10% of the expected value */
659 ok(fabs(1000*duration
-now
+start_time
)<=100*duration
,
660 "The sound played for %d ms instead of %g ms\n",
661 now
-start_time
,1000*duration
);
665 /* Set the CooperativeLevel back to normal */
666 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
667 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
668 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) "
669 "failed: %s\n",DXGetErrorString8(rc
));
672 ref
=IDirectSound3DBuffer_Release(buffer
);
673 ok(ref
==0,"IDirectSound3DBuffer_Release() has %d references, "
674 "should have 0\n",ref
);
679 static HRESULT
test_secondary(LPGUID lpGuid
, int play
,
680 int has_3d
, int has_3dbuffer
,
681 int has_listener
, int has_duplicate
,
682 int move_listener
, int move_sound
)
685 LPDIRECTSOUND dso
=NULL
;
686 LPDIRECTSOUNDBUFFER primary
=NULL
,secondary
=NULL
;
687 LPDIRECTSOUND3DLISTENER listener
=NULL
;
688 DSBUFFERDESC bufdesc
;
689 WAVEFORMATEX wfx
, wfx1
;
692 /* Create the DirectSound object */
693 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
694 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
695 DXGetErrorString8(rc
));
699 /* We must call SetCooperativeLevel before creating primary buffer */
700 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
701 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
702 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
703 "%s\n",DXGetErrorString8(rc
));
707 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
708 bufdesc
.dwSize
=sizeof(bufdesc
);
709 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
711 bufdesc
.dwFlags
|=DSBCAPS_CTRL3D
;
713 bufdesc
.dwFlags
|=(DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
);
714 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
715 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
716 "IDirectSound_CreateSoundBuffer() failed to create a %sprimary buffer: "
717 "%s\n",has_3d
?"3D ":"", DXGetErrorString8(rc
));
718 if (rc
==DSERR_CONTROLUNAVAIL
)
719 trace(" No Primary\n");
720 else if (rc
==DS_OK
&& primary
!=NULL
) {
721 rc
=IDirectSoundBuffer_GetFormat(primary
,&wfx1
,sizeof(wfx1
),NULL
);
722 ok(rc
==DS_OK
,"IDirectSoundBuffer8_Getformat() failed: %s\n",
723 DXGetErrorString8(rc
));
728 rc
=IDirectSoundBuffer_QueryInterface(primary
,
729 &IID_IDirectSound3DListener
,
731 ok(rc
==DS_OK
&& listener
!=NULL
,
732 "IDirectSoundBuffer_QueryInterface() failed to get a 3D "
733 "listener: %s\n",DXGetErrorString8(rc
));
734 ref
=IDirectSoundBuffer_Release(primary
);
735 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
736 "should have 0\n",ref
);
737 if (rc
==DS_OK
&& listener
!=NULL
) {
738 DS3DLISTENER listener_param
;
739 ZeroMemory(&listener_param
,sizeof(listener_param
));
740 /* DSOUND: Error: Invalid buffer */
741 rc
=IDirectSound3DListener_GetAllParameters(listener
,0);
742 ok(rc
==DSERR_INVALIDPARAM
,
743 "IDirectSound3dListener_GetAllParameters() should have "
744 "returned DSERR_INVALIDPARAM, returned: %s\n",
745 DXGetErrorString8(rc
));
747 /* DSOUND: Error: Invalid buffer */
748 rc
=IDirectSound3DListener_GetAllParameters(listener
,
750 ok(rc
==DSERR_INVALIDPARAM
,
751 "IDirectSound3dListener_GetAllParameters() should have "
752 "returned DSERR_INVALIDPARAM, returned: %s\n",
753 DXGetErrorString8(rc
));
755 listener_param
.dwSize
=sizeof(listener_param
);
756 rc
=IDirectSound3DListener_GetAllParameters(listener
,
758 ok(rc
==DS_OK
,"IDirectSound3dListener_GetAllParameters() "
759 "failed: %s\n",DXGetErrorString8(rc
));
761 ok(listener
==NULL
, "IDirectSoundBuffer_QueryInterface() "
762 "failed but returned a listener anyway\n");
763 ok(rc
!=DS_OK
, "IDirectSoundBuffer_QueryInterface() succeeded "
764 "but returned a NULL listener\n");
766 ref
=IDirectSound3DListener_Release(listener
);
767 ok(ref
==0,"IDirectSound3dListener_Release() listener has "
768 "%d references, should have 0\n",ref
);
774 init_format(&wfx
,WAVE_FORMAT_PCM
,22050,16,2);
776 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
777 bufdesc
.dwSize
=sizeof(bufdesc
);
778 bufdesc
.dwFlags
=DSBCAPS_GETCURRENTPOSITION2
;
780 bufdesc
.dwFlags
|=DSBCAPS_CTRL3D
;
783 (DSBCAPS_CTRLFREQUENCY
|DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
);
784 bufdesc
.dwBufferBytes
=align(wfx
.nAvgBytesPerSec
*BUFFER_LEN
/1000,
786 bufdesc
.lpwfxFormat
=&wfx
;
787 if (winetest_interactive
) {
788 trace(" Testing a %s%ssecondary buffer %s%s%s%sat %dx%dx%d "
789 "with a primary buffer at %dx%dx%d\n",
790 has_3dbuffer
?"3D ":"",
791 has_duplicate
?"duplicated ":"",
792 listener
!=NULL
||move_sound
?"with ":"",
793 move_listener
?"moving ":"",
794 listener
!=NULL
?"listener ":"",
795 listener
&&move_sound
?"and moving sound ":move_sound
?
797 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
798 wfx1
.nSamplesPerSec
,wfx1
.wBitsPerSample
,wfx1
.nChannels
);
800 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&secondary
,NULL
);
801 ok(rc
==DS_OK
&& secondary
!=NULL
,"IDirectSound_CreateSoundBuffer() "
802 "failed to create a %s%ssecondary buffer %s%s%s%sat %dx%dx%d (%s): %s\n",
803 has_3dbuffer
?"3D ":"", has_duplicate
?"duplicated ":"",
804 listener
!=NULL
||move_sound
?"with ":"", move_listener
?"moving ":"",
805 listener
!=NULL
?"listener ":"",
806 listener
&&move_sound
?"and moving sound ":move_sound
?
808 wfx
.nSamplesPerSec
,wfx
.wBitsPerSample
,wfx
.nChannels
,
809 getDSBCAPS(bufdesc
.dwFlags
),DXGetErrorString8(rc
));
810 if (rc
==DS_OK
&& secondary
!=NULL
) {
812 LONG refvol
,vol
,refpan
,pan
;
814 /* Check the initial secondary buffer's volume and pan */
815 rc
=IDirectSoundBuffer_GetVolume(secondary
,&vol
);
816 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(secondary) failed: "
817 "%s\n",DXGetErrorString8(rc
));
818 ok(vol
==0,"wrong volume for a new secondary buffer: %d\n",vol
);
819 rc
=IDirectSoundBuffer_GetPan(secondary
,&pan
);
820 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(secondary) failed: "
821 "%s\n",DXGetErrorString8(rc
));
822 ok(pan
==0,"wrong pan for a new secondary buffer: %d\n",pan
);
824 /* Check that changing the secondary buffer's volume and pan
825 * does not impact the primary buffer's volume and pan
827 rc
=IDirectSoundBuffer_GetVolume(primary
,&refvol
);
828 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(primary) failed: "
829 "%s\n",DXGetErrorString8(rc
));
830 rc
=IDirectSoundBuffer_GetPan(primary
,&refpan
);
831 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
832 DXGetErrorString8(rc
));
834 rc
=IDirectSoundBuffer_SetVolume(secondary
,-1000);
835 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: "
836 "%s\n",DXGetErrorString8(rc
));
837 rc
=IDirectSoundBuffer_GetVolume(secondary
,&vol
);
838 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: "
839 "%s\n",DXGetErrorString8(rc
));
840 ok(vol
==-1000,"secondary: wrong volume %d instead of -1000\n",
842 rc
=IDirectSoundBuffer_SetPan(secondary
,-1000);
843 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: "
844 "%s\n",DXGetErrorString8(rc
));
845 rc
=IDirectSoundBuffer_GetPan(secondary
,&pan
);
846 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: "
847 "%s\n",DXGetErrorString8(rc
));
848 ok(pan
==-1000,"secondary: wrong pan %d instead of -1000\n",
851 rc
=IDirectSoundBuffer_GetVolume(primary
,&vol
);
852 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetVolume(primary) failed: "
853 "%s\n",DXGetErrorString8(rc
));
854 ok(vol
==refvol
,"The primary volume changed from %d to %d\n",
856 rc
=IDirectSoundBuffer_GetPan(primary
,&pan
);
857 ok(rc
==DS_OK
,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
858 DXGetErrorString8(rc
));
859 ok(pan
==refpan
,"The primary pan changed from %d to %d\n",
862 rc
=IDirectSoundBuffer_SetVolume(secondary
,0);
863 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetVolume(secondary) failed: "
864 "%s\n",DXGetErrorString8(rc
));
865 rc
=IDirectSoundBuffer_SetPan(secondary
,0);
866 ok(rc
==DS_OK
,"IDirectSoundBuffer_SetPan(secondary) failed: "
867 "%s\n",DXGetErrorString8(rc
));
870 LPDIRECTSOUNDBUFFER duplicated
=NULL
;
872 /* DSOUND: Error: Invalid source buffer */
873 rc
=IDirectSound_DuplicateSoundBuffer(dso
,0,0);
874 ok(rc
==DSERR_INVALIDPARAM
,
875 "IDirectSound_DuplicateSoundBuffer() should have returned "
876 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
878 /* DSOUND: Error: Invalid dest buffer */
879 rc
=IDirectSound_DuplicateSoundBuffer(dso
,secondary
,0);
880 ok(rc
==DSERR_INVALIDPARAM
,
881 "IDirectSound_DuplicateSoundBuffer() should have returned "
882 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
884 /* DSOUND: Error: Invalid source buffer */
885 rc
=IDirectSound_DuplicateSoundBuffer(dso
,0,&duplicated
);
886 ok(rc
==DSERR_INVALIDPARAM
,
887 "IDirectSound_DuplicateSoundBuffer() should have returned "
888 "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc
));
891 rc
=IDirectSound_DuplicateSoundBuffer(dso
,secondary
,
893 ok(rc
==DS_OK
&& duplicated
!=NULL
,
894 "IDirectSound_DuplicateSoundBuffer() failed to duplicate "
895 "a secondary buffer: %s\n",DXGetErrorString8(rc
));
897 if (rc
==DS_OK
&& duplicated
!=NULL
) {
898 ref
=IDirectSoundBuffer_Release(secondary
);
899 ok(ref
==0,"IDirectSoundBuffer_Release() secondary has %d "
900 "references, should have 0\n",ref
);
901 secondary
=duplicated
;
905 if (rc
==DS_OK
&& secondary
!=NULL
) {
907 duration
=(move_listener
|| move_sound
?4.0:1.0);
908 test_buffer(dso
,&secondary
,0,FALSE
,0,FALSE
,0,
909 winetest_interactive
,duration
,has_3dbuffer
,
910 listener
,move_listener
,move_sound
,FALSE
,0);
911 ref
=IDirectSoundBuffer_Release(secondary
);
912 ok(ref
==0,"IDirectSoundBuffer_Release() %s has %d references, "
913 "should have 0\n",has_duplicate
?"duplicated":"secondary",
919 ref
=IDirectSound3DListener_Release(listener
);
920 ok(ref
==0,"IDirectSound3dListener_Release() listener has %d "
921 "references, should have 0\n",ref
);
923 ref
=IDirectSoundBuffer_Release(primary
);
924 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
925 "should have 0\n",ref
);
928 ok(primary
==NULL
,"IDirectSound_CreateSoundBuffer(primary) failed "
929 "but primary created anyway\n");
930 ok(rc
!=DS_OK
,"IDirectSound_CreateSoundBuffer(primary) succeeded "
931 "but primary not created\n");
933 ref
=IDirectSoundBuffer_Release(primary
);
934 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
935 "should have 0\n",ref
);
939 /* Set the CooperativeLevel back to normal */
940 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
941 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
942 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
943 DXGetErrorString8(rc
));
946 ref
=IDirectSound_Release(dso
);
947 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
949 return DSERR_GENERIC
;
954 static HRESULT
test_for_driver(LPGUID lpGuid
)
957 LPDIRECTSOUND dso
=NULL
;
960 /* Create the DirectSound object */
961 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
962 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
||rc
==DSERR_ALLOCATED
||rc
==E_FAIL
,
963 "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc
));
967 ref
=IDirectSound_Release(dso
);
968 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
970 return DSERR_GENERIC
;
975 static HRESULT
test_primary(LPGUID lpGuid
)
978 LPDIRECTSOUND dso
=NULL
;
979 LPDIRECTSOUNDBUFFER primary
=NULL
;
980 DSBUFFERDESC bufdesc
;
984 /* Create the DirectSound object */
985 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
986 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
987 DXGetErrorString8(rc
));
991 /* Get the device capabilities */
992 ZeroMemory(&dscaps
, sizeof(dscaps
));
993 dscaps
.dwSize
=sizeof(dscaps
);
994 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
995 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
999 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1000 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1001 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1002 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
1003 "%s\n",DXGetErrorString8(rc
));
1007 /* Testing the primary buffer */
1009 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1010 bufdesc
.dwSize
=sizeof(bufdesc
);
1011 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRLVOLUME
|DSBCAPS_CTRLPAN
;
1012 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1013 ok((rc
==DS_OK
&& primary
!=NULL
) || (rc
==DSERR_CONTROLUNAVAIL
),
1014 "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: "
1015 "%s\n",DXGetErrorString8(rc
));
1016 if (rc
==DSERR_CONTROLUNAVAIL
)
1017 trace(" No Primary\n");
1018 else if (rc
==DS_OK
&& primary
!=NULL
) {
1019 test_buffer(dso
,&primary
,1,TRUE
,0,TRUE
,0,winetest_interactive
&&
1020 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,NULL
,0,0,
1022 if (winetest_interactive
) {
1025 volume
= DSBVOLUME_MAX
;
1026 for (i
= 0; i
< 6; i
++) {
1027 test_buffer(dso
,&primary
,1,TRUE
,volume
,TRUE
,0,
1028 winetest_interactive
&&
1029 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),
1030 1.0,0,NULL
,0,0,FALSE
,0);
1031 volume
-= ((DSBVOLUME_MAX
-DSBVOLUME_MIN
) / 40);
1035 for (i
= 0; i
< 7; i
++) {
1036 test_buffer(dso
,&primary
,1,TRUE
,0,TRUE
,pan
,
1037 winetest_interactive
&&
1038 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,0,0,0,FALSE
,0);
1039 pan
+= ((DSBPAN_RIGHT
-DSBPAN_LEFT
) / 6);
1042 ref
=IDirectSoundBuffer_Release(primary
);
1043 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1044 "should have 0\n",ref
);
1047 /* Set the CooperativeLevel back to normal */
1048 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1049 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1050 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
1051 DXGetErrorString8(rc
));
1054 ref
=IDirectSound_Release(dso
);
1055 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1057 return DSERR_GENERIC
;
1062 static HRESULT
test_primary_3d(LPGUID lpGuid
)
1065 LPDIRECTSOUND dso
=NULL
;
1066 LPDIRECTSOUNDBUFFER primary
=NULL
;
1067 DSBUFFERDESC bufdesc
;
1071 /* Create the DirectSound object */
1072 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1073 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
1074 DXGetErrorString8(rc
));
1078 /* Get the device capabilities */
1079 ZeroMemory(&dscaps
, sizeof(dscaps
));
1080 dscaps
.dwSize
=sizeof(dscaps
);
1081 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1082 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
1086 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1087 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1088 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1089 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
1090 "%s\n",DXGetErrorString8(rc
));
1095 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1096 bufdesc
.dwSize
=sizeof(bufdesc
);
1097 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
;
1098 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1099 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1100 "to create a primary buffer: %s\n",DXGetErrorString8(rc
));
1101 if (rc
==DS_OK
&& primary
!=NULL
) {
1102 ref
=IDirectSoundBuffer_Release(primary
);
1103 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1104 "should have 0\n",ref
);
1106 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1107 bufdesc
.dwSize
=sizeof(bufdesc
);
1108 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRL3D
;
1109 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1110 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() "
1111 "failed to create a 3D primary buffer: %s\n",DXGetErrorString8(rc
));
1112 if (rc
==DS_OK
&& primary
!=NULL
) {
1113 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,winetest_interactive
&&
1114 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,0,0,0,
1116 ref
=IDirectSoundBuffer_Release(primary
);
1117 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1118 "should have 0\n",ref
);
1121 /* Set the CooperativeLevel back to normal */
1122 /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
1123 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_NORMAL
);
1124 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
1125 DXGetErrorString8(rc
));
1128 ref
=IDirectSound_Release(dso
);
1129 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1131 return DSERR_GENERIC
;
1136 static HRESULT
test_primary_3d_with_listener(LPGUID lpGuid
)
1139 LPDIRECTSOUND dso
=NULL
;
1140 LPDIRECTSOUNDBUFFER primary
=NULL
;
1141 DSBUFFERDESC bufdesc
;
1145 /* Create the DirectSound object */
1146 rc
=pDirectSoundCreate(lpGuid
,&dso
,NULL
);
1147 ok(rc
==DS_OK
||rc
==DSERR_NODRIVER
,"DirectSoundCreate() failed: %s\n",
1148 DXGetErrorString8(rc
));
1152 /* Get the device capabilities */
1153 ZeroMemory(&dscaps
, sizeof(dscaps
));
1154 dscaps
.dwSize
=sizeof(dscaps
);
1155 rc
=IDirectSound_GetCaps(dso
,&dscaps
);
1156 ok(rc
==DS_OK
,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc
));
1160 /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
1161 /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
1162 rc
=IDirectSound_SetCooperativeLevel(dso
,get_hwnd(),DSSCL_PRIORITY
);
1163 ok(rc
==DS_OK
,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
1164 "%s\n",DXGetErrorString8(rc
));
1168 ZeroMemory(&bufdesc
, sizeof(bufdesc
));
1169 bufdesc
.dwSize
=sizeof(bufdesc
);
1170 bufdesc
.dwFlags
=DSBCAPS_PRIMARYBUFFER
|DSBCAPS_CTRL3D
;
1171 rc
=IDirectSound_CreateSoundBuffer(dso
,&bufdesc
,&primary
,NULL
);
1172 ok(rc
==DS_OK
&& primary
!=NULL
,"IDirectSound_CreateSoundBuffer() failed "
1173 "to create a 3D primary buffer: %s\n",DXGetErrorString8(rc
));
1174 if (rc
==DS_OK
&& primary
!=NULL
) {
1175 LPDIRECTSOUND3DLISTENER listener
=NULL
;
1176 rc
=IDirectSoundBuffer_QueryInterface(primary
,
1177 &IID_IDirectSound3DListener
,(void **)&listener
);
1178 ok(rc
==DS_OK
&& listener
!=NULL
,"IDirectSoundBuffer_QueryInterface() "
1179 "failed to get a 3D listener: %s\n",DXGetErrorString8(rc
));
1180 if (rc
==DS_OK
&& listener
!=NULL
) {
1181 LPDIRECTSOUNDBUFFER temp_buffer
=NULL
;
1183 /* Checking the COM interface */
1184 rc
=IDirectSoundBuffer_QueryInterface(primary
,
1185 &IID_IDirectSoundBuffer
,(LPVOID
*)&temp_buffer
);
1186 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1187 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
1188 DXGetErrorString8(rc
));
1189 ok(temp_buffer
==primary
,
1190 "COM interface broken: %p != %p\n",
1191 temp_buffer
,primary
);
1192 if (rc
==DS_OK
&& temp_buffer
!=NULL
) {
1193 ref
=IDirectSoundBuffer_Release(temp_buffer
);
1194 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
1195 "should have 1\n",ref
);
1198 rc
=IDirectSound3DListener_QueryInterface(listener
,
1199 &IID_IDirectSoundBuffer
,(LPVOID
*)&temp_buffer
);
1200 ok(rc
==DS_OK
&& temp_buffer
!=NULL
,
1201 "IDirectSoundBuffer_QueryInterface() failed: %s\n",
1202 DXGetErrorString8(rc
));
1203 ok(temp_buffer
==primary
,
1204 "COM interface broken: %p != %p\n",
1205 temp_buffer
,primary
);
1206 ref
=IDirectSoundBuffer_Release(temp_buffer
);
1207 ok(ref
==1,"IDirectSoundBuffer_Release() has %d references, "
1208 "should have 1\n",ref
);
1210 /* Testing the buffer */
1211 test_buffer(dso
,&primary
,1,FALSE
,0,FALSE
,0,
1212 winetest_interactive
&&
1213 !(dscaps
.dwFlags
& DSCAPS_EMULDRIVER
),1.0,0,
1214 listener
,0,0,FALSE
,0);
1217 /* Testing the reference counting */
1218 ref
=IDirectSound3DListener_Release(listener
);
1219 ok(ref
==0,"IDirectSound3DListener_Release() listener has %d "
1220 "references, should have 0\n",ref
);
1223 /* Testing the reference counting */
1224 ref
=IDirectSoundBuffer_Release(primary
);
1225 ok(ref
==0,"IDirectSoundBuffer_Release() primary has %d references, "
1226 "should have 0\n",ref
);
1230 ref
=IDirectSound_Release(dso
);
1231 ok(ref
==0,"IDirectSound_Release() has %d references, should have 0\n",ref
);
1233 return DSERR_GENERIC
;
1238 static BOOL WINAPI
dsenum_callback(LPGUID lpGuid
, LPCSTR lpcstrDescription
,
1239 LPCSTR lpcstrModule
, LPVOID lpContext
)
1242 trace("*** Testing %s - %s ***\n",lpcstrDescription
,lpcstrModule
);
1244 rc
= test_for_driver(lpGuid
);
1245 if (rc
== DSERR_NODRIVER
) {
1246 trace(" No Driver\n");
1248 } else if (rc
== DSERR_ALLOCATED
) {
1249 trace(" Already In Use\n");
1251 } else if (rc
== E_FAIL
) {
1252 trace(" No Device\n");
1256 trace(" Testing the primary buffer\n");
1257 test_primary(lpGuid
);
1259 trace(" Testing 3D primary buffer\n");
1260 test_primary_3d(lpGuid
);
1262 trace(" Testing 3D primary buffer with listener\n");
1263 test_primary_3d_with_listener(lpGuid
);
1265 /* Testing secondary buffers */
1266 test_secondary(lpGuid
,winetest_interactive
,0,0,0,0,0,0);
1267 test_secondary(lpGuid
,winetest_interactive
,0,0,0,1,0,0);
1269 /* Testing 3D secondary buffers */
1270 test_secondary(lpGuid
,winetest_interactive
,1,0,0,0,0,0);
1271 test_secondary(lpGuid
,winetest_interactive
,1,1,0,0,0,0);
1272 test_secondary(lpGuid
,winetest_interactive
,1,1,0,1,0,0);
1273 test_secondary(lpGuid
,winetest_interactive
,1,0,1,0,0,0);
1274 test_secondary(lpGuid
,winetest_interactive
,1,0,1,1,0,0);
1275 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,0,0);
1276 test_secondary(lpGuid
,winetest_interactive
,1,1,1,1,0,0);
1277 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,1,0);
1278 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,0,1);
1279 test_secondary(lpGuid
,winetest_interactive
,1,1,1,0,1,1);
1284 static void ds3d_tests(void)
1287 rc
=pDirectSoundEnumerateA(&dsenum_callback
,NULL
);
1288 ok(rc
==DS_OK
,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc
));
1297 hDsound
= LoadLibrary("dsound.dll");
1300 trace("DLL Version: %s\n", get_file_version("dsound.dll"));
1302 pDirectSoundEnumerateA
= (void*)GetProcAddress(hDsound
,
1303 "DirectSoundEnumerateA");
1304 pDirectSoundCreate
= (void*)GetProcAddress(hDsound
,
1305 "DirectSoundCreate");
1309 FreeLibrary(hDsound
);
1312 skip("dsound.dll not found!\n");