/* * Tests basic sound playback in DirectSound. * In particular we test each standard Windows sound format to make sure * we handle the sound card/driver quirks correctly. * * Part of this test involves playing test tones. But this only makes * sense if someone is going to carefully listen to it, and would only * bother everyone else. * So this is only done if the test is being run in interactive mode. * * Copyright (c) 2002-2004 Francois Gouget * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #define COBJMACROS #define NONAMELESSUNION #include #include #include "wine/test.h" #include "mmsystem.h" #include "dsound.h" #include "dsconf.h" #include "ks.h" #include "ksmedia.h" #include "initguid.h" #include "mediaobj.h" #include "wingdi.h" #include "mmdeviceapi.h" #include "audioclient.h" #include "propkey.h" #include "devpkey.h" #include "dsound_test.h" static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL; static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,LPUNKNOWN)=NULL; int align(int length, int align) { return (length / align) * align; } static void IDirectSound8_test(LPDIRECTSOUND8 dso, BOOL initialized, LPCGUID lpGuid) { HRESULT rc; DSCAPS dscaps; int ref; IUnknown * unknown; IDirectSound * ds; IDirectSound8 * ds8; DWORD speaker_config, new_speaker_config, ref_speaker_config; DWORD certified; /* Try to Query for objects */ rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown); ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %08x\n", rc); if (rc==DS_OK) IDirectSound8_Release(unknown); rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds); ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %08x\n", rc); if (rc==DS_OK) IDirectSound_Release(ds); rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8); ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) " "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); if (rc==DS_OK) IDirectSound8_Release(ds8); if (initialized == FALSE) { /* try uninitialized object */ rc=IDirectSound8_GetCaps(dso,0); ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps(NULL) " "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc); rc=IDirectSound8_GetCaps(dso,&dscaps); ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetCaps() " "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc); rc=IDirectSound8_Compact(dso); ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_Compact() " "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc); rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config); ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_GetSpeakerConfig() " "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc); rc=IDirectSound8_VerifyCertification(dso, &certified); ok(rc==DSERR_UNINITIALIZED,"IDirectSound8_VerifyCertification() " "should have returned DSERR_UNINITIALIZED, returned: %08x\n", rc); rc=IDirectSound8_Initialize(dso,lpGuid); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "IDirectSound8_Initialize() failed: %08x\n",rc); if (rc==DSERR_NODRIVER) { trace(" No Driver\n"); goto EXIT; } else if (rc==E_FAIL) { trace(" No Device\n"); goto EXIT; } else if (rc==DSERR_ALLOCATED) { trace(" Already In Use\n"); goto EXIT; } } rc=IDirectSound8_Initialize(dso,lpGuid); ok(rc==DSERR_ALREADYINITIALIZED, "IDirectSound8_Initialize() " "should have returned DSERR_ALREADYINITIALIZED: %08x\n", rc); /* DSOUND: Error: Invalid caps buffer */ rc=IDirectSound8_GetCaps(dso,0); ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() " "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); ZeroMemory(&dscaps, sizeof(dscaps)); /* DSOUND: Error: Invalid caps buffer */ rc=IDirectSound8_GetCaps(dso,&dscaps); ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetCaps() " "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); dscaps.dwSize=sizeof(dscaps); /* DSOUND: Running on a certified driver */ rc=IDirectSound8_GetCaps(dso,&dscaps); ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc); rc=IDirectSound8_Compact(dso); ok(rc==DSERR_PRIOLEVELNEEDED,"IDirectSound8_Compact() failed: %08x\n", rc); rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc); rc=IDirectSound8_Compact(dso); ok(rc==DS_OK,"IDirectSound8_Compact() failed: %08x\n",rc); rc=IDirectSound8_GetSpeakerConfig(dso,0); ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_GetSpeakerConfig(NULL) " "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); rc=IDirectSound8_GetSpeakerConfig(dso,&speaker_config); ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %08x\n", rc); ref_speaker_config = speaker_config; speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_WIDE); if (speaker_config == ref_speaker_config) speaker_config = DSSPEAKER_COMBINED(DSSPEAKER_STEREO, DSSPEAKER_GEOMETRY_NARROW); if(rc==DS_OK) { rc=IDirectSound8_SetSpeakerConfig(dso,speaker_config); ok(rc==DS_OK,"IDirectSound8_SetSpeakerConfig() failed: %08x\n", rc); } if (rc==DS_OK) { rc=IDirectSound8_GetSpeakerConfig(dso,&new_speaker_config); ok(rc==DS_OK,"IDirectSound8_GetSpeakerConfig() failed: %08x\n", rc); if (rc==DS_OK && speaker_config!=new_speaker_config && ref_speaker_config!=new_speaker_config) trace("IDirectSound8_GetSpeakerConfig() failed to set speaker " "config: expected 0x%08x or 0x%08x, got 0x%08x\n", speaker_config,ref_speaker_config,new_speaker_config); IDirectSound8_SetSpeakerConfig(dso,ref_speaker_config); } rc=IDirectSound8_VerifyCertification(dso, &certified); ok(rc==DS_OK||rc==E_NOTIMPL,"IDirectSound8_VerifyCertification() failed: %08x\n", rc); EXIT: ref=IDirectSound8_Release(dso); ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref); } static void IDirectSound8_tests(void) { HRESULT rc; LPDIRECTSOUND8 dso=NULL; LPCLASSFACTORY cf=NULL; trace("Testing IDirectSound8\n"); rc=CoGetClassObject(&CLSID_DirectSound8, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&cf); ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSound8, IID_IClassFactory) " "failed: %08x\n", rc); rc=CoGetClassObject(&CLSID_DirectSound8, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&cf); ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSound8, IID_IUnknown) " "failed: %08x\n", rc); /* try the COM class factory method of creation with no device specified */ rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void**)&dso); ok(rc==S_OK||rc==REGDB_E_CLASSNOTREG,"CoCreateInstance() failed: %08x\n", rc); if (rc==REGDB_E_CLASSNOTREG) { trace(" Class Not Registered\n"); return; } if (dso) IDirectSound8_test(dso, FALSE, NULL); /* try the COM class factory method of creation with default playback * device specified */ rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void**)&dso); ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc); if (dso) IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultPlayback); /* try the COM class factory method of creation with default voice * playback device specified */ rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void**)&dso); ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound8) failed: %08x\n", rc); if (dso) IDirectSound8_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback); /* try the COM class factory method of creation with a bad * IID specified */ rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &CLSID_DirectSoundPrivate, (void**)&dso); ok(rc==E_NOINTERFACE, "CoCreateInstance(CLSID_DirectSound8,CLSID_DirectSoundPrivate) " "should have failed: %08x\n",rc); /* try the COM class factory method of creation with a bad * GUID and IID specified */ rc=CoCreateInstance(&CLSID_DirectSoundPrivate, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void**)&dso); ok(rc==REGDB_E_CLASSNOTREG, "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound8) " "should have failed: %08x\n",rc); /* try with no device specified */ rc=pDirectSoundCreate8(NULL,&dso,NULL); ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate8() failed: %08x\n",rc); if (rc==DS_OK && dso) IDirectSound8_test(dso, TRUE, NULL); /* try with default playback device specified */ rc=pDirectSoundCreate8(&DSDEVID_DefaultPlayback,&dso,NULL); ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate8() failed: %08x\n",rc); if (rc==DS_OK && dso) IDirectSound8_test(dso, TRUE, NULL); /* try with default voice playback device specified */ rc=pDirectSoundCreate8(&DSDEVID_DefaultVoicePlayback,&dso,NULL); ok(rc==S_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate8() failed: %08x\n",rc); if (rc==DS_OK && dso) IDirectSound8_test(dso, TRUE, NULL); /* try with a bad device specified */ rc=pDirectSoundCreate8(&DSDEVID_DefaultVoiceCapture,&dso,NULL); ok(rc==DSERR_NODRIVER,"DirectSoundCreate8(DSDEVID_DefaultVoiceCapture) " "should have failed: %08x\n",rc); } static HRESULT test_dsound8(LPGUID lpGuid) { HRESULT rc; LPDIRECTSOUND8 dso=NULL; int ref; /* DSOUND: Error: Invalid interface buffer */ rc=pDirectSoundCreate8(lpGuid,0,NULL); ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8() should have returned " "DSERR_INVALIDPARAM, returned: %08x\n",rc); /* Create the DirectSound8 object */ rc=pDirectSoundCreate8(lpGuid,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate8() failed: %08x\n",rc); if (rc!=DS_OK) return rc; /* Try the enumerated device */ IDirectSound8_test(dso, TRUE, lpGuid); /* Try the COM class factory method of creation with enumerated device */ rc=CoCreateInstance(&CLSID_DirectSound8, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound8, (void**)&dso); ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc); if (dso) IDirectSound8_test(dso, FALSE, lpGuid); /* Create a DirectSound8 object */ rc=pDirectSoundCreate8(lpGuid,&dso,NULL); ok(rc==DS_OK,"DirectSoundCreate8() failed: %08x\n",rc); if (rc==DS_OK) { LPDIRECTSOUND8 dso1=NULL; /* Create a second DirectSound8 object */ rc=pDirectSoundCreate8(lpGuid,&dso1,NULL); ok(rc==DS_OK,"DirectSoundCreate8() failed: %08x\n",rc); if (rc==DS_OK) { /* Release the second DirectSound8 object */ ref=IDirectSound8_Release(dso1); ok(ref==0,"IDirectSound8_Release() has %d references, " "should have 0\n",ref); ok(dso!=dso1,"DirectSound8 objects should be unique: " "dso=%p,dso1=%p\n",dso,dso1); } /* Release the first DirectSound8 object */ ref=IDirectSound8_Release(dso); ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n", ref); if (ref!=0) return DSERR_GENERIC; } else return rc; /* Create a DirectSound8 object */ rc=pDirectSoundCreate8(lpGuid,&dso,NULL); ok(rc==DS_OK,"DirectSoundCreate8() failed: %08x\n",rc); if (rc==DS_OK) { LPDIRECTSOUNDBUFFER secondary; DSBUFFERDESC bufdesc; WAVEFORMATEX wfx; init_format(&wfx,WAVE_FORMAT_PCM,11025,8,1); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D; bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx; rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary!=NULL, "IDirectSound8_CreateSoundBuffer() failed to create a secondary " "buffer: %08x\n",rc); if (rc==DS_OK && secondary!=NULL) { LPDIRECTSOUND3DBUFFER buffer3d; LPDIRECTSOUNDBUFFER8 buffer8; rc=IDirectSound8_QueryInterface(secondary, &IID_IDirectSound3DBuffer, (void **)&buffer3d); ok(rc==DS_OK && buffer3d!=NULL, "IDirectSound8_QueryInterface() failed: %08x\n", rc); if (rc==DS_OK && buffer3d!=NULL) { ref=IDirectSound3DBuffer_AddRef(buffer3d); ok(ref==2,"IDirectSound3DBuffer_AddRef() has %d references, " "should have 2\n",ref); } rc=IDirectSound8_QueryInterface(secondary, &IID_IDirectSoundBuffer8, (void **)&buffer8); if (rc==DS_OK && buffer8!=NULL) { ok(buffer8==(IDirectSoundBuffer8*)secondary, "IDirectSoundBuffer8 iface different from IDirectSoundBuffer.\n"); ref=IDirectSoundBuffer8_AddRef(buffer8); ok(ref==3,"IDirectSoundBuffer8_AddRef() has %d references, " "should have 3\n",ref); } ref=IDirectSoundBuffer_AddRef(secondary); ok(ref==4,"IDirectSoundBuffer_AddRef() has %d references, " "should have 4\n",ref); } /* release with buffer */ ref=IDirectSound8_Release(dso); ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n", ref); if (ref!=0) return DSERR_GENERIC; } else return rc; return DS_OK; } static HRESULT test_primary8(LPGUID lpGuid) { HRESULT rc; LPDIRECTSOUND8 dso=NULL; LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL; LPDIRECTSOUNDBUFFER8 pb8 = NULL; DSBUFFERDESC bufdesc; DSCAPS dscaps; WAVEFORMATEX wfx; int ref; /* Create the DirectSound object */ rc=pDirectSoundCreate8(lpGuid,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, "DirectSoundCreate8() failed: %08x\n",rc); if (rc!=DS_OK) return rc; /* Get the device capabilities */ ZeroMemory(&dscaps, sizeof(dscaps)); dscaps.dwSize=sizeof(dscaps); rc=IDirectSound8_GetCaps(dso,&dscaps); ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc); if (rc!=DS_OK) goto EXIT; /* DSOUND: Error: Invalid buffer description pointer */ rc=IDirectSound8_CreateSoundBuffer(dso,0,0,NULL); ok(rc==DSERR_INVALIDPARAM, "IDirectSound8_CreateSoundBuffer should have returned " "DSERR_INVALIDPARAM, returned: %08x\n",rc); /* DSOUND: Error: Invalid buffer description pointer */ rc=IDirectSound8_CreateSoundBuffer(dso,0,&primary,NULL); ok(rc==DSERR_INVALIDPARAM && primary==0, "IDirectSound8_CreateSoundBuffer() should have returned " "DSERR_INVALIDPARAM, returned: rc=%08x,dsbo=%p\n", rc,primary); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize = sizeof(DSBUFFERDESC); /* DSOUND: Error: Invalid dsound buffer interface pointer */ rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,0,NULL); ok(rc==DSERR_INVALIDPARAM && primary==0, "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x," "dsbo=%p\n",rc,primary); ZeroMemory(&bufdesc, sizeof(bufdesc)); /* DSOUND: Error: Invalid size */ /* DSOUND: Error: Invalid buffer description */ rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok(rc==DSERR_INVALIDPARAM && primary==0, "IDirectSound8_CreateSoundBuffer() should have failed: rc=%08x," "primary=%p\n",rc,primary); /* We must call SetCooperativeLevel before calling CreateSoundBuffer */ /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc); if (rc!=DS_OK) goto EXIT; /* Testing the primary buffer */ primary=NULL; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME; bufdesc.lpwfxFormat = &wfx; init_format(&wfx,WAVE_FORMAT_PCM,11025,8,2); rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok(rc==DSERR_INVALIDPARAM,"IDirectSound8_CreateSoundBuffer() should have " "returned DSERR_INVALIDPARAM, returned: %08x\n", rc); if (rc==DS_OK && primary!=NULL) IDirectSoundBuffer_Release(primary); primary=NULL; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_CTRLVOLUME; rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL), "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer: " "%08x\n",rc); if (rc==DSERR_CONTROLUNAVAIL) trace(" No Primary\n"); else if (rc==DS_OK && primary!=NULL) { LONG vol; /* Try to create a second primary buffer */ /* DSOUND: Error: The primary buffer already exists. * Any changes made to the buffer description will be ignored. */ rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&second,NULL); ok(rc==DS_OK && second==primary, "IDirectSound8_CreateSoundBuffer() should have returned original " "primary buffer: %08x\n",rc); ref=IDirectSoundBuffer_Release(second); ok(ref==1,"IDirectSoundBuffer_Release() primary has %d references, " "should have 1\n",ref); /* Try to duplicate a primary buffer */ /* DSOUND: Error: Can't duplicate primary buffers */ rc=IDirectSound8_DuplicateSoundBuffer(dso,primary,&third); /* rc=0x88780032 */ ok(rc!=DS_OK,"IDirectSound8_DuplicateSoundBuffer() primary buffer " "should have failed %08x\n",rc); /* Primary buffers don't have an IDirectSoundBuffer8 */ rc = IDirectSoundBuffer_QueryInterface(primary, &IID_IDirectSoundBuffer8, (LPVOID*)&pb8); ok(FAILED(rc), "Primary buffer does have an IDirectSoundBuffer8: %08x\n", rc); rc=IDirectSoundBuffer_GetVolume(primary,&vol); ok(rc==DS_OK,"IDirectSoundBuffer_GetVolume() failed: %08x\n", rc); if (winetest_interactive) { trace("Playing a 5 seconds reference tone at the current volume.\n"); if (rc==DS_OK) trace("(the current volume is %d according to DirectSound)\n", vol); trace("All subsequent tones should be identical to this one.\n"); trace("Listen for stutter, changes in pitch, volume, etc.\n"); } test_buffer8(dso,&primary,TRUE,FALSE,0,FALSE,0, winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER), 5.0,FALSE,NULL,FALSE,FALSE); ref=IDirectSoundBuffer_Release(primary); ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " "should have 0\n",ref); } /* Set the CooperativeLevel back to normal */ /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc); EXIT: ref=IDirectSound8_Release(dso); ok(ref==0,"IDirectSound8_Release() has %d references, should have 0\n",ref); if (ref!=0) return DSERR_GENERIC; return rc; } /* * Test the primary buffer at different formats while keeping the * secondary buffer at a constant format. */ static HRESULT test_primary_secondary8(LPGUID lpGuid) { HRESULT rc; LPDIRECTSOUND8 dso=NULL; LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL; DSBUFFERDESC bufdesc; DSCAPS dscaps; WAVEFORMATEX wfx, wfx2; int ref; unsigned int f, tag; /* Create the DirectSound object */ rc=pDirectSoundCreate8(lpGuid,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, "DirectSoundCreate8() failed: %08x\n",rc); if (rc!=DS_OK) return rc; /* Get the device capabilities */ ZeroMemory(&dscaps, sizeof(dscaps)); dscaps.dwSize=sizeof(dscaps); rc=IDirectSound8_GetCaps(dso,&dscaps); ok(rc==DS_OK,"IDirectSound8_GetCaps() failed: %08x\n",rc); if (rc!=DS_OK) goto EXIT; /* We must call SetCooperativeLevel before creating primary buffer */ /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ rc=IDirectSound8_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound8_SetCooperativeLevel() failed: %08x\n", rc); if (rc!=DS_OK) goto EXIT; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; rc=IDirectSound8_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok(rc==DS_OK && primary!=NULL, "IDirectSound8_CreateSoundBuffer() failed to create a primary buffer " "%08x\n",rc); if (rc==DS_OK && primary!=NULL) { for (f=0;f 0 and pDSFXDesc == NULL */ rc=IDirectSoundBuffer8_SetFX(secondary8,1,NULL,NULL); ok(rc==E_INVALIDARG||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX() " "should have returned E_INVALIDARG, returned: %08x\n", rc); /* Call SetFX with dwEffectsCount == 0 and pDSFXDesc != NULL */ rc=IDirectSoundBuffer8_SetFX(secondary8,0,effects,NULL); ok(rc==E_INVALIDARG||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX() " "should have returned E_INVALIDARG, returned: %08x\n", rc); /* Call SetFX with dwEffectsCount == 0 and pdwResultCodes != NULL */ rc=IDirectSoundBuffer8_SetFX(secondary8,0,NULL,resultcodes); ok(rc==E_INVALIDARG||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX() " "should have returned E_INVALIDARG, returned: %08x\n", rc); rc=IDirectSoundBuffer8_Lock(secondary8,0,0,&ptr1,&bytes1,&ptr2,&bytes2,DSBLOCK_ENTIREBUFFER); ok(rc==DS_OK,"IDirectSoundBuffer8_Lock() failed: %08x\n",rc); if (rc==DS_OK) { /* Call SetFX when buffer is locked */ rc=IDirectSoundBuffer8_SetFX(secondary8,1,effects,resultcodes); ok(rc==DSERR_INVALIDCALL||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX() " "should have returned DSERR_INVALIDCALL, returned: %08x\n", rc); rc=IDirectSoundBuffer8_Unlock(secondary8,ptr1,bytes1,ptr2,bytes2); ok(rc==DS_OK,"IDirectSoundBuffer8_Unlock() failed: %08x\n",rc); } rc=IDirectSoundBuffer8_Play(secondary8,0,0,DSBPLAY_LOOPING); ok(rc==DS_OK,"IDirectSoundBuffer8_Play() failed: %08x\n",rc); if (rc==DS_OK) { /* Call SetFX when buffer is playing */ rc=IDirectSoundBuffer8_SetFX(secondary8,1,effects,resultcodes); ok(rc==DSERR_INVALIDCALL||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX() " "should have returned DSERR_INVALIDCALL, returned: %08x\n", rc); rc=IDirectSoundBuffer8_Stop(secondary8); ok(rc==DS_OK,"IDirectSoundBuffer8_Stop() failed: %08x\n",rc); } /* Call SetFX with non-existent filter */ rc=IDirectSoundBuffer8_SetFX(secondary8,1,&effects[1],resultcodes); ok(rc==REGDB_E_CLASSNOTREG||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_SetFX(GUID_NULL) " "should have returned REGDB_E_CLASSNOTREG, returned: %08x\n",rc); if (rc!=DSERR_CONTROLUNAVAIL) { ok(resultcodes[0]==DSFXR_UNKNOWN,"result code == %08x, expected DSFXR_UNKNOWN\n",resultcodes[0]); } /* Call SetFX with standard echo */ rc2=IDirectSoundBuffer8_SetFX(secondary8,1,&effects[0],resultcodes); ok(rc2==DS_OK||rc2==REGDB_E_CLASSNOTREG||rc2==DSERR_CONTROLUNAVAIL, "IDirectSoundBuffer8_SetFX(GUID_DSFX_STANDARD_ECHO) failed: %08x\n",rc); if (rc2!=DSERR_CONTROLUNAVAIL) { ok(resultcodes[0]==DSFXR_UNKNOWN||resultcodes[0]==DSFXR_LOCHARDWARE||resultcodes[0]==DSFXR_LOCSOFTWARE, "resultcode == %08x, expected DSFXR_UNKNOWN, DSFXR_LOCHARDWARE, or DSFXR_LOCSOFTWARE\n",resultcodes[0]); } /* Call GetObjectInPath for out-of-bounds DMO */ rc=IDirectSoundBuffer8_GetObjectInPath(secondary8,&GUID_All_Objects,2,&IID_IMediaObject,(void**)&obj); ok(rc==DSERR_OBJECTNOTFOUND||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() " "should have returned DSERR_OBJECTNOTFOUND, returned: %08x\n",rc); /* Call GetObjectInPath with NULL ppObject */ rc=IDirectSoundBuffer8_GetObjectInPath(secondary8,&GUID_All_Objects,0,&IID_IMediaObject,NULL); ok(rc==E_INVALIDARG||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() " "should have returned E_INVALIDARG, returned: %08x\n",rc); /* Call GetObjectInPath for unsupported interface */ rc=IDirectSoundBuffer8_GetObjectInPath(secondary8,&GUID_All_Objects,0,&GUID_NULL,(void**)&obj); ok(rc==E_NOINTERFACE||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() " "should have returned E_NOINTERFACE, returned: %08x\n",rc); /* Call GetObjectInPath for unloaded DMO */ rc=IDirectSoundBuffer8_GetObjectInPath(secondary8,&GUID_NULL,0,&IID_IMediaObject,(void**)&obj); ok(rc==DSERR_OBJECTNOTFOUND||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() " "should have returned DSERR_OBJECTNOTFOUND, returned: %08x\n",rc); /* Call GetObjectInPath for first DMO */ obj=NULL; rc=IDirectSoundBuffer8_GetObjectInPath(secondary8,&GUID_All_Objects,0,&IID_IMediaObject,(void**)&obj); if (rc2==DS_OK) { ok(rc==DS_OK||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() " "should have returned DS_OK, returned: %08x\n",rc); if (obj) IUnknown_Release(obj); } else { ok(rc==DSERR_OBJECTNOTFOUND||rc==DSERR_CONTROLUNAVAIL,"IDirectSoundBuffer8_GetObjectInPath() " "should have returned DSERR_OBJECTNOTFOUND, returned: %08x\n",rc); } /* Call SetFX with one real filter and one fake one */ rc=IDirectSoundBuffer8_SetFX(secondary8,2,effects,resultcodes); ok(rc==REGDB_E_CLASSNOTREG||rc==DSERR_CONTROLUNAVAIL, "IDirectSoundBuffer8_SetFX(GUID_DSFX_STANDARD_ECHO, GUID_NULL) " "should have returned REGDB_E_CLASSNOTREG, returned: %08x\n",rc); if (rc!=DSERR_CONTROLUNAVAIL) { ok(resultcodes[0]==DSFXR_PRESENT||resultcodes[0]==DSFXR_UNKNOWN, "resultcodes[0] == %08x, expected DSFXR_PRESENT or DSFXR_UNKNOWN\n",resultcodes[0]); ok(resultcodes[1]==DSFXR_UNKNOWN, "resultcodes[1] == %08x, expected DSFXR_UNKNOWN\n",resultcodes[1]); } IDirectSoundBuffer8_Release(secondary8); } IDirectSoundBuffer_Release(secondary); } IDirectSoundBuffer_Release(primary); } while (IDirectSound_Release(dso)); } START_TEST(dsound8) { HMODULE hDsound; CoInitialize(NULL); hDsound = LoadLibraryA("dsound.dll"); if (hDsound) { pDirectSoundEnumerateA = (void*)GetProcAddress(hDsound, "DirectSoundEnumerateA"); pDirectSoundCreate8 = (void*)GetProcAddress(hDsound, "DirectSoundCreate8"); if (pDirectSoundCreate8) { test_COM(); IDirectSound8_tests(); dsound8_tests(); test_hw_buffers(); test_first_device(); test_effects(); } else skip("DirectSoundCreate8 missing - skipping all tests\n"); FreeLibrary(hDsound); } else skip("dsound.dll not found - skipping all tests\n"); CoUninitialize(); }