ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ds3d.c
Go to the documentation of this file.
00001 /*
00002  * Tests the panning and 3D functions of DirectSound
00003  *
00004  * Part of this test involves playing test tones. But this only makes
00005  * sense if someone is going to carefully listen to it, and would only
00006  * bother everyone else.
00007  * So this is only done if the test is being run in interactive mode.
00008  *
00009  * Copyright (c) 2002-2004 Francois Gouget
00010  *
00011  * This library is free software; you can redistribute it and/or
00012  * modify it under the terms of the GNU Lesser General Public
00013  * License as published by the Free Software Foundation; either
00014  * version 2.1 of the License, or (at your option) any later version.
00015  *
00016  * This library is distributed in the hope that it will be useful,
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  * Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License along with this library; if not, write to the Free Software
00023  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024  */
00025 
00026 #define NONAMELESSSTRUCT
00027 #define NONAMELESSUNION
00028 #include <windows.h>
00029 
00030 #include <math.h>
00031 
00032 #include "wine/test.h"
00033 #include "dsound.h"
00034 #include "dxerr8.h"
00035 
00036 #include "dsound_test.h"
00037 
00038 #define PI 3.14159265358979323846
00039 char* wave_generate_la(WAVEFORMATEX* wfx, double duration, DWORD* size)
00040 {
00041     int i;
00042     int nb_samples;
00043     char* buf;
00044     char* b;
00045 
00046     nb_samples=(int)(duration*wfx->nSamplesPerSec);
00047     *size=nb_samples*wfx->nBlockAlign;
00048     b=buf=malloc(*size);
00049     for (i=0;i<nb_samples;i++) {
00050         double y=sin(440.0*2*PI*i/wfx->nSamplesPerSec);
00051         if (wfx->wBitsPerSample==8) {
00052             unsigned char sample=(unsigned char)((double)127.5*(y+1.0));
00053             *b++=sample;
00054             if (wfx->nChannels==2)
00055                 *b++=sample;
00056         } else {
00057             signed short sample=(signed short)((double)32767.5*y-0.5);
00058             b[0]=sample & 0xff;
00059             b[1]=sample >> 8;
00060             b+=2;
00061             if (wfx->nChannels==2) {
00062                 b[0]=sample & 0xff;
00063                 b[1]=sample >> 8;
00064                 b+=2;
00065             }
00066         }
00067     }
00068     return buf;
00069 }
00070 
00071 const char * getDSBCAPS(DWORD xmask) {
00072     static struct {
00073         DWORD   mask;
00074         const char    *name;
00075     } flags[] = {
00076 #define FE(x) { x, #x },
00077         FE(DSBCAPS_PRIMARYBUFFER)
00078         FE(DSBCAPS_STATIC)
00079         FE(DSBCAPS_LOCHARDWARE)
00080         FE(DSBCAPS_LOCSOFTWARE)
00081         FE(DSBCAPS_CTRL3D)
00082         FE(DSBCAPS_CTRLFREQUENCY)
00083         FE(DSBCAPS_CTRLPAN)
00084         FE(DSBCAPS_CTRLVOLUME)
00085         FE(DSBCAPS_CTRLPOSITIONNOTIFY)
00086         FE(DSBCAPS_STICKYFOCUS)
00087         FE(DSBCAPS_GLOBALFOCUS)
00088         FE(DSBCAPS_GETCURRENTPOSITION2)
00089         FE(DSBCAPS_MUTE3DATMAXDISTANCE)
00090 #undef FE
00091     };
00092     static char buffer[512];
00093     unsigned int i;
00094     BOOL first = TRUE;
00095 
00096     buffer[0] = 0;
00097 
00098     for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++) {
00099         if ((flags[i].mask & xmask) == flags[i].mask) {
00100             if (first)
00101                 first = FALSE;
00102             else
00103                 strcat(buffer, "|");
00104             strcat(buffer, flags[i].name);
00105         }
00106     }
00107 
00108     return buffer;
00109 }
00110 
00111 HWND get_hwnd()
00112 {
00113     HWND hwnd=GetForegroundWindow();
00114     if (!hwnd)
00115         hwnd=GetDesktopWindow();
00116     return hwnd;
00117 }
00118 
00119 void init_format(WAVEFORMATEX* wfx, int format, int rate, int depth,
00120                  int channels)
00121 {
00122     wfx->wFormatTag=format;
00123     wfx->nChannels=channels;
00124     wfx->wBitsPerSample=depth;
00125     wfx->nSamplesPerSec=rate;
00126     wfx->nBlockAlign=wfx->nChannels*wfx->wBitsPerSample/8;
00127     /* FIXME: Shouldn't this test be if (format!=WAVE_FORMAT_PCM) */
00128     if (wfx->nBlockAlign==0)
00129     {
00130         /* align compressed formats to byte boundary */
00131         wfx->nBlockAlign=1;
00132     }
00133     wfx->nAvgBytesPerSec=wfx->nSamplesPerSec*wfx->nBlockAlign;
00134     wfx->cbSize=0;
00135 }
00136 
00137 typedef struct {
00138     char* wave;
00139     DWORD wave_len;
00140 
00141     LPDIRECTSOUNDBUFFER dsbo;
00142     LPWAVEFORMATEX wfx;
00143     DWORD buffer_size;
00144     DWORD written;
00145     DWORD played;
00146     DWORD offset;
00147 } play_state_t;
00148 
00149 static int buffer_refill(play_state_t* state, DWORD size)
00150 {
00151     LPVOID ptr1,ptr2;
00152     DWORD len1,len2;
00153     HRESULT rc;
00154 
00155     if (size>state->wave_len-state->written)
00156         size=state->wave_len-state->written;
00157 
00158     rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size,
00159                                &ptr1,&len1,&ptr2,&len2,0);
00160     ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n",
00161        DXGetErrorString8(rc));
00162     if (rc!=DS_OK)
00163         return -1;
00164 
00165     memcpy(ptr1,state->wave+state->written,len1);
00166     state->written+=len1;
00167     if (ptr2!=NULL) {
00168         memcpy(ptr2,state->wave+state->written,len2);
00169         state->written+=len2;
00170     }
00171     state->offset=state->written % state->buffer_size;
00172     rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2);
00173     ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n",
00174        DXGetErrorString8(rc));
00175     if (rc!=DS_OK)
00176         return -1;
00177     return size;
00178 }
00179 
00180 static int buffer_silence(play_state_t* state, DWORD size)
00181 {
00182     LPVOID ptr1,ptr2;
00183     DWORD len1,len2;
00184     HRESULT rc;
00185     BYTE s;
00186 
00187     rc=IDirectSoundBuffer_Lock(state->dsbo,state->offset,size,
00188                                &ptr1,&len1,&ptr2,&len2,0);
00189     ok(rc==DS_OK,"IDirectSoundBuffer_Lock() failed: %s\n",
00190        DXGetErrorString8(rc));
00191     if (rc!=DS_OK)
00192         return -1;
00193 
00194     s=(state->wfx->wBitsPerSample==8?0x80:0);
00195     memset(ptr1,s,len1);
00196     if (ptr2!=NULL) {
00197         memset(ptr2,s,len2);
00198     }
00199     state->offset=(state->offset+size) % state->buffer_size;
00200     rc=IDirectSoundBuffer_Unlock(state->dsbo,ptr1,len1,ptr2,len2);
00201     ok(rc==DS_OK,"IDirectSoundBuffer_Unlock() failed: %s\n",
00202        DXGetErrorString8(rc));
00203     if (rc!=DS_OK)
00204         return -1;
00205     return size;
00206 }
00207 
00208 static int buffer_service(play_state_t* state)
00209 {
00210     DWORD last_play_pos,play_pos,buf_free;
00211     HRESULT rc;
00212 
00213     rc=IDirectSoundBuffer_GetCurrentPosition(state->dsbo,&play_pos,NULL);
00214     ok(rc==DS_OK,"IDirectSoundBuffer_GetCurrentPosition() failed: %s\n",
00215        DXGetErrorString8(rc));
00216     if (rc!=DS_OK) {
00217         goto STOP;
00218     }
00219 
00220     /* Update the amount played */
00221     last_play_pos=state->played % state->buffer_size;
00222     if (play_pos<last_play_pos)
00223         state->played+=state->buffer_size-last_play_pos+play_pos;
00224     else
00225         state->played+=play_pos-last_play_pos;
00226 
00227     if (winetest_debug > 1)
00228         trace("buf size=%ld last_play_pos=%ld play_pos=%ld played=%ld / %ld\n",
00229               state->buffer_size,last_play_pos,play_pos,state->played,
00230               state->wave_len);
00231 
00232     if (state->played>state->wave_len)
00233     {
00234         /* Everything has been played */
00235         goto STOP;
00236     }
00237 
00238     /* Refill the buffer */
00239     if (state->offset<=play_pos)
00240         buf_free=play_pos-state->offset;
00241     else
00242         buf_free=state->buffer_size-state->offset+play_pos;
00243 
00244     if (winetest_debug > 1)
00245         trace("offset=%ld free=%ld written=%ld / %ld\n",
00246               state->offset,buf_free,state->written,state->wave_len);
00247     if (buf_free==0)
00248         return 1;
00249 
00250     if (state->written<state->wave_len)
00251     {
00252         int w=buffer_refill(state,buf_free);
00253         if (w==-1)
00254             goto STOP;
00255         buf_free-=w;
00256         if (state->written==state->wave_len && winetest_debug > 1)
00257             trace("last sound byte at %ld\n",
00258                   (state->written % state->buffer_size));
00259     }
00260 
00261     if (buf_free>0) {
00262         /* Fill with silence */
00263         if (winetest_debug > 1)
00264             trace("writing %ld bytes of silence\n",buf_free);
00265         if (buffer_silence(state,buf_free)==-1)
00266             goto STOP;
00267     }
00268     return 1;
00269 
00270 STOP:
00271     if (winetest_debug > 1)
00272         trace("stopping playback\n");
00273     rc=IDirectSoundBuffer_Stop(state->dsbo);
00274     ok(rc==DS_OK,"IDirectSoundBuffer_Stop() failed: %s\n",
00275        DXGetErrorString8(rc));
00276     return 0;
00277 }
00278 
00279 void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
00280                  BOOL is_primary, BOOL set_volume, LONG volume,
00281                  BOOL set_pan, LONG pan, BOOL play, double duration,
00282                  BOOL buffer3d, LPDIRECTSOUND3DLISTENER listener,
00283                  BOOL move_listener, BOOL move_sound,
00284                  BOOL set_frequency, DWORD frequency)
00285 {
00286     HRESULT rc;
00287     DSBCAPS dsbcaps;
00288     WAVEFORMATEX wfx,wfx2;
00289     DWORD size,status,freq;
00290     int ref;
00291 
00292     if (set_frequency) {
00293         rc=IDirectSoundBuffer_SetFrequency(dsbo,frequency);
00294         ok(rc==DS_OK||rc==DSERR_CONTROLUNAVAIL,
00295            "IDirectSoundBuffer_SetFrequency() failed to set frequency "
00296            "%s\n",DXGetErrorString8(rc));
00297         if (rc!=DS_OK)
00298             return;
00299     }
00300 
00301     /* DSOUND: Error: Invalid caps pointer */
00302     rc=IDirectSoundBuffer_GetCaps(dsbo,0);
00303     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have "
00304        "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
00305 
00306     ZeroMemory(&dsbcaps, sizeof(dsbcaps));
00307 
00308     /* DSOUND: Error: Invalid caps pointer */
00309     rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps);
00310     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetCaps() should have "
00311        "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
00312 
00313     dsbcaps.dwSize=sizeof(dsbcaps);
00314     rc=IDirectSoundBuffer_GetCaps(dsbo,&dsbcaps);
00315     ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() failed: %s\n",
00316        DXGetErrorString8(rc));
00317     if (rc==DS_OK && winetest_debug > 1) {
00318         trace("    Caps: flags=0x%08lx size=%ld\n",dsbcaps.dwFlags,
00319               dsbcaps.dwBufferBytes);
00320     }
00321 
00322     /* Query the format size. Note that it may not match sizeof(wfx) */
00323     size=0;
00324     rc=IDirectSoundBuffer_GetFormat(dsbo,NULL,0,&size);
00325     ok(rc==DS_OK && size!=0,"IDirectSoundBuffer_GetFormat() should have "
00326        "returned the needed size: rc=%s size=%ld\n",DXGetErrorString8(rc),size);
00327 
00328     rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL);
00329     ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
00330        DXGetErrorString8(rc));
00331     if (rc==DS_OK && winetest_debug > 1) {
00332         trace("    Format: %s tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
00333               is_primary ? "Primary" : "Secondary",
00334               wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
00335               wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
00336     }
00337 
00338     /* DSOUND: Error: Invalid frequency buffer */
00339     rc=IDirectSoundBuffer_GetFrequency(dsbo,0);
00340     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetFrequency() should have "
00341        "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
00342 
00343     /* DSOUND: Error: Primary buffers don't support CTRLFREQUENCY */
00344     rc=IDirectSoundBuffer_GetFrequency(dsbo,&freq);
00345     ok((rc==DS_OK && !is_primary) || (rc==DSERR_CONTROLUNAVAIL&&is_primary) ||
00346        (rc==DSERR_CONTROLUNAVAIL&&!(dsbcaps.dwFlags&DSBCAPS_CTRLFREQUENCY)),
00347        "IDirectSoundBuffer_GetFrequency() failed: %s\n",DXGetErrorString8(rc));
00348     if (rc==DS_OK) {
00349         DWORD f = set_frequency?frequency:wfx.nSamplesPerSec;
00350         ok(freq==f,"The frequency returned by GetFrequency "
00351            "%ld does not match the format %ld\n",freq,f);
00352     }
00353 
00354     /* DSOUND: Error: Invalid status pointer */
00355     rc=IDirectSoundBuffer_GetStatus(dsbo,0);
00356     ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_GetStatus() should have "
00357        "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
00358 
00359     rc=IDirectSoundBuffer_GetStatus(dsbo,&status);
00360     ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %s\n",
00361        DXGetErrorString8(rc));
00362     ok(status==0,"status=0x%lx instead of 0\n",status);
00363 
00364     if (is_primary) {
00365         /* We must call SetCooperativeLevel to be allowed to call SetFormat */
00366         /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
00367         rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
00368         ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
00369            "%s\n",DXGetErrorString8(rc));
00370         if (rc!=DS_OK)
00371             return;
00372 
00373         /* DSOUND: Error: Invalid format pointer */
00374         rc=IDirectSoundBuffer_SetFormat(dsbo,0);
00375         ok(rc==DSERR_INVALIDPARAM,"IDirectSoundBuffer_SetFormat() should have "
00376            "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
00377 
00378         init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2);
00379         rc=IDirectSoundBuffer_SetFormat(dsbo,&wfx2);
00380         ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat() failed: %s\n",
00381            DXGetErrorString8(rc));
00382 
00383         /* There is no garantee that SetFormat will actually change the
00384      * format to what we asked for. It depends on what the soundcard
00385      * supports. So we must re-query the format.
00386      */
00387         rc=IDirectSoundBuffer_GetFormat(dsbo,&wfx,sizeof(wfx),NULL);
00388         ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %s\n",
00389            DXGetErrorString8(rc));
00390         if (rc==DS_OK &&
00391             (wfx.wFormatTag!=wfx2.wFormatTag ||
00392              wfx.nSamplesPerSec!=wfx2.nSamplesPerSec ||
00393              wfx.wBitsPerSample!=wfx2.wBitsPerSample ||
00394              wfx.nChannels!=wfx2.nChannels)) {
00395             trace("Requested format tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
00396                   wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample,
00397                   wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign);
00398             trace("Got tag=0x%04x %ldx%dx%d avg.B/s=%ld align=%d\n",
00399                   wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample,
00400                   wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign);
00401         }
00402 
00403         /* Set the CooperativeLevel back to normal */
00404         /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
00405         rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
00406         ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: "
00407            "%s\n",DXGetErrorString8(rc));
00408     }
00409 
00410     if (play) {
00411         play_state_t state;
00412         DS3DLISTENER listener_param;
00413         LPDIRECTSOUND3DBUFFER buffer=NULL;
00414         DS3DBUFFER buffer_param;
00415         DWORD start_time,now;
00416 
00417         if (winetest_interactive) {
00418             if (set_frequency)
00419                 trace("    Playing %g second 440Hz tone at %ldx%dx%d with a "
00420                       "frequency of %ld (%ldHz)\n", duration,
00421                       wfx.nSamplesPerSec, wfx.wBitsPerSample, wfx.nChannels,
00422                       frequency, (440 * frequency) / wfx.nSamplesPerSec);
00423             else
00424                 trace("    Playing %g second 440Hz tone at %ldx%dx%d\n", duration,
00425                       wfx.nSamplesPerSec, wfx.wBitsPerSample, wfx.nChannels);
00426         }
00427 
00428         if (is_primary) {
00429             /* We must call SetCooperativeLevel to be allowed to call Lock */
00430             /* DSOUND: Setting DirectSound cooperative level to
00431              * DSSCL_WRITEPRIMARY */
00432             rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),
00433                                                 DSSCL_WRITEPRIMARY);
00434             ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_WRITEPRIMARY) "
00435                "failed: %s\n",DXGetErrorString8(rc));
00436             if (rc!=DS_OK)
00437                 return;
00438         }
00439         if (buffer3d) {
00440             LPDIRECTSOUNDBUFFER temp_buffer;
00441 
00442             rc=IDirectSoundBuffer_QueryInterface(dsbo,&IID_IDirectSound3DBuffer,
00443                                                  (LPVOID *)&buffer);
00444             ok(rc==DS_OK,"IDirectSoundBuffer_QueryInterface() failed: %s\n",
00445                DXGetErrorString8(rc));
00446             if (rc!=DS_OK)
00447                 return;
00448 
00449             /* check the COM interface */
00450             rc=IDirectSoundBuffer_QueryInterface(dsbo, &IID_IDirectSoundBuffer,
00451                                                  (LPVOID *)&temp_buffer);
00452             ok(rc==DS_OK && temp_buffer!=NULL,
00453                "IDirectSoundBuffer_QueryInterface() failed: %s\n",
00454                DXGetErrorString8(rc));
00455             ok(temp_buffer==dsbo,"COM interface broken: %p != %p\n",
00456                temp_buffer,dsbo);
00457             ref=IDirectSoundBuffer_Release(temp_buffer);
00458             ok(ref==1,"IDirectSoundBuffer_Release() has %d references, "
00459                "should have 1\n",ref);
00460 
00461             temp_buffer=NULL;
00462             rc=IDirectSound3DBuffer_QueryInterface(dsbo,
00463                                                    &IID_IDirectSoundBuffer,
00464                                                    (LPVOID *)&temp_buffer);
00465             ok(rc==DS_OK && temp_buffer!=NULL,
00466                "IDirectSound3DBuffer_QueryInterface() failed: %s\n",
00467                DXGetErrorString8(rc));
00468             ok(temp_buffer==dsbo,"COM interface broken: %p != %p\n",
00469                temp_buffer,dsbo);
00470             ref=IDirectSoundBuffer_Release(temp_buffer);
00471             ok(ref==1,"IDirectSoundBuffer_Release() has %d references, "
00472                "should have 1\n",ref);
00473 
00474 #if 0
00475             /* FIXME: this works on windows */
00476             ref=IDirectSoundBuffer_Release(dsbo);
00477             ok(ref==0,"IDirectSoundBuffer_Release() has %d references, "
00478                "should have 0\n",ref);
00479 
00480             rc=IDirectSound3DBuffer_QueryInterface(buffer,
00481                                                    &IID_IDirectSoundBuffer,
00482                                                    (LPVOID *)&dsbo);
00483             ok(rc==DS_OK && dsbo!=NULL,"IDirectSound3DBuffer_QueryInterface() "
00484                "failed: %s\n",DXGetErrorString8(rc));
00485 #endif
00486 
00487             /* DSOUND: Error: Invalid buffer */
00488             rc=IDirectSound3DBuffer_GetAllParameters(buffer,0);
00489             ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() "
00490                "failed: %s\n",DXGetErrorString8(rc));
00491 
00492             ZeroMemory(&buffer_param, sizeof(buffer_param));
00493 
00494             /* DSOUND: Error: Invalid buffer */
00495             rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param);
00496             ok(rc==DSERR_INVALIDPARAM,"IDirectSound3DBuffer_GetAllParameters() "
00497                "failed: %s\n",DXGetErrorString8(rc));
00498 
00499             buffer_param.dwSize=sizeof(buffer_param);
00500             rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param);
00501             ok(rc==DS_OK,"IDirectSound3DBuffer_GetAllParameters() failed: %s\n",
00502                DXGetErrorString8(rc));
00503         }
00504         if (set_volume) {
00505             if (dsbcaps.dwFlags & DSBCAPS_CTRLVOLUME) {
00506                 LONG val;
00507                 rc=IDirectSoundBuffer_GetVolume(dsbo,&val);
00508                 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %s\n",
00509                    DXGetErrorString8(rc));
00510 
00511                 rc=IDirectSoundBuffer_SetVolume(dsbo,volume);
00512                 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume() failed: %s\n",
00513                    DXGetErrorString8(rc));
00514             } else {
00515                 /* DSOUND: Error: Buffer does not have CTRLVOLUME */
00516                 rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
00517                 ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetVolume() "
00518                    "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
00519                    DXGetErrorString8(rc));
00520             }
00521         }
00522 
00523         if (set_pan) {
00524             if (dsbcaps.dwFlags & DSBCAPS_CTRLPAN) {
00525                 LONG val;
00526                 rc=IDirectSoundBuffer_GetPan(dsbo,&val);
00527                 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan() failed: %s\n",
00528                    DXGetErrorString8(rc));
00529 
00530                 rc=IDirectSoundBuffer_SetPan(dsbo,pan);
00531                 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan() failed: %s\n",
00532                    DXGetErrorString8(rc));
00533             } else {
00534                 /* DSOUND: Error: Buffer does not have CTRLPAN */
00535                 rc=IDirectSoundBuffer_GetPan(dsbo,&pan);
00536                 ok(rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer_GetPan() "
00537                    "should have returned DSERR_CONTROLUNAVAIL, returned: %s\n",
00538                    DXGetErrorString8(rc));
00539             }
00540         }
00541 
00542         if (set_frequency)
00543             state.wave=wave_generate_la(&wfx,(duration*frequency)/wfx.nSamplesPerSec,&state.wave_len);
00544         else
00545             state.wave=wave_generate_la(&wfx,duration,&state.wave_len);
00546 
00547         state.dsbo=dsbo;
00548         state.wfx=&wfx;
00549         state.buffer_size=dsbcaps.dwBufferBytes;
00550         state.played=state.written=state.offset=0;
00551         buffer_refill(&state,state.buffer_size);
00552 
00553         rc=IDirectSoundBuffer_Play(dsbo,0,0,DSBPLAY_LOOPING);
00554         ok(rc==DS_OK,"IDirectSoundBuffer_Play() failed: %s\n",
00555            DXGetErrorString8(rc));
00556 
00557         rc=IDirectSoundBuffer_GetStatus(dsbo,&status);
00558         ok(rc==DS_OK,"IDirectSoundBuffer_GetStatus() failed: %s\n",
00559            DXGetErrorString8(rc));
00560         ok(status==(DSBSTATUS_PLAYING|DSBSTATUS_LOOPING),
00561            "GetStatus: bad status: %lx\n",status);
00562 
00563         if (listener) {
00564             ZeroMemory(&listener_param,sizeof(listener_param));
00565             listener_param.dwSize=sizeof(listener_param);
00566             rc=IDirectSound3DListener_GetAllParameters(listener,
00567                                                        &listener_param);
00568             ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters() "
00569                "failed: %s\n",DXGetErrorString8(rc));
00570             if (move_listener) {
00571                 listener_param.vPosition.x = -5.0;
00572                 listener_param.vVelocity.x = 10.0/duration;
00573             }
00574             rc=IDirectSound3DListener_SetAllParameters(listener,
00575                                                        &listener_param,
00576                                                        DS3D_IMMEDIATE);
00577             ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: %s\n",
00578                DXGetErrorString8(rc));
00579         }
00580         if (buffer3d) {
00581             if (move_sound) {
00582                 buffer_param.vPosition.x = 100.0;
00583                 buffer_param.vVelocity.x = -200.0/duration;
00584             }
00585             buffer_param.flMinDistance = 10;
00586             rc=IDirectSound3DBuffer_SetAllParameters(buffer,&buffer_param,
00587                                                      DS3D_IMMEDIATE);
00588             ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
00589                DXGetErrorString8(rc));
00590         }
00591 
00592         start_time=GetTickCount();
00593         while (buffer_service(&state)) {
00594             WaitForSingleObject(GetCurrentProcess(),TIME_SLICE);
00595             now=GetTickCount();
00596             if (listener && move_listener) {
00597                 listener_param.vPosition.x = -5.0+10.0*(now-start_time)/
00598                     1000/duration;
00599                 if (winetest_debug>2)
00600                     trace("listener position=%g\n",listener_param.vPosition.x);
00601                 rc=IDirectSound3DListener_SetPosition(listener,
00602                     listener_param.vPosition.x,listener_param.vPosition.y,
00603                     listener_param.vPosition.z,DS3D_IMMEDIATE);
00604                 ok(rc==DS_OK,"IDirectSound3dListener_SetPosition() failed: "
00605                    "%s\n",DXGetErrorString8(rc));
00606             }
00607             if (buffer3d && move_sound) {
00608                 buffer_param.vPosition.x = 100-200.0*(now-start_time)/
00609                     1000/duration;
00610                 if (winetest_debug>2)
00611                     trace("sound position=%g\n",buffer_param.vPosition.x);
00612                 rc=IDirectSound3DBuffer_SetPosition(buffer,
00613                     buffer_param.vPosition.x,buffer_param.vPosition.y,
00614                     buffer_param.vPosition.z,DS3D_IMMEDIATE);
00615                 ok(rc==DS_OK,"IDirectSound3dBuffer_SetPosition() failed: %s\n",
00616                    DXGetErrorString8(rc));
00617             }
00618         }
00619         /* Check the sound duration was within 10% of the expected value */
00620         now=GetTickCount();
00621         ok(fabs(1000*duration-now+start_time)<=100*duration,
00622            "The sound played for %ld ms instead of %g ms\n",
00623            now-start_time,1000*duration);
00624 
00625         free(state.wave);
00626         if (is_primary) {
00627             /* Set the CooperativeLevel back to normal */
00628             /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
00629             rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
00630             ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) "
00631                "failed: %s\n",DXGetErrorString8(rc));
00632         }
00633         if (buffer3d) {
00634             ref=IDirectSound3DBuffer_Release(buffer);
00635             ok(ref==0,"IDirectSound3DBuffer_Release() has %d references, "
00636                "should have 0\n",ref);
00637         }
00638     }
00639 }
00640 
00641 static HRESULT test_secondary(LPGUID lpGuid, int play,
00642                               int has_3d, int has_3dbuffer,
00643                               int has_listener, int has_duplicate,
00644                               int move_listener, int move_sound)
00645 {
00646     HRESULT rc;
00647     LPDIRECTSOUND dso=NULL;
00648     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
00649     LPDIRECTSOUND3DLISTENER listener=NULL;
00650     DSBUFFERDESC bufdesc;
00651     WAVEFORMATEX wfx, wfx1;
00652     int ref;
00653 
00654     /* Create the DirectSound object */
00655     rc=DirectSoundCreate(lpGuid,&dso,NULL);
00656     ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n",
00657        DXGetErrorString8(rc));
00658     if (rc!=DS_OK)
00659         return rc;
00660 
00661     /* We must call SetCooperativeLevel before creating primary buffer */
00662     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
00663     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
00664     ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
00665        "%s\n",DXGetErrorString8(rc));
00666     if (rc!=DS_OK)
00667         goto EXIT;
00668 
00669     ZeroMemory(&bufdesc, sizeof(bufdesc));
00670     bufdesc.dwSize=sizeof(bufdesc);
00671     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
00672     if (has_3d)
00673         bufdesc.dwFlags|=DSBCAPS_CTRL3D;
00674     else
00675         bufdesc.dwFlags|=(DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN);
00676     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
00677     ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL),
00678        "IDirectSound_CreateSoundBuffer() failed to create a %sprimary buffer: "
00679        "%s\n",has_3d?"3D ":"", DXGetErrorString8(rc));
00680     if (rc==DSERR_CONTROLUNAVAIL)
00681         trace("  No Primary\n");
00682     else if (rc==DS_OK && primary!=NULL) {
00683         rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL);
00684         ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %s\n",
00685            DXGetErrorString8(rc));
00686         if (rc!=DS_OK)
00687             goto EXIT1;
00688 
00689         if (has_listener) {
00690             rc=IDirectSoundBuffer_QueryInterface(primary,
00691                                                  &IID_IDirectSound3DListener,
00692                                                  (void **)&listener);
00693             ok(rc==DS_OK && listener!=NULL,
00694                "IDirectSoundBuffer_QueryInterface() failed to get a 3D "
00695                "listener: %s\n",DXGetErrorString8(rc));
00696             ref=IDirectSoundBuffer_Release(primary);
00697             ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
00698                "should have 0\n",ref);
00699             if (rc==DS_OK && listener!=NULL) {
00700                 DS3DLISTENER listener_param;
00701                 ZeroMemory(&listener_param,sizeof(listener_param));
00702                 /* DSOUND: Error: Invalid buffer */
00703                 rc=IDirectSound3DListener_GetAllParameters(listener,0);
00704                 ok(rc==DSERR_INVALIDPARAM,
00705                    "IDirectSound3dListener_GetAllParameters() should have "
00706                    "returned DSERR_INVALIDPARAM, returned: %s\n",
00707                    DXGetErrorString8(rc));
00708 
00709                 /* DSOUND: Error: Invalid buffer */
00710                 rc=IDirectSound3DListener_GetAllParameters(listener,
00711                                                            &listener_param);
00712                 ok(rc==DSERR_INVALIDPARAM,
00713                    "IDirectSound3dListener_GetAllParameters() should have "
00714                    "returned DSERR_INVALIDPARAM, returned: %s\n",
00715                    DXGetErrorString8(rc));
00716 
00717                 listener_param.dwSize=sizeof(listener_param);
00718                 rc=IDirectSound3DListener_GetAllParameters(listener,
00719                                                            &listener_param);
00720                 ok(rc==DS_OK,"IDirectSound3dListener_GetAllParameters() "
00721                    "failed: %s\n",DXGetErrorString8(rc));
00722             }
00723             else
00724                 goto EXIT;
00725         }
00726 
00727         init_format(&wfx,WAVE_FORMAT_PCM,22050,16,2);
00728         secondary=NULL;
00729         ZeroMemory(&bufdesc, sizeof(bufdesc));
00730         bufdesc.dwSize=sizeof(bufdesc);
00731         bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2;
00732         if (has_3d)
00733             bufdesc.dwFlags|=DSBCAPS_CTRL3D;
00734         else
00735             bufdesc.dwFlags|=
00736                 (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN);
00737         bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000,
00738                                     wfx.nBlockAlign);
00739         bufdesc.lpwfxFormat=&wfx;
00740         if (winetest_interactive) {
00741             trace("  Testing a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d "
00742                   "with a primary buffer at %ldx%dx%d\n",
00743                   has_3dbuffer?"3D ":"",
00744                   has_duplicate?"duplicated ":"",
00745                   listener!=NULL||move_sound?"with ":"",
00746                   move_listener?"moving ":"",
00747                   listener!=NULL?"listener ":"",
00748                   listener&&move_sound?"and moving sound ":move_sound?
00749                   "moving sound ":"",
00750                   wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
00751                   wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels);
00752         }
00753         rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
00754         ok(rc==DS_OK && secondary!=NULL,"IDirectSound_CreateSoundBuffer() "
00755            "failed to create a %s%ssecondary buffer %s%s%s%sat %ldx%dx%d (%s): %s\n",
00756            has_3dbuffer?"3D ":"", has_duplicate?"duplicated ":"",
00757            listener!=NULL||move_sound?"with ":"", move_listener?"moving ":"",
00758            listener!=NULL?"listener ":"",
00759            listener&&move_sound?"and moving sound ":move_sound?
00760            "moving sound ":"",
00761            wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels,
00762            getDSBCAPS(bufdesc.dwFlags),DXGetErrorString8(rc));
00763         if (rc==DS_OK && secondary!=NULL) {
00764             if (!has_3d) {
00765                 LONG refvol,vol,refpan,pan;
00766 
00767                 /* Check the initial secondary buffer's volume and pan */
00768                 rc=IDirectSoundBuffer_GetVolume(secondary,&vol);
00769                 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(secondary) failed: "
00770                    "%s\n",DXGetErrorString8(rc));
00771                 ok(vol==0,"wrong volume for a new secondary buffer: %ld\n",vol);
00772                 rc=IDirectSoundBuffer_GetPan(secondary,&pan);
00773                 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(secondary) failed: "
00774                    "%s\n",DXGetErrorString8(rc));
00775                 ok(pan==0,"wrong pan for a new secondary buffer: %ld\n",pan);
00776 
00777                 /* Check that changing the secondary buffer's volume and pan
00778                  * does not impact the primary buffer's volume and pan
00779                  */
00780                 rc=IDirectSoundBuffer_GetVolume(primary,&refvol);
00781                 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(primary) failed: "
00782                    "%s\n",DXGetErrorString8(rc));
00783                 rc=IDirectSoundBuffer_GetPan(primary,&refpan);
00784                 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
00785                    DXGetErrorString8(rc));
00786 
00787                 rc=IDirectSoundBuffer_SetVolume(secondary,-1000);
00788                 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
00789                    "%s\n",DXGetErrorString8(rc));
00790                 rc=IDirectSoundBuffer_GetVolume(secondary,&vol);
00791                 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
00792                    "%s\n",DXGetErrorString8(rc));
00793                 ok(vol==-1000,"secondary: wrong volume %ld instead of -1000\n",
00794                    vol);
00795                 rc=IDirectSoundBuffer_SetPan(secondary,-1000);
00796                 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
00797                    "%s\n",DXGetErrorString8(rc));
00798                 rc=IDirectSoundBuffer_GetPan(secondary,&pan);
00799                 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
00800                    "%s\n",DXGetErrorString8(rc));
00801                 ok(pan==-1000,"secondary: wrong pan %ld instead of -1000\n",
00802                    pan);
00803 
00804                 rc=IDirectSoundBuffer_GetVolume(primary,&vol);
00805                 ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume(primary) failed: "
00806                    "%s\n",DXGetErrorString8(rc));
00807                 ok(vol==refvol,"The primary volume changed from %ld to %ld\n",
00808                    refvol,vol);
00809                 rc=IDirectSoundBuffer_GetPan(primary,&pan);
00810                 ok(rc==DS_OK,"IDirectSoundBuffer_GetPan(primary) failed: %s\n",
00811                    DXGetErrorString8(rc));
00812                 ok(pan==refpan,"The primary pan changed from %ld to %ld\n",
00813                    refpan,pan);
00814 
00815                 rc=IDirectSoundBuffer_SetVolume(secondary,0);
00816                 ok(rc==DS_OK,"IDirectSoundBuffer_SetVolume(secondary) failed: "
00817                    "%s\n",DXGetErrorString8(rc));
00818                 rc=IDirectSoundBuffer_SetPan(secondary,0);
00819                 ok(rc==DS_OK,"IDirectSoundBuffer_SetPan(secondary) failed: "
00820                    "%s\n",DXGetErrorString8(rc));
00821             }
00822             if (has_duplicate) {
00823                 LPDIRECTSOUNDBUFFER duplicated=NULL;
00824 
00825                 /* DSOUND: Error: Invalid source buffer */
00826                 rc=IDirectSound_DuplicateSoundBuffer(dso,0,0);
00827                 ok(rc==DSERR_INVALIDPARAM,
00828                    "IDirectSound_DuplicateSoundBuffer() should have returned "
00829                    "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
00830 
00831                 /* DSOUND: Error: Invalid dest buffer */
00832                 rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,0);
00833                 ok(rc==DSERR_INVALIDPARAM,
00834                    "IDirectSound_DuplicateSoundBuffer() should have returned "
00835                    "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
00836 
00837                 /* DSOUND: Error: Invalid source buffer */
00838                 rc=IDirectSound_DuplicateSoundBuffer(dso,0,&duplicated);
00839                 ok(rc==DSERR_INVALIDPARAM,
00840                   "IDirectSound_DuplicateSoundBuffer() should have returned "
00841                   "DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
00842 
00843                 duplicated=NULL;
00844                 rc=IDirectSound_DuplicateSoundBuffer(dso,secondary,
00845                                                      &duplicated);
00846                 ok(rc==DS_OK && duplicated!=NULL,
00847                    "IDirectSound_DuplicateSoundBuffer() failed to duplicate "
00848                    "a secondary buffer: %s\n",DXGetErrorString8(rc));
00849 
00850                 if (rc==DS_OK && duplicated!=NULL) {
00851                     ref=IDirectSoundBuffer_Release(secondary);
00852                     ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d "
00853                       "references, should have 0\n",ref);
00854                     secondary=duplicated;
00855                 }
00856             }
00857 
00858             if (rc==DS_OK && secondary!=NULL) {
00859                 double duration;
00860                 duration=(move_listener || move_sound?4.0:1.0);
00861                 test_buffer(dso,secondary,0,FALSE,0,FALSE,0,
00862                             winetest_interactive,duration,has_3dbuffer,
00863                             listener,move_listener,move_sound,FALSE,0);
00864                 ref=IDirectSoundBuffer_Release(secondary);
00865                 ok(ref==0,"IDirectSoundBuffer_Release() %s has %d references, "
00866                    "should have 0\n",has_duplicate?"duplicated":"secondary",
00867                    ref);
00868             }
00869         }
00870     }
00871 EXIT1:
00872     if (has_listener) {
00873         ref=IDirectSound3DListener_Release(listener);
00874         ok(ref==0,"IDirectSound3dListener_Release() listener has %d "
00875            "references, should have 0\n",ref);
00876     } else {
00877         ref=IDirectSoundBuffer_Release(primary);
00878         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
00879            "should have 0\n",ref);
00880     }
00881 
00882     /* Set the CooperativeLevel back to normal */
00883     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
00884     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
00885     ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
00886        DXGetErrorString8(rc));
00887 
00888 EXIT:
00889     ref=IDirectSound_Release(dso);
00890     ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
00891     if (ref!=0)
00892         return DSERR_GENERIC;
00893 
00894     return rc;
00895 }
00896 
00897 static HRESULT test_for_driver(LPGUID lpGuid)
00898 {
00899     HRESULT rc;
00900     LPDIRECTSOUND dso=NULL;
00901     int ref;
00902 
00903     /* Create the DirectSound object */
00904     rc=DirectSoundCreate(lpGuid,&dso,NULL);
00905     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
00906        "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
00907     if (rc!=DS_OK)
00908         return rc;
00909 
00910     ref=IDirectSound_Release(dso);
00911     ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
00912     if (ref!=0)
00913         return DSERR_GENERIC;
00914 
00915     return rc;
00916 }
00917 
00918 static HRESULT test_primary(LPGUID lpGuid)
00919 {
00920     HRESULT rc;
00921     LPDIRECTSOUND dso=NULL;
00922     LPDIRECTSOUNDBUFFER primary=NULL;
00923     DSBUFFERDESC bufdesc;
00924     DSCAPS dscaps;
00925     int ref, i;
00926 
00927     /* Create the DirectSound object */
00928     rc=DirectSoundCreate(lpGuid,&dso,NULL);
00929     ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n",
00930        DXGetErrorString8(rc));
00931     if (rc!=DS_OK)
00932         return rc;
00933 
00934     /* Get the device capabilities */
00935     ZeroMemory(&dscaps, sizeof(dscaps));
00936     dscaps.dwSize=sizeof(dscaps);
00937     rc=IDirectSound_GetCaps(dso,&dscaps);
00938     ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
00939     if (rc!=DS_OK)
00940         goto EXIT;
00941 
00942     /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
00943     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
00944     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
00945     ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
00946        "%s\n",DXGetErrorString8(rc));
00947     if (rc!=DS_OK)
00948         goto EXIT;
00949 
00950     /* Testing the primary buffer */
00951     primary=NULL;
00952     ZeroMemory(&bufdesc, sizeof(bufdesc));
00953     bufdesc.dwSize=sizeof(bufdesc);
00954     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME|DSBCAPS_CTRLPAN;
00955     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
00956     ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL),
00957        "IDirectSound_CreateSoundBuffer() failed to create a primary buffer: "
00958        "%s\n",DXGetErrorString8(rc));
00959     if (rc==DSERR_CONTROLUNAVAIL)
00960         trace("  No Primary\n");
00961     else if (rc==DS_OK && primary!=NULL) {
00962         test_buffer(dso,primary,1,TRUE,0,TRUE,0,winetest_interactive &&
00963                     !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,NULL,0,0,
00964                     FALSE,0);
00965         if (winetest_interactive) {
00966             LONG volume,pan;
00967 
00968             volume = DSBVOLUME_MAX;
00969             for (i = 0; i < 6; i++) {
00970                 test_buffer(dso,primary,1,TRUE,volume,TRUE,0,
00971                             winetest_interactive &&
00972                             !(dscaps.dwFlags & DSCAPS_EMULDRIVER),
00973                             1.0,0,NULL,0,0,FALSE,0);
00974                 volume -= ((DSBVOLUME_MAX-DSBVOLUME_MIN) / 40);
00975             }
00976 
00977             pan = DSBPAN_LEFT;
00978             for (i = 0; i < 7; i++) {
00979                 test_buffer(dso,primary,1,TRUE,0,TRUE,pan,
00980                             winetest_interactive &&
00981                             !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0,FALSE,0);
00982                 pan += ((DSBPAN_RIGHT-DSBPAN_LEFT) / 6);
00983             }
00984         }
00985         ref=IDirectSoundBuffer_Release(primary);
00986         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
00987            "should have 0\n",ref);
00988     }
00989 
00990     /* Set the CooperativeLevel back to normal */
00991     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
00992     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
00993     ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
00994        DXGetErrorString8(rc));
00995 
00996 EXIT:
00997     ref=IDirectSound_Release(dso);
00998     ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
00999     if (ref!=0)
01000         return DSERR_GENERIC;
01001 
01002     return rc;
01003 }
01004 
01005 static HRESULT test_primary_3d(LPGUID lpGuid)
01006 {
01007     HRESULT rc;
01008     LPDIRECTSOUND dso=NULL;
01009     LPDIRECTSOUNDBUFFER primary=NULL;
01010     DSBUFFERDESC bufdesc;
01011     DSCAPS dscaps;
01012     int ref;
01013 
01014     /* Create the DirectSound object */
01015     rc=DirectSoundCreate(lpGuid,&dso,NULL);
01016     ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n",
01017        DXGetErrorString8(rc));
01018     if (rc!=DS_OK)
01019         return rc;
01020 
01021     /* Get the device capabilities */
01022     ZeroMemory(&dscaps, sizeof(dscaps));
01023     dscaps.dwSize=sizeof(dscaps);
01024     rc=IDirectSound_GetCaps(dso,&dscaps);
01025     ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
01026     if (rc!=DS_OK)
01027         goto EXIT;
01028 
01029     /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
01030     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
01031     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
01032     ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
01033        "%s\n",DXGetErrorString8(rc));
01034     if (rc!=DS_OK)
01035         goto EXIT;
01036 
01037     primary=NULL;
01038     ZeroMemory(&bufdesc, sizeof(bufdesc));
01039     bufdesc.dwSize=sizeof(bufdesc);
01040     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER;
01041     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
01042     ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() failed "
01043        "to create a primary buffer: %s\n",DXGetErrorString8(rc));
01044     if (rc==DS_OK && primary!=NULL) {
01045         ref=IDirectSoundBuffer_Release(primary);
01046         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
01047            "should have 0\n",ref);
01048         primary=NULL;
01049         ZeroMemory(&bufdesc, sizeof(bufdesc));
01050         bufdesc.dwSize=sizeof(bufdesc);
01051         bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
01052         rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
01053         ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() "
01054            "failed to create a 3D primary buffer: %s\n",DXGetErrorString8(rc));
01055         if (rc==DS_OK && primary!=NULL) {
01056             test_buffer(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive &&
01057                         !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,0,0,0,
01058                         FALSE,0);
01059             ref=IDirectSoundBuffer_Release(primary);
01060             ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
01061                "should have 0\n",ref);
01062         }
01063     }
01064     /* Set the CooperativeLevel back to normal */
01065     /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */
01066     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL);
01067     ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_NORMAL) failed: %s\n",
01068        DXGetErrorString8(rc));
01069 
01070 EXIT:
01071     ref=IDirectSound_Release(dso);
01072     ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
01073     if (ref!=0)
01074         return DSERR_GENERIC;
01075 
01076     return rc;
01077 }
01078 
01079 static HRESULT test_primary_3d_with_listener(LPGUID lpGuid)
01080 {
01081     HRESULT rc;
01082     LPDIRECTSOUND dso=NULL;
01083     LPDIRECTSOUNDBUFFER primary=NULL;
01084     DSBUFFERDESC bufdesc;
01085     DSCAPS dscaps;
01086     int ref;
01087 
01088     /* Create the DirectSound object */
01089     rc=DirectSoundCreate(lpGuid,&dso,NULL);
01090     ok(rc==DS_OK||rc==DSERR_NODRIVER,"DirectSoundCreate() failed: %s\n",
01091        DXGetErrorString8(rc));
01092     if (rc!=DS_OK)
01093         return rc;
01094 
01095     /* Get the device capabilities */
01096     ZeroMemory(&dscaps, sizeof(dscaps));
01097     dscaps.dwSize=sizeof(dscaps);
01098     rc=IDirectSound_GetCaps(dso,&dscaps);
01099     ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %s\n",DXGetErrorString8(rc));
01100     if (rc!=DS_OK)
01101         goto EXIT;
01102 
01103     /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
01104     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
01105     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
01106     ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel(DSSCL_PRIORITY) failed: "
01107        "%s\n",DXGetErrorString8(rc));
01108     if (rc!=DS_OK)
01109         goto EXIT;
01110     primary=NULL;
01111     ZeroMemory(&bufdesc, sizeof(bufdesc));
01112     bufdesc.dwSize=sizeof(bufdesc);
01113     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRL3D;
01114     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
01115     ok(rc==DS_OK && primary!=NULL,"IDirectSound_CreateSoundBuffer() failed "
01116        "to create a 3D primary buffer: %s\n",DXGetErrorString8(rc));
01117     if (rc==DS_OK && primary!=NULL) {
01118         LPDIRECTSOUND3DLISTENER listener=NULL;
01119         rc=IDirectSoundBuffer_QueryInterface(primary,
01120             &IID_IDirectSound3DListener,(void **)&listener);
01121         ok(rc==DS_OK && listener!=NULL,"IDirectSoundBuffer_QueryInterface() "
01122            "failed to get a 3D listener: %s\n",DXGetErrorString8(rc));
01123         if (rc==DS_OK && listener!=NULL) {
01124             LPDIRECTSOUNDBUFFER temp_buffer=NULL;
01125 
01126             /* Checking the COM interface */
01127             rc=IDirectSoundBuffer_QueryInterface(primary,
01128                 &IID_IDirectSoundBuffer,(LPVOID *)&temp_buffer);
01129             ok(rc==DS_OK && temp_buffer!=NULL,
01130                "IDirectSoundBuffer_QueryInterface() failed: %s\n",
01131                DXGetErrorString8(rc));
01132             ok(temp_buffer==primary,
01133                "COM interface broken: %p != %p\n",
01134                temp_buffer,primary);
01135             if (rc==DS_OK && temp_buffer!=NULL) {
01136                 ref=IDirectSoundBuffer_Release(temp_buffer);
01137                 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, "
01138                    "should have 1\n",ref);
01139 
01140                 temp_buffer=NULL;
01141                 rc=IDirectSound3DListener_QueryInterface(listener,
01142                     &IID_IDirectSoundBuffer,(LPVOID *)&temp_buffer);
01143                 ok(rc==DS_OK && temp_buffer!=NULL,
01144                    "IDirectSoundBuffer_QueryInterface() failed: %s\n",
01145                    DXGetErrorString8(rc));
01146                 ok(temp_buffer==primary,
01147                    "COM interface broken: %p != %p\n",
01148                    temp_buffer,primary);
01149                 ref=IDirectSoundBuffer_Release(temp_buffer);
01150                 ok(ref==1,"IDirectSoundBuffer_Release() has %d references, "
01151                    "should have 1\n",ref);
01152 
01153                 /* Testing the buffer */
01154                 test_buffer(dso,primary,1,FALSE,0,FALSE,0,
01155                             winetest_interactive &&
01156                             !(dscaps.dwFlags & DSCAPS_EMULDRIVER),1.0,0,
01157                             listener,0,0,FALSE,0);
01158             }
01159 
01160             /* Testing the reference counting */
01161             ref=IDirectSound3DListener_Release(listener);
01162             ok(ref==0,"IDirectSound3DListener_Release() listener has %d "
01163                "references, should have 0\n",ref);
01164         }
01165 
01166         /* Testing the reference counting */
01167         ref=IDirectSoundBuffer_Release(primary);
01168         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
01169            "should have 0\n",ref);
01170     }
01171 
01172 EXIT:
01173     ref=IDirectSound_Release(dso);
01174     ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref);
01175     if (ref!=0)
01176 return DSERR_GENERIC;
01177 
01178     return rc;
01179 }
01180 
01181 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
01182                                    LPCSTR lpcstrModule, LPVOID lpContext)
01183 {
01184     HRESULT rc;
01185     trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
01186 
01187     rc = test_for_driver(lpGuid);
01188     if (rc == DSERR_NODRIVER) {
01189         trace("  No Driver\n");
01190         return 1;
01191     } else if (rc == DSERR_ALLOCATED) {
01192         trace("  Already In Use\n");
01193         return 1;
01194     } else if (rc == E_FAIL) {
01195         trace("  No Device\n");
01196         return 1;
01197     }
01198 
01199     trace("  Testing the primary buffer\n");
01200     test_primary(lpGuid);
01201 
01202     trace("  Testing 3D primary buffer\n");
01203     test_primary_3d(lpGuid);
01204 
01205     trace("  Testing 3D primary buffer with listener\n");
01206     test_primary_3d_with_listener(lpGuid);
01207 
01208     /* Testing secondary buffers */
01209     test_secondary(lpGuid,winetest_interactive,0,0,0,0,0,0);
01210     test_secondary(lpGuid,winetest_interactive,0,0,0,1,0,0);
01211 
01212     /* Testing 3D secondary buffers */
01213     test_secondary(lpGuid,winetest_interactive,1,0,0,0,0,0);
01214     test_secondary(lpGuid,winetest_interactive,1,1,0,0,0,0);
01215     test_secondary(lpGuid,winetest_interactive,1,1,0,1,0,0);
01216     test_secondary(lpGuid,winetest_interactive,1,0,1,0,0,0);
01217     test_secondary(lpGuid,winetest_interactive,1,0,1,1,0,0);
01218     test_secondary(lpGuid,winetest_interactive,1,1,1,0,0,0);
01219     test_secondary(lpGuid,winetest_interactive,1,1,1,1,0,0);
01220     test_secondary(lpGuid,winetest_interactive,1,1,1,0,1,0);
01221     test_secondary(lpGuid,winetest_interactive,1,1,1,0,0,1);
01222     test_secondary(lpGuid,winetest_interactive,1,1,1,0,1,1);
01223 
01224     return 1;
01225 }
01226 
01227 static void ds3d_tests(void)
01228 {
01229     HRESULT rc;
01230     rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
01231     ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
01232 }
01233 
01234 START_TEST(ds3d)
01235 {
01236     CoInitialize(NULL);
01237 
01238     trace("DLL Version: %s\n", get_file_version("dsound.dll"));
01239 
01240     ds3d_tests();
01241 
01242     CoUninitialize();
01243 }

Generated on Sun May 27 2012 04:21:42 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.