static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName) { DSoundData *pData = NULL; LPGUID guid = NULL; HRESULT hr; if(!DSoundLoad()) return ALC_FALSE; if(!deviceName) deviceName = dsDevice; else if(strcmp(deviceName, dsDevice) != 0) { ALuint i; if(!DeviceList) { hr = pDirectSoundEnumerateA(DSoundEnumDevices, NULL); if(FAILED(hr)) AL_PRINT("Error enumerating DirectSound devices (%#x)!\n", (unsigned int)hr); } for(i = 0; i < NumDevices; i++) { if(strcmp(deviceName, DeviceList[i].name) == 0) { if(i > 0) guid = &DeviceList[i].guid; break; } } if(i == NumDevices) return ALC_FALSE; } //Initialise requested device pData = calloc(1, sizeof(DSoundData)); if(!pData) { alcSetError(device, ALC_OUT_OF_MEMORY); return ALC_FALSE; } //DirectSound Init code hr = pDirectSoundCreate(guid, &pData->lpDS, NULL); if(SUCCEEDED(hr)) hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY); if(FAILED(hr)) { if(pData->lpDS) IDirectSound_Release(pData->lpDS); free(pData); AL_PRINT("Device init failed: 0x%08lx\n", hr); return ALC_FALSE; } device->szDeviceName = strdup(deviceName); device->ExtraData = pData; return ALC_TRUE; }
static ALCboolean DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName) { DSoundData *pData = NULL; LPGUID guid = NULL; HRESULT hr; if(!deviceName) deviceName = dsDevice; else if(strcmp(deviceName, dsDevice) != 0) { ALuint i; for(i = 0;i < NumDevices;i++) { if(strcmp(deviceName, DeviceList[i].name) == 0) { guid = &DeviceList[i].guid; break; } } if(i == NumDevices) return ALC_FALSE; } DSoundLoad(); if(ds_handle == NULL) return ALC_FALSE; //Initialise requested device pData = calloc(1, sizeof(DSoundData)); if(!pData) { alcSetError(ALC_OUT_OF_MEMORY); DSoundUnload(); return ALC_FALSE; } //DirectSound Init code hr = pDirectSoundCreate(guid, &pData->lpDS, NULL); if(SUCCEEDED(hr)) hr = IDirectSound_SetCooperativeLevel(pData->lpDS, GetForegroundWindow(), DSSCL_PRIORITY); if(FAILED(hr)) { if(pData->lpDS) IDirectSound_Release(pData->lpDS); free(pData); DSoundUnload(); return ALC_FALSE; } device->szDeviceName = strdup(deviceName); device->ExtraData = pData; return ALC_TRUE; }
int DirectSoundInit() { HRESULT hr; HWND hWnd; LoadDsound(); hr = pDirectSoundCreate(NULL, &lpDirectSound, NULL); if( hr != DS_OK ) return 0; hWnd = GetForegroundWindow(); // establecer el nivel de cooperacion hr = IDirectSound_SetCooperativeLevel(lpDirectSound,hWnd, DSSCL_NORMAL ); if( hr != DS_OK) return 0; return 1; }
static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext) { HRESULT rc; LPDIRECTSOUND dso=NULL; LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL; DSBUFFERDESC bufdesc; WAVEFORMATEX wfx; int ref; trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule); driver_count++; rc=pDirectSoundCreate(lpGuid,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate() failed: %08x\n",rc); if (rc!=DS_OK) { if (rc==DSERR_NODRIVER) trace(" No Driver\n"); else if (rc == DSERR_ALLOCATED) trace(" Already In Use\n"); else if (rc == E_FAIL) trace(" No Device\n"); goto EXIT; } /* We must call SetCooperativeLevel before calling CreateSoundBuffer */ /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */ rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); if (rc!=DS_OK) goto EXIT; /* Testing 3D buffers */ primary=NULL; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_LOCHARDWARE|DSBCAPS_CTRL3D; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok((rc==DS_OK&&primary!=NULL) || broken(rc==DSERR_INVALIDPARAM), "IDirectSound_CreateSoundBuffer() failed to " "create a hardware 3D primary buffer: %08x\n",rc); if(rc==DSERR_INVALIDPARAM) { skip("broken driver\n"); goto EXIT; } if (rc==DS_OK&&primary!=NULL) { ZeroMemory(&wfx, sizeof(wfx)); wfx.wFormatTag=WAVE_FORMAT_PCM; wfx.nChannels=1; wfx.wBitsPerSample=16; wfx.nSamplesPerSec=44100; wfx.nBlockAlign=wfx.nChannels*wfx.wBitsPerSample/8; wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2; bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec; bufdesc.lpwfxFormat=&wfx; trace(" Testing a secondary buffer at %dx%dx%d\n", wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels); rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok((rc==DS_OK && secondary!=NULL) || broken(rc == DSERR_CONTROLUNAVAIL), /* vmware drivers on w2k */ "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer: %08x\n",rc); if (rc==DS_OK&&secondary!=NULL) { IKsPropertySet * pPropertySet=NULL; rc=IDirectSoundBuffer_QueryInterface(secondary, &IID_IKsPropertySet, (void **)&pPropertySet); /* it's not an error for this to fail */ if(rc==DS_OK) { ULONG ulTypeSupport; trace(" Supports property sets\n"); /* it's not an error for these to fail */ rc=IKsPropertySet_QuerySupport(pPropertySet, &DSPROPSETID_VoiceManager, 0,&ulTypeSupport); if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET| KSPROPERTY_SUPPORT_SET))) trace(" DSPROPSETID_VoiceManager supported\n"); else trace(" DSPROPSETID_VoiceManager not supported\n"); rc=IKsPropertySet_QuerySupport(pPropertySet, &DSPROPSETID_EAX20_ListenerProperties,0,&ulTypeSupport); if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET| KSPROPERTY_SUPPORT_SET))) trace(" DSPROPSETID_EAX20_ListenerProperties " "supported\n"); else trace(" DSPROPSETID_EAX20_ListenerProperties not " "supported\n"); rc=IKsPropertySet_QuerySupport(pPropertySet, &DSPROPSETID_EAX20_BufferProperties,0,&ulTypeSupport); if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET| KSPROPERTY_SUPPORT_SET))) trace(" DSPROPSETID_EAX20_BufferProperties supported\n"); else trace(" DSPROPSETID_EAX20_BufferProperties not " "supported\n"); rc=IKsPropertySet_QuerySupport(pPropertySet, &DSPROPSETID_I3DL2_ListenerProperties,0,&ulTypeSupport); if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET| KSPROPERTY_SUPPORT_SET))) trace(" DSPROPSETID_I3DL2_ListenerProperties " "supported\n"); else trace(" DSPROPSETID_I3DL2_ListenerProperties not " "supported\n"); rc=IKsPropertySet_QuerySupport(pPropertySet, &DSPROPSETID_I3DL2_BufferProperties,0,&ulTypeSupport); if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET| KSPROPERTY_SUPPORT_SET))) trace(" DSPROPSETID_I3DL2_BufferProperties supported\n"); else trace(" DSPROPSETID_I3DL2_BufferProperties not " "supported\n"); rc=IKsPropertySet_QuerySupport(pPropertySet, &DSPROPSETID_ZOOMFX_BufferProperties,0,&ulTypeSupport); if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET| KSPROPERTY_SUPPORT_SET))) trace(" DSPROPSETID_ZOOMFX_BufferProperties " "supported\n"); else trace(" DSPROPSETID_ZOOMFX_BufferProperties not " "supported\n"); ref=IKsPropertySet_Release(pPropertySet); /* try a few common ones */ ok(ref==0,"IKsPropertySet_Release() secondary has %d " "references, should have 0\n",ref); } else trace(" Doesn't support property sets\n"); ref=IDirectSoundBuffer_Release(secondary); ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d " "references, should have 0\n",ref); } ref=IDirectSoundBuffer_Release(primary); ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, " "should have 0\n",ref); } EXIT: if (dso!=NULL) { ref=IDirectSound_Release(dso); ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n", ref); } return TRUE; }
static HRESULT test_frequency(LPGUID lpGuid) { HRESULT rc; LPDIRECTSOUND dso=NULL; LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL; DSBUFFERDESC bufdesc; DSCAPS dscaps; WAVEFORMATEX wfx, wfx1; DWORD f, r; int ref; int rates[] = { 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 96000 }; /* Create the DirectSound object */ rc=pDirectSoundCreate(lpGuid,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, "DirectSoundCreate() failed: %08x\n",rc); if (rc!=DS_OK) return rc; /* Get the device capabilities */ ZeroMemory(&dscaps, sizeof(dscaps)); dscaps.dwSize=sizeof(dscaps); rc=IDirectSound_GetCaps(dso,&dscaps); ok(rc==DS_OK,"IDirectSound_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=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); if (rc!=DS_OK) goto EXIT; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok(rc==DS_OK && primary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a primary buffer %08x\n",rc); if (rc==DS_OK && primary!=NULL) { rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL); ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc); if (rc!=DS_OK) goto EXIT1; for (f=0;f<sizeof(fmts)/sizeof(fmts[0]);f++) { for (r=0;r<sizeof(rates)/sizeof(rates[0]);r++) { init_format(&wfx,WAVE_FORMAT_PCM,11025,fmts[f].bits, fmts[f].channels); secondary=NULL; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRLFREQUENCY; bufdesc.dwBufferBytes=align((wfx.nAvgBytesPerSec*rates[r]/11025)* BUFFER_LEN/1000,wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx; if (winetest_interactive) { trace(" Testing a secondary buffer at %dx%dx%d " "with a primary buffer at %dx%dx%d\n", wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels, wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels); } rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc); if (rc==DS_OK && secondary!=NULL) { test_buffer(dso,&secondary,0,FALSE,0,FALSE,0, winetest_interactive,1.0,0,NULL,0,0,TRUE,rates[r]); ref=IDirectSoundBuffer_Release(secondary); ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " "should have 0\n",ref); } } } EXIT1: 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=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); EXIT: ref=IDirectSound_Release(dso); ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); if (ref!=0) return DSERR_GENERIC; return rc; }
static HRESULT test_block_align(LPGUID lpGuid) { HRESULT rc; LPDIRECTSOUND dso=NULL; LPDIRECTSOUNDBUFFER secondary=NULL; DSBUFFERDESC bufdesc; DSBCAPS dsbcaps; WAVEFORMATEX wfx; DWORD pos, pos2; int ref; /* Create the DirectSound object */ rc=pDirectSoundCreate(lpGuid,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, "DirectSoundCreate() failed: %08x\n",rc); if (rc!=DS_OK) return rc; init_format(&wfx,WAVE_FORMAT_PCM,11025,16,2); ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec + 1; bufdesc.lpwfxFormat=&wfx; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK,"IDirectSound_CreateSoundBuffer() " "should have returned DS_OK, returned: %08x\n", rc); if (rc==DS_OK && secondary!=NULL) { ZeroMemory(&dsbcaps, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); rc=IDirectSoundBuffer_GetCaps(secondary,&dsbcaps); ok(rc==DS_OK,"IDirectSoundBuffer_GetCaps() should have returned DS_OK, " "returned: %08x\n", rc); if (rc==DS_OK && wfx.nBlockAlign > 1) { ok(dsbcaps.dwBufferBytes==(wfx.nAvgBytesPerSec + wfx.nBlockAlign), "Buffer size not a multiple of nBlockAlign: requested %d, " "got %d, should be %d\n", bufdesc.dwBufferBytes, dsbcaps.dwBufferBytes, wfx.nAvgBytesPerSec + wfx.nBlockAlign); rc = IDirectSoundBuffer_SetCurrentPosition(secondary, 0); ok(rc == DS_OK, "Could not set position to 0: %08x\n", rc); rc = IDirectSoundBuffer_GetCurrentPosition(secondary, &pos, NULL); ok(rc == DS_OK, "Could not get position: %08x\n", rc); rc = IDirectSoundBuffer_SetCurrentPosition(secondary, 1); ok(rc == DS_OK, "Could not set position to 1: %08x\n", rc); rc = IDirectSoundBuffer_GetCurrentPosition(secondary, &pos2, NULL); ok(rc == DS_OK, "Could not get new position: %08x\n", rc); ok(pos == pos2, "Positions not the same! Old position: %d, new position: %d\n", pos, pos2); } ref=IDirectSoundBuffer_Release(secondary); ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d references, " "should have 0\n",ref); } ref=IDirectSound_Release(dso); ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); if (ref!=0) return DSERR_GENERIC; return rc; }
static HRESULT test_secondary(LPGUID lpGuid) { HRESULT rc; LPDIRECTSOUND dso=NULL; LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL; DSBUFFERDESC bufdesc; DSCAPS dscaps; WAVEFORMATEX wfx, wfx1; DWORD f; int ref; /* Create the DirectSound object */ rc=pDirectSoundCreate(lpGuid,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, "DirectSoundCreate() failed: %08x\n",rc); if (rc!=DS_OK) return rc; /* Get the device capabilities */ ZeroMemory(&dscaps, sizeof(dscaps)); dscaps.dwSize=sizeof(dscaps); rc=IDirectSound_GetCaps(dso,&dscaps); ok(rc==DS_OK,"IDirectSound_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=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); if (rc!=DS_OK) goto EXIT; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok(rc==DS_OK && primary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a primary buffer %08x\n",rc); if (rc==DS_OK && primary!=NULL) { rc=IDirectSoundBuffer_GetFormat(primary,&wfx1,sizeof(wfx1),NULL); ok(rc==DS_OK,"IDirectSoundBuffer8_Getformat() failed: %08x\n", rc); if (rc!=DS_OK) goto EXIT1; for (f=0;f<NB_FORMATS;f++) { WAVEFORMATEXTENSIBLE wfxe; init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1], formats[f][2]); secondary=NULL; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, wfx.nBlockAlign); rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DSERR_INVALIDPARAM,"IDirectSound_CreateSoundBuffer() " "should have returned DSERR_INVALIDPARAM, returned: %08x\n", rc); if (rc==DS_OK && secondary!=NULL) IDirectSoundBuffer_Release(secondary); secondary=NULL; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); if (gotdx8 || wfx.wBitsPerSample <= 16) { if (wfx.wBitsPerSample > 16) ok(((rc == DSERR_CONTROLUNAVAIL || rc == DSERR_INVALIDCALL || rc == DSERR_INVALIDPARAM /* 2003 */) && !secondary) || rc == DS_OK, /* driver dependent? */ "IDirectSound_CreateSoundBuffer() " "should have returned (DSERR_CONTROLUNAVAIL or DSERR_INVALIDCALL) " "and NULL, returned: %08x %p\n", rc, secondary); else ok(rc==DS_OK && secondary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc); } else ok(rc==E_INVALIDARG, "Creating %d bpp buffer on dx < 8 returned: %p %08x\n", wfx.wBitsPerSample, secondary, rc); if (!gotdx8) { skip("Not doing the WAVE_FORMAT_EXTENSIBLE tests\n"); /* Apparently they succeed with bogus values, * which means that older dsound doesn't look at them */ goto no_wfe; } if (secondary) IDirectSoundBuffer_Release(secondary); secondary = NULL; bufdesc.lpwfxFormat=(WAVEFORMATEX*)&wfxe; wfxe.Format = wfx; wfxe.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; wfxe.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; wfxe.Format.cbSize = 1; wfxe.Samples.wValidBitsPerSample = wfx.wBitsPerSample; wfxe.dwChannelMask = (wfx.nChannels == 1 ? KSAUDIO_SPEAKER_MONO : KSAUDIO_SPEAKER_STEREO); rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok((rc==DSERR_INVALIDPARAM || rc==DSERR_INVALIDCALL /* 2003 */) && !secondary, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) { IDirectSoundBuffer_Release(secondary); secondary=NULL; } wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx) + 1; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(((rc==DSERR_CONTROLUNAVAIL || rc==DSERR_INVALIDCALL || rc==DSERR_INVALIDPARAM) && !secondary) || rc==DS_OK, /* 2003 / 2008 */ "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) { IDirectSoundBuffer_Release(secondary); secondary=NULL; } wfxe.Format.cbSize = sizeof(wfxe) - sizeof(wfx); wfxe.SubFormat = GUID_NULL; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok((rc==DSERR_INVALIDPARAM || rc==DSERR_INVALIDCALL) && !secondary, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) { IDirectSoundBuffer_Release(secondary); secondary=NULL; } wfxe.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; ++wfxe.Samples.wValidBitsPerSample; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DSERR_INVALIDPARAM && !secondary, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) { IDirectSoundBuffer_Release(secondary); secondary=NULL; } --wfxe.Samples.wValidBitsPerSample; wfxe.Samples.wValidBitsPerSample = 0; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary, "IDirectSound_CreateSoundBuffer() returned: %08x %p\n", rc, secondary); if (secondary) { IDirectSoundBuffer_Release(secondary); secondary=NULL; } wfxe.Samples.wValidBitsPerSample = wfxe.Format.wBitsPerSample; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc); no_wfe: if (rc==DS_OK && secondary!=NULL) { if (winetest_interactive) { trace(" Testing a secondary buffer at %dx%dx%d " "with a primary buffer at %dx%dx%d\n", wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels, wfx1.nSamplesPerSec,wfx1.wBitsPerSample,wfx1.nChannels); } test_buffer(dso,&secondary,0,FALSE,0,FALSE,0, winetest_interactive,1.0,0,NULL,0,0,FALSE,0); ref=IDirectSoundBuffer_Release(secondary); ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " "should have 0\n",ref); } } EXIT1: 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=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); EXIT: ref=IDirectSound_Release(dso); ok(ref==0,"IDirectSound_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_secondary(LPGUID lpGuid) { HRESULT rc; LPDIRECTSOUND dso=NULL; LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL; DSBUFFERDESC bufdesc; DSCAPS dscaps; WAVEFORMATEX wfx, wfx2; int f,ref; /* Create the DirectSound object */ rc=pDirectSoundCreate(lpGuid,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, "DirectSoundCreate() failed: %08x\n",rc); if (rc!=DS_OK) return rc; /* Get the device capabilities */ ZeroMemory(&dscaps, sizeof(dscaps)); dscaps.dwSize=sizeof(dscaps); rc=IDirectSound_GetCaps(dso,&dscaps); ok(rc==DS_OK,"IDirectSound_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=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); if (rc!=DS_OK) goto EXIT; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok(rc==DS_OK && primary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a primary buffer %08x\n",rc); if (rc==DS_OK && primary!=NULL) { for (f=0;f<NB_FORMATS;f++) { /* We must call SetCooperativeLevel to be allowed to call * SetFormat */ /* DSOUND: Setting DirectSound cooperative level to * DSSCL_PRIORITY */ rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); if (rc!=DS_OK) goto EXIT; init_format(&wfx,WAVE_FORMAT_PCM,formats[f][0],formats[f][1], formats[f][2]); wfx2=wfx; rc=IDirectSoundBuffer_SetFormat(primary,&wfx); if (wfx.wBitsPerSample <= 16) ok(rc==DS_OK,"IDirectSoundBuffer_SetFormat(%s) failed: %08x\n", format_string(&wfx), rc); else ok(rc==DS_OK || rc == E_INVALIDARG, "SetFormat (%s) failed: %08x\n", format_string(&wfx), rc); /* There is no guarantee that SetFormat will actually change the * format to what we asked for. It depends on what the soundcard * supports. So we must re-query the format. */ rc=IDirectSoundBuffer_GetFormat(primary,&wfx,sizeof(wfx),NULL); ok(rc==DS_OK,"IDirectSoundBuffer_GetFormat() failed: %08x\n", rc); if (rc==DS_OK && (wfx.wFormatTag!=wfx2.wFormatTag || wfx.nSamplesPerSec!=wfx2.nSamplesPerSec || wfx.wBitsPerSample!=wfx2.wBitsPerSample || wfx.nChannels!=wfx2.nChannels)) { trace("Requested primary format tag=0x%04x %dx%dx%d " "avg.B/s=%d align=%d\n", wfx2.wFormatTag,wfx2.nSamplesPerSec,wfx2.wBitsPerSample, wfx2.nChannels,wfx2.nAvgBytesPerSec,wfx2.nBlockAlign); trace("Got tag=0x%04x %dx%dx%d avg.B/s=%d align=%d\n", wfx.wFormatTag,wfx.nSamplesPerSec,wfx.wBitsPerSample, wfx.nChannels,wfx.nAvgBytesPerSec,wfx.nBlockAlign); } /* Set the CooperativeLevel back to normal */ /* DSOUND: Setting DirectSound cooperative level to DSSCL_NORMAL */ rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); init_format(&wfx2,WAVE_FORMAT_PCM,11025,16,2); secondary=NULL; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_GETCURRENTPOSITION2; bufdesc.dwBufferBytes=align(wfx.nAvgBytesPerSec*BUFFER_LEN/1000, wfx.nBlockAlign); bufdesc.lpwfxFormat=&wfx2; if (winetest_interactive) { trace(" Testing a primary buffer at %dx%dx%d with a " "secondary buffer at %dx%dx%d\n", wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels, wfx2.nSamplesPerSec,wfx2.wBitsPerSample,wfx2.nChannels); } rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer %08x\n",rc); if (rc==DS_OK && secondary!=NULL) { test_buffer(dso,&secondary,0,FALSE,0,FALSE,0, winetest_interactive,1.0,0,NULL,0,0,FALSE,0); ref=IDirectSoundBuffer_Release(secondary); ok(ref==0,"IDirectSoundBuffer_Release() has %d references, " "should have 0\n",ref); } } 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=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); EXIT: ref=IDirectSound_Release(dso); ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); if (ref!=0) return DSERR_GENERIC; return rc; }
static HRESULT test_primary(LPGUID lpGuid) { HRESULT rc; LPDIRECTSOUND dso=NULL; LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL; DSBUFFERDESC bufdesc; DSCAPS dscaps; WAVEFORMATEX wfx; int ref; /* Create the DirectSound object */ rc=pDirectSoundCreate(lpGuid,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED, "DirectSoundCreate() failed: %08x\n",rc); if (rc!=DS_OK) return rc; /* Get the device capabilities */ ZeroMemory(&dscaps, sizeof(dscaps)); dscaps.dwSize=sizeof(dscaps); rc=IDirectSound_GetCaps(dso,&dscaps); ok(rc==DS_OK,"IDirectSound_GetCaps() failed: %08x\n",rc); if (rc!=DS_OK) goto EXIT; /* DSOUND: Error: Invalid buffer description pointer */ rc=IDirectSound_CreateSoundBuffer(dso,0,0,NULL); ok(rc==DSERR_INVALIDPARAM, "IDirectSound_CreateSoundBuffer() should have failed: %08x\n", rc); /* DSOUND: Error: NULL pointer is invalid */ /* DSOUND: Error: Invalid buffer description pointer */ rc=IDirectSound_CreateSoundBuffer(dso,0,&primary,NULL); ok(rc==DSERR_INVALIDPARAM && primary==0, "IDirectSound_CreateSoundBuffer() should have failed: rc=%08x," "dsbo=%p\n",rc,primary); /* DSOUND: Error: Invalid size */ /* DSOUND: Error: Invalid buffer description */ primary=NULL; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc)-1; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok(rc==DSERR_INVALIDPARAM && primary==0, "IDirectSound_CreateSoundBuffer() should have failed: rc=%08x," "primary=%p\n",rc,primary); /* DSOUND: Error: DSBCAPS_PRIMARYBUFFER flag with non-NULL lpwfxFormat */ /* DSOUND: Error: Invalid buffer description pointer */ primary=NULL; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER; bufdesc.lpwfxFormat=&wfx; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok(rc==DSERR_INVALIDPARAM && primary==0, "IDirectSound_CreateSoundBuffer() should have failed: rc=%08x," "primary=%p\n",rc,primary); /* DSOUND: Error: No DSBCAPS_PRIMARYBUFFER flag with NULL lpwfxFormat */ /* DSOUND: Error: Invalid buffer description pointer */ primary=NULL; ZeroMemory(&bufdesc, sizeof(bufdesc)); bufdesc.dwSize=sizeof(bufdesc); bufdesc.dwFlags=0; bufdesc.lpwfxFormat=NULL; rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok(rc==DSERR_INVALIDPARAM && primary==0, "IDirectSound_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=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY); ok(rc==DS_OK,"IDirectSound_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=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok(rc==DSERR_INVALIDPARAM,"IDirectSound_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=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL); ok((rc==DS_OK && primary!=NULL) || (rc==DSERR_CONTROLUNAVAIL), "IDirectSound_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=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&second,NULL); ok(rc==DS_OK && second==primary, "IDirectSound_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=IDirectSound_DuplicateSoundBuffer(dso,primary,&third); /* rc=0x88780032 */ ok(rc!=DS_OK,"IDirectSound_DuplicateSoundBuffer() primary buffer " "should have failed %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_buffer(dso,&primary,1,FALSE,0,FALSE,0,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),5.0,0,0,0,0,FALSE,0); 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=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_NORMAL); ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n", rc); EXIT: ref=IDirectSound_Release(dso); ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",ref); if (ref!=0) return DSERR_GENERIC; return rc; }
static HRESULT test_dsound(LPGUID lpGuid) { HRESULT rc; LPDIRECTSOUND dso=NULL; int ref; /* DSOUND: Error: Invalid interface buffer */ rc=pDirectSoundCreate(lpGuid,0,NULL); ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate() should have returned " "DSERR_INVALIDPARAM, returned: %08x\n",rc); /* Create the DirectSound object */ rc=pDirectSoundCreate(lpGuid,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate() failed: %08x\n",rc); if (rc!=DS_OK) return rc; /* Try the enumerated device */ IDirectSound_test(dso, TRUE, lpGuid); /* Try the COM class factory method of creation with enumerated device */ rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void**)&dso); ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc); if (dso) IDirectSound_test(dso, FALSE, lpGuid); /* Create a DirectSound object */ rc=pDirectSoundCreate(lpGuid,&dso,NULL); ok(rc==DS_OK,"DirectSoundCreate() failed: %08x\n",rc); if (rc==DS_OK) { LPDIRECTSOUND dso1=NULL; /* Create a second DirectSound object */ rc=pDirectSoundCreate(lpGuid,&dso1,NULL); ok(rc==DS_OK,"DirectSoundCreate() failed: %08x\n",rc); if (rc==DS_OK) { /* Release the second DirectSound object */ ref=IDirectSound_Release(dso1); ok(ref==0,"IDirectSound_Release() has %d references, should have " "0\n",ref); ok(dso!=dso1,"DirectSound objects should be unique: dso=%p,dso1=%p\n",dso,dso1); } /* Release the first DirectSound object */ ref=IDirectSound_Release(dso); ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n", ref); if (ref!=0) return DSERR_GENERIC; } else return rc; /* Create a DirectSound object */ rc=pDirectSoundCreate(lpGuid,&dso,NULL); ok(rc==DS_OK,"DirectSoundCreate() 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=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL); ok(rc==DS_OK && secondary!=NULL, "IDirectSound_CreateSoundBuffer() failed to create a secondary " "buffer %08x\n",rc); if (rc==DS_OK && secondary!=NULL) { LPDIRECTSOUND3DBUFFER buffer3d; rc=IDirectSound_QueryInterface(secondary, &IID_IDirectSound3DBuffer, (void **)&buffer3d); ok(rc==DS_OK && buffer3d!=NULL,"IDirectSound_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); } ref=IDirectSoundBuffer_AddRef(secondary); ok(ref==2,"IDirectSoundBuffer_AddRef() has %d references, " "should have 2\n",ref); } /* release with buffer */ ref=IDirectSound_Release(dso); ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n", ref); if (ref!=0) return DSERR_GENERIC; } else return rc; return DS_OK; }
static void IDirectSound_tests(void) { HRESULT rc; LPDIRECTSOUND dso=NULL; LPCLASSFACTORY cf=NULL; trace("Testing IDirectSound\n"); rc=CoGetClassObject(&CLSID_DirectSound, CLSCTX_INPROC_SERVER, NULL, &IID_IClassFactory, (void**)&cf); ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSound, IID_IClassFactory) " "failed: %08x\n", rc); rc=CoGetClassObject(&CLSID_DirectSound, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&cf); ok(rc==S_OK,"CoGetClassObject(CLSID_DirectSound, IID_IUnknown) " "failed: %08x\n", rc); /* try the COM class factory method of creation with no device specified */ rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void**)&dso); ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc); if (dso) IDirectSound_test(dso, FALSE, NULL); /* try the COM class factory method of creation with default playback * device specified */ rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void**)&dso); ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc); if (dso) IDirectSound_test(dso, FALSE, &DSDEVID_DefaultPlayback); /* try the COM class factory method of creation with default voice * playback device specified */ rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void**)&dso); ok(rc==S_OK,"CoCreateInstance(CLSID_DirectSound) failed: %08x\n", rc); if (dso) IDirectSound_test(dso, FALSE, &DSDEVID_DefaultVoicePlayback); /* try the COM class factory method of creation with a bad * IID specified */ rc=CoCreateInstance(&CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER, &CLSID_DirectSoundPrivate, (void**)&dso); ok(rc==E_NOINTERFACE, "CoCreateInstance(CLSID_DirectSound,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_IDirectSound, (void**)&dso); ok(rc==REGDB_E_CLASSNOTREG, "CoCreateInstance(CLSID_DirectSoundPrivate,IID_IDirectSound) " "should have failed: %08x\n",rc); /* try with no device specified */ rc=pDirectSoundCreate(NULL,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate(NULL) failed: %08x\n",rc); if (rc==S_OK && dso) IDirectSound_test(dso, TRUE, NULL); /* try with default playback device specified */ rc=pDirectSoundCreate(&DSDEVID_DefaultPlayback,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate(DSDEVID_DefaultPlayback) failed: %08x\n", rc); if (rc==DS_OK && dso) IDirectSound_test(dso, TRUE, NULL); /* try with default voice playback device specified */ rc=pDirectSoundCreate(&DSDEVID_DefaultVoicePlayback,&dso,NULL); ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL, "DirectSoundCreate(DSDEVID_DefaultVoicePlayback) failed: %08x\n", rc); if (rc==DS_OK && dso) IDirectSound_test(dso, TRUE, NULL); /* try with a bad device specified */ rc=pDirectSoundCreate(&DSDEVID_DefaultVoiceCapture,&dso,NULL); ok(rc==DSERR_NODRIVER,"DirectSoundCreate(DSDEVID_DefaultVoiceCapture) " "should have failed: %08x\n",rc); if (rc==DS_OK && dso) IDirectSound_Release(dso); }
/* ================== SndSys_InitDirectSound DirectSound 5 support ================== */ static sndinitstat SndSys_InitDirectSound (const snd_format_t* requested) { DSBUFFERDESC dsbuf; DSBCAPS dsbcaps; DWORD dwSize; DSCAPS dscaps; WAVEFORMATEXTENSIBLE format, pformat; HRESULT hresult; int reps; if (! SndSys_BuildWaveFormat(requested, &format)) return SIS_FAILURE; if (!hInstDS) { hInstDS = LoadLibrary("dsound.dll"); if (hInstDS == NULL) { Con_Print("Couldn't load dsound.dll\n"); return SIS_FAILURE; } pDirectSoundCreate = (HRESULT (__stdcall *)(GUID *, LPDIRECTSOUND *,IUnknown *))GetProcAddress(hInstDS,"DirectSoundCreate"); if (!pDirectSoundCreate) { Con_Print("Couldn't get DS proc addr\n"); return SIS_FAILURE; } } while ((hresult = pDirectSoundCreate(NULL, &pDS, NULL)) != DS_OK) { if (hresult != DSERR_ALLOCATED) { Con_Print("DirectSound create failed\n"); return SIS_FAILURE; } if (MessageBox (NULL, "The sound hardware is in use by another app.\n\n" "Select Retry to try to start sound again or Cancel to run Quake with no sound.", "Sound not available", MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION) != IDRETRY) { Con_Print("DirectSoundCreate failure\n hardware already in use\n"); return SIS_NOTAVAIL; } } dscaps.dwSize = sizeof(dscaps); if (DS_OK != IDirectSound_GetCaps (pDS, &dscaps)) { Con_Print("Couldn't get DS caps\n"); } if (dscaps.dwFlags & DSCAPS_EMULDRIVER) { Con_Print("No DirectSound driver installed\n"); SndSys_Shutdown (); return SIS_FAILURE; } if (DS_OK != IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_EXCLUSIVE)) { Con_Print("Set coop level failed\n"); SndSys_Shutdown (); return SIS_FAILURE; } // get access to the primary buffer, if possible, so we can set the // sound hardware format memset (&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER; dsbuf.dwBufferBytes = 0; dsbuf.lpwfxFormat = NULL; memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); primary_format_set = false; // COMMANDLINEOPTION: Windows DirectSound: -snoforceformat uses the format that DirectSound returns, rather than forcing it if (!COM_CheckParm ("-snoforceformat")) { if (DS_OK == IDirectSound_CreateSoundBuffer(pDS, &dsbuf, &pDSPBuf, NULL)) { pformat = format; if (DS_OK != IDirectSoundBuffer_SetFormat (pDSPBuf, (WAVEFORMATEX*)&pformat)) { Con_Print("Set primary sound buffer format: no\n"); } else { Con_Print("Set primary sound buffer format: yes\n"); primary_format_set = true; } } } // COMMANDLINEOPTION: Windows DirectSound: -primarysound locks the sound hardware for exclusive use if (!primary_format_set || !COM_CheckParm ("-primarysound")) { HRESULT result; // create the secondary buffer we'll actually work with memset (&dsbuf, 0, sizeof(dsbuf)); dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_LOCSOFTWARE; dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE(requested); dsbuf.lpwfxFormat = (WAVEFORMATEX*)&format; memset(&dsbcaps, 0, sizeof(dsbcaps)); dsbcaps.dwSize = sizeof(dsbcaps); result = IDirectSound_CreateSoundBuffer(pDS, &dsbuf, &pDSBuf, NULL); if (result != DS_OK || requested->channels != format.Format.nChannels || requested->width != format.Format.wBitsPerSample / 8 || requested->speed != format.Format.nSamplesPerSec) { Con_Printf("DS:CreateSoundBuffer Failed (%d): channels=%u, width=%u, speed=%u\n", (int)result, (unsigned)format.Format.nChannels, (unsigned)format.Format.wBitsPerSample / 8, (unsigned)format.Format.nSamplesPerSec); SndSys_Shutdown (); return SIS_FAILURE; } if (DS_OK != IDirectSoundBuffer_GetCaps (pDSBuf, &dsbcaps)) { Con_Print("DS:GetCaps failed\n"); SndSys_Shutdown (); return SIS_FAILURE; } Con_Print("Using secondary sound buffer\n"); } else { if (DS_OK != IDirectSound_SetCooperativeLevel (pDS, mainwindow, DSSCL_WRITEPRIMARY)) { Con_Print("Set coop level failed\n"); SndSys_Shutdown (); return SIS_FAILURE; } if (DS_OK != IDirectSoundBuffer_GetCaps (pDSPBuf, &dsbcaps)) { Con_Print("DS:GetCaps failed\n"); return SIS_FAILURE; } pDSBuf = pDSPBuf; Con_Print("Using primary sound buffer\n"); } // Make sure mixer is active IDirectSoundBuffer_Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); Con_Printf(" %d channel(s)\n" " %d bits/sample\n" " %d samples/sec\n", requested->channels, requested->width * 8, requested->speed); gSndBufSize = dsbcaps.dwBufferBytes; // initialize the buffer reps = 0; while ((hresult = IDirectSoundBuffer_Lock(pDSBuf, 0, gSndBufSize, (LPVOID*)&lpData, &dwSize, NULL, NULL, 0)) != DS_OK) { if (hresult != DSERR_BUFFERLOST) { Con_Print("SNDDMA_InitDirect: DS::Lock Sound Buffer Failed\n"); SndSys_Shutdown (); return SIS_FAILURE; } if (++reps > 10000) { Con_Print("SNDDMA_InitDirect: DS: couldn't restore buffer\n"); SndSys_Shutdown (); return SIS_FAILURE; } } memset(lpData, 0, dwSize); IDirectSoundBuffer_Unlock(pDSBuf, lpData, dwSize, NULL, 0); IDirectSoundBuffer_Stop(pDSBuf); IDirectSoundBuffer_Play(pDSBuf, 0, 0, DSBPLAY_LOOPING); dwStartTime = 0; dsound_time = 0; snd_renderbuffer = Snd_CreateRingBuffer(requested, gSndBufSize / (requested->width * requested->channels), lpData); dsound_init = true; return SIS_SUCCESS; }
soundplay_t *SND_InitPlayback(int speed, int bits) { int ret; DSBCAPS caps; DSBUFFERDESC bufdesc; LPDIRECTSOUND ds; dsplay_t *hnd; WAVEFORMATEX format; if (!hInstDS) { hInstDS = LoadLibrary("dsound.dll"); if (hInstDS == NULL) { printf ("Couldn't load dsound.dll\n"); return NULL; } pDirectSoundCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCreate"); if (!pDirectSoundCreate) { printf ("Couldn't get DS proc addr\n"); return NULL; } // pDirectSoundEnumerate = (void *)GetProcAddress(hInstDS,"DirectSoundEnumerateA"); } ds = NULL; pDirectSoundCreate(NULL, &ds, NULL); if (!ds) return NULL; hnd = malloc(sizeof(*hnd)); memset(hnd, 0, sizeof(*hnd)); hnd->funcs.update = DSOUND_UpdatePlayback; hnd->funcs.close = DSOUND_Shutdown; hnd->ds = ds; hnd->sampbytes = bits/8; if (FAILED(IDirectSound_SetCooperativeLevel (hnd->ds, GetDesktopWindow(), DSSCL_EXCLUSIVE))) printf("SetCooperativeLevel failed\n"); memset(&bufdesc, 0, sizeof(bufdesc)); bufdesc.dwSize = sizeof(bufdesc); // bufdesc.dwFlags |= DSBCAPS_GLOBALFOCUS; //so we hear it if quake is loaded bufdesc.dwFlags |= DSBCAPS_PRIMARYBUFFER; //so we can set speed bufdesc.dwFlags |= DSBCAPS_CTRLVOLUME; bufdesc.lpwfxFormat = NULL; bufdesc.dwBufferBytes = 0; format.wFormatTag = WAVE_FORMAT_PCM; format.cbSize = 0; format.nChannels = 1; format.wBitsPerSample = bits; format.nSamplesPerSec = speed; format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; ret = IDirectSound_CreateSoundBuffer(hnd->ds, &bufdesc, &hnd->dsbuf, NULL); if (!hnd->dsbuf) { printf("Couldn't create primary buffer\n"); DSOUND_Shutdown(&hnd->funcs); return NULL; } if (FAILED(IDirectSoundBuffer_SetFormat(hnd->dsbuf, &format))) printf("SetFormat failed\n"); //and now make a secondary buffer bufdesc.dwFlags = 0; bufdesc.dwFlags |= DSBCAPS_CTRLFREQUENCY; bufdesc.dwFlags |= DSBCAPS_LOCSOFTWARE; bufdesc.dwFlags |= DSBCAPS_GLOBALFOCUS; bufdesc.dwBufferBytes = speed * format.nChannels * hnd->sampbytes; bufdesc.lpwfxFormat = &format; ret = IDirectSound_CreateSoundBuffer(hnd->ds, &bufdesc, &hnd->dsbuf, NULL); if (!hnd->dsbuf) { printf("Couldn't create secondary buffer\n"); DSOUND_Shutdown(&hnd->funcs); return NULL; } memset(&caps, 0, sizeof(caps)); caps.dwSize = sizeof(caps); IDirectSoundBuffer_GetCaps(hnd->dsbuf, &caps); hnd->buffersize = caps.dwBufferBytes / hnd->sampbytes; //clear out the buffer { char *buffer; int buffersize=0; IDirectSoundBuffer_Play(hnd->dsbuf, 0, 0, DSBPLAY_LOOPING); ret = IDirectSoundBuffer_Lock(hnd->dsbuf, 0, hnd->buffersize*hnd->sampbytes, (void**)&buffer, &buffersize, NULL, NULL, 0); memset(buffer, 0, buffersize); IDirectSoundBuffer_Unlock(hnd->dsbuf, buffer, buffersize, NULL, 0); IDirectSoundBuffer_Stop(hnd->dsbuf); } //DSERR_INVALIDPARAM IDirectSoundBuffer_Play(hnd->dsbuf, 0, 0, DSBPLAY_LOOPING); IDirectSoundBuffer_GetCurrentPosition(hnd->dsbuf, &hnd->readpos, &hnd->writepos); hnd->writepos = hnd->readpos + speed / 2; //position our write position a quater of a second infront of the read position printf("%i %i\n", 100*hnd->readpos / hnd->buffersize, 100*hnd->writepos / hnd->buffersize); return &hnd->funcs; }
/* * SNDDMA_InitDirect * * Direct-Sound support */ sndinitstat SNDDMA_InitDirect( bool verbose ) { DSCAPS dscaps; HRESULT hresult; dma.channels = 2; dma.samplebits = 16; if( s_khz->integer == 48 ) dma.speed = 48000; else if( s_khz->integer == 44 ) dma.speed = 44100; else if( s_khz->integer == 22 ) dma.speed = 22050; else dma.speed = 11025; dma.msec_per_sample = 1000.0 / dma.speed; if( verbose ) Com_Printf( "Initializing DirectSound\n" ); if( !hInstDS ) { if( verbose ) Com_Printf( "...loading dsound.dll: " ); hInstDS = LoadLibrary( "dsound.dll" ); if( hInstDS == NULL ) { if( verbose ) Com_Printf( "failed\n" ); return SIS_FAILURE; } if( verbose ) Com_Printf( "ok\n" ); pDirectSoundCreate = (void *)GetProcAddress( hInstDS, "DirectSoundCreate" ); if( !pDirectSoundCreate ) { if( verbose ) Com_Printf( "*** couldn't get DS proc addr ***\n" ); return SIS_FAILURE; } } if( verbose ) Com_Printf( "...creating DS object: " ); while( ( hresult = pDirectSoundCreate( NULL, &pDS, NULL ) ) != DS_OK ) { if( hresult != DSERR_ALLOCATED ) { if( verbose ) Com_Printf( "failed\n" ); return SIS_FAILURE; } if( MessageBox( NULL, "The sound hardware is in use by another app.\n\n" "Select Retry to try to start sound again or Cancel to run with no sound.", "Sound not available", MB_RETRYCANCEL | MB_SETFOREGROUND | MB_ICONEXCLAMATION ) != IDRETRY ) { if( verbose ) Com_Printf( "failed, hardware already in use\n" ); return SIS_NOTAVAIL; } } if( verbose ) Com_Printf( "ok\n" ); dscaps.dwSize = sizeof( dscaps ); if( DS_OK != pDS->lpVtbl->GetCaps( pDS, &dscaps ) ) { if( verbose ) Com_Printf( "*** couldn't get DS caps ***\n" ); } if( dscaps.dwFlags & DSCAPS_EMULDRIVER ) { if( verbose ) Com_Printf( "...no DSound driver found\n" ); FreeSound( verbose ); return SIS_FAILURE; } if( !DS_CreateBuffers() ) return SIS_FAILURE; dsound_init = true; if( verbose ) Com_Printf( "...completed successfully\n" ); return SIS_SUCCESS; }