Added volume and pan support to primary buffers.
Added more property set support.
This commit is contained in:
parent
6f7cbc0840
commit
99b0e8fa66
|
@ -1140,6 +1140,8 @@ HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown
|
|||
(*ippDS)->drvcaps.dwPrimaryBuffers = 1;
|
||||
}
|
||||
|
||||
(*ippDS)->volpan.lVolume = 0;
|
||||
(*ippDS)->volpan.lPan = 0;
|
||||
DSOUND_RecalcVolPan(&((*ippDS)->volpan));
|
||||
|
||||
InitializeCriticalSection(&((*ippDS)->mixlock));
|
||||
|
|
|
@ -55,14 +55,14 @@ void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan)
|
|||
TRACE("(%p)\n",volpan);
|
||||
|
||||
/* the AmpFactors are expressed in 16.16 fixed point */
|
||||
volpan->dwVolAmpFactor = (ULONG) (pow(2.0, volpan->lVolume / 600.0) * 65536);
|
||||
volpan->dwVolAmpFactor = (ULONG) (pow(2.0, volpan->lVolume / 600.0) * 0xffff);
|
||||
/* FIXME: dwPan{Left|Right}AmpFactor */
|
||||
|
||||
/* FIXME: use calculated vol and pan ampfactors */
|
||||
temp = (double) (volpan->lVolume - (volpan->lPan > 0 ? volpan->lPan : 0));
|
||||
volpan->dwTotalLeftAmpFactor = (ULONG) (pow(2.0, temp / 600.0) * 65536);
|
||||
volpan->dwTotalLeftAmpFactor = (ULONG) (pow(2.0, temp / 600.0) * 0xffff);
|
||||
temp = (double) (volpan->lVolume + (volpan->lPan < 0 ? volpan->lPan : 0));
|
||||
volpan->dwTotalRightAmpFactor = (ULONG) (pow(2.0, temp / 600.0) * 65536);
|
||||
volpan->dwTotalRightAmpFactor = (ULONG) (pow(2.0, temp / 600.0) * 0xffff);
|
||||
|
||||
TRACE("left = %lx, right = %lx\n", volpan->dwTotalLeftAmpFactor, volpan->dwTotalRightAmpFactor);
|
||||
}
|
||||
|
|
|
@ -74,6 +74,8 @@ static HRESULT DSOUND_PrimaryOpen(IDirectSoundImpl *This)
|
|||
HRESULT err = DS_OK;
|
||||
TRACE("(%p)\n",This);
|
||||
|
||||
DSOUND_RecalcVolPan(&(This->volpan));
|
||||
|
||||
/* are we using waveOut stuff? */
|
||||
if (!This->hwbuf) {
|
||||
LPBYTE newbuf;
|
||||
|
@ -128,7 +130,15 @@ static HRESULT DSOUND_PrimaryOpen(IDirectSoundImpl *This)
|
|||
}
|
||||
if ((err == DS_OK) && (merr != DS_OK))
|
||||
err = merr;
|
||||
|
||||
if (!err) {
|
||||
DWORD vol = (This->volpan.dwTotalLeftAmpFactor & 0xffff) | (This->volpan.dwTotalRightAmpFactor << 16);
|
||||
err = mmErr(waveOutSetVolume(This->hwo, vol));
|
||||
}
|
||||
} else {
|
||||
err = IDsDriverBuffer_SetVolumePan(This->hwbuf, &(This->volpan));
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -431,7 +441,6 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume(
|
|||
|
||||
TRACE("(%p,%ld)\n",This,vol);
|
||||
|
||||
/* I'm not sure if we need this for primary buffer */
|
||||
if (!(This->dsound->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
|
||||
WARN("control unavailable\n");
|
||||
return DSERR_CONTROLUNAVAIL;
|
||||
|
@ -458,15 +467,9 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume(
|
|||
WARN("IDsDriverBuffer_SetVolumePan failed\n");
|
||||
return hres;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if 0 /* should we really do this? */
|
||||
/* the DS volume ranges from 0 (max, 0dB attenuation) to -10000 (min, 100dB attenuation) */
|
||||
/* the MM volume ranges from 0 to 0xffff in an unspecified logarithmic scale */
|
||||
WORD cvol = 0xffff + vol*6 + vol/2;
|
||||
DWORD vol = cvol | ((DWORD)cvol << 16)
|
||||
} else {
|
||||
DWORD vol = (dsound->volpan.dwTotalLeftAmpFactor & 0xffff) | (dsound->volpan.dwTotalRightAmpFactor << 16);
|
||||
waveOutSetVolume(dsound->hwo, vol);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -778,13 +781,8 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan(
|
|||
}
|
||||
}
|
||||
else {
|
||||
#if 0 /* should we really do this? */
|
||||
/* the DS volume ranges from 0 (max, 0dB attenuation) to -10000 (min, 100dB attenuation) */
|
||||
/* the MM volume ranges from 0 to 0xffff in an unspecified logarithmic scale */
|
||||
WORD cvol = 0xffff + vol*6 + vol/2;
|
||||
DWORD vol = cvol | ((DWORD)cvol << 16)
|
||||
DWORD vol = (dsound->volpan.dwTotalLeftAmpFactor & 0xffff) | (dsound->volpan.dwTotalRightAmpFactor << 16);
|
||||
waveOutSetVolume(dsound->hwo, vol);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -431,8 +431,47 @@ static HRESULT WINAPI DSPROPERTY_Description1(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
FIXME("DeviceId=Unknown\n");
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
BOOL found = FALSE;
|
||||
ULONG wod;
|
||||
int wodn;
|
||||
/* given specific device so try the render devices first */
|
||||
wodn = waveOutGetNumDevs();
|
||||
for (wod = 0; wod < wodn; wod++) {
|
||||
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
|
||||
if (err == DS_OK) {
|
||||
if (IsEqualGUID( &ppd->DeviceId, &guid) ) {
|
||||
DSDRIVERDESC desc;
|
||||
TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
|
||||
ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
|
||||
ppd->WaveDeviceId = wod;
|
||||
ppd->Devnode = wod;
|
||||
err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
|
||||
if (err == DS_OK) {
|
||||
PIDSDRIVER drv = NULL;
|
||||
strncpy(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA) - 1);
|
||||
strncpy(ppd->ModuleA, desc.szDrvName, sizeof(ppd->ModuleA) - 1);
|
||||
MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
|
||||
MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
|
||||
err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
|
||||
if (err == DS_OK && drv)
|
||||
ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
|
||||
found = TRUE;
|
||||
break;
|
||||
} else {
|
||||
WARN("waveOutMessage failed\n");
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WARN("waveOutMessage failed\n");
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (found == FALSE) {
|
||||
WARN("device not found\n");
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (pcbReturned) {
|
||||
|
|
|
@ -254,7 +254,8 @@ STOP:
|
|||
}
|
||||
|
||||
static void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
|
||||
int is_primary, int play, int buffer3d,
|
||||
int is_primary, BOOL set_volume, LONG volume,
|
||||
BOOL set_pan, LONG pan, int play, int buffer3d,
|
||||
LPDIRECTSOUND3DLISTENER listener,
|
||||
int move_listener, int move_sound)
|
||||
{
|
||||
|
@ -358,7 +359,7 @@ static void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
|
|||
|
||||
if (play) {
|
||||
play_state_t state;
|
||||
LONG volume,pan;
|
||||
|
||||
LPDIRECTSOUND3DBUFFER buffer=NULL;
|
||||
DS3DBUFFER buffer_param;
|
||||
DS3DLISTENER listener_param;
|
||||
|
@ -417,34 +418,50 @@ static void test_buffer(LPDIRECTSOUND dso, LPDIRECTSOUNDBUFFER dsbo,
|
|||
rc=IDirectSound3DBuffer_GetAllParameters(buffer,&buffer_param);
|
||||
ok(rc==DS_OK,"IDirectSound3DBuffer_GetAllParameters failed: 0x%lx\n",rc);
|
||||
}
|
||||
if (dsbcaps.dwFlags & DSBCAPS_CTRLVOLUME) {
|
||||
rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
|
||||
ok(rc==DS_OK,"GetVolume failed: 0x%lx\n",rc);
|
||||
|
||||
rc=IDirectSoundBuffer_SetVolume(dsbo,-300);
|
||||
if (set_volume) {
|
||||
rc=IDirectSoundBuffer_SetVolume(dsbo,volume);
|
||||
ok(rc==DS_OK,"SetVolume failed: 0x%lx\n",rc);
|
||||
|
||||
rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
|
||||
trace(" volume=%ld\n",volume);
|
||||
} else {
|
||||
/* DSOUND: Error: Buffer does not have CTRLVOLUME */
|
||||
rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
|
||||
ok(rc==DSERR_CONTROLUNAVAIL,"GetVolume should have failed: 0x%lx\n",rc);
|
||||
if (dsbcaps.dwFlags & DSBCAPS_CTRLVOLUME) {
|
||||
rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
|
||||
ok(rc==DS_OK,"GetVolume failed: 0x%lx\n",rc);
|
||||
|
||||
rc=IDirectSoundBuffer_SetVolume(dsbo,-300);
|
||||
ok(rc==DS_OK,"SetVolume failed: 0x%lx\n",rc);
|
||||
|
||||
rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
|
||||
trace(" volume=%ld\n",volume);
|
||||
} else {
|
||||
/* DSOUND: Error: Buffer does not have CTRLVOLUME */
|
||||
rc=IDirectSoundBuffer_GetVolume(dsbo,&volume);
|
||||
ok(rc==DSERR_CONTROLUNAVAIL,"GetVolume should have failed: 0x%lx\n",rc);
|
||||
}
|
||||
}
|
||||
|
||||
if (dsbcaps.dwFlags & DSBCAPS_CTRLPAN) {
|
||||
rc=IDirectSoundBuffer_GetPan(dsbo,&pan);
|
||||
ok(rc==DS_OK,"GetPan failed: 0x%lx\n",rc);
|
||||
|
||||
rc=IDirectSoundBuffer_SetPan(dsbo,0);
|
||||
if (set_pan) {
|
||||
rc=IDirectSoundBuffer_SetPan(dsbo,pan);
|
||||
ok(rc==DS_OK,"SetPan failed: 0x%lx\n",rc);
|
||||
|
||||
rc=IDirectSoundBuffer_GetPan(dsbo,&pan);
|
||||
trace(" pan=%ld\n",pan);
|
||||
} else {
|
||||
/* DSOUND: Error: Buffer does not have CTRLPAN */
|
||||
rc=IDirectSoundBuffer_GetPan(dsbo,&pan);
|
||||
ok(rc==DSERR_CONTROLUNAVAIL,"GetPan should have failed: 0x%lx\n",rc);
|
||||
if (dsbcaps.dwFlags & DSBCAPS_CTRLPAN) {
|
||||
rc=IDirectSoundBuffer_GetPan(dsbo,&pan);
|
||||
ok(rc==DS_OK,"GetPan failed: 0x%lx\n",rc);
|
||||
|
||||
rc=IDirectSoundBuffer_SetPan(dsbo,0);
|
||||
ok(rc==DS_OK,"SetPan failed: 0x%lx\n",rc);
|
||||
|
||||
rc=IDirectSoundBuffer_GetPan(dsbo,&pan);
|
||||
trace(" pan=%ld\n",pan);
|
||||
} else {
|
||||
/* DSOUND: Error: Buffer does not have CTRLPAN */
|
||||
rc=IDirectSoundBuffer_GetPan(dsbo,&pan);
|
||||
ok(rc==DSERR_CONTROLUNAVAIL,"GetPan should have failed: 0x%lx\n",rc);
|
||||
}
|
||||
}
|
||||
|
||||
state.wave=wave_generate_la(&wfx,((double)TONE_DURATION)/1000,&state.wave_len);
|
||||
|
@ -639,7 +656,7 @@ static HRESULT test_secondary(LPGUID lpGuid, int play,
|
|||
}
|
||||
|
||||
if (rc==DS_OK&&secondary!=NULL) {
|
||||
test_buffer(dso,secondary,0,winetest_interactive,has_3dbuffer,listener,move_listener,move_sound);
|
||||
test_buffer(dso,secondary,0,FALSE,0,FALSE,0,winetest_interactive,has_3dbuffer,listener,move_listener,move_sound);
|
||||
ref=IDirectSoundBuffer_Release(secondary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release %s has %d references, should have 0\n",has_duplicate?"duplicated":"secondary",ref);
|
||||
}
|
||||
|
@ -768,7 +785,7 @@ static HRESULT test_primary(LPGUID lpGuid)
|
|||
LPDIRECTSOUNDBUFFER primary=NULL,second=NULL,third=NULL;
|
||||
DSBUFFERDESC bufdesc;
|
||||
DSCAPS dscaps;
|
||||
int ref;
|
||||
int ref, i;
|
||||
|
||||
/* Create the DirectSound object */
|
||||
rc=DirectSoundCreate(lpGuid,&dso,NULL);
|
||||
|
@ -829,7 +846,22 @@ static HRESULT test_primary(LPGUID lpGuid)
|
|||
rc=IDirectSound_DuplicateSoundBuffer(dso,primary,&third);
|
||||
/* rc=0x88780032 */
|
||||
ok(rc!=DS_OK,"IDirectSound_DuplicateSoundBuffer primary buffer should have failed 0x%lx\n",rc);
|
||||
test_buffer(dso,primary,1,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,0,0,0);
|
||||
test_buffer(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,0,0,0);
|
||||
test_buffer(dso,primary,1,TRUE,0,TRUE,0,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,0,0,0);
|
||||
if (winetest_interactive) {
|
||||
LONG volume = DSBVOLUME_MAX;
|
||||
for (i = 0; i < 6; i++) {
|
||||
test_buffer(dso,primary,1,TRUE,volume,TRUE,0,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,0,0,0);
|
||||
volume -= ((DSBVOLUME_MAX-DSBVOLUME_MIN) / 40);
|
||||
}
|
||||
if (winetest_interactive) {
|
||||
LONG pan = DSBPAN_LEFT;
|
||||
for (i = 0; i < 7; i++) {
|
||||
test_buffer(dso,primary,1,TRUE,0,TRUE,pan,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,0,0,0);
|
||||
pan += ((DSBPAN_RIGHT-DSBPAN_LEFT) / 6);
|
||||
}
|
||||
}
|
||||
}
|
||||
ref=IDirectSoundBuffer_Release(primary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
|
||||
}
|
||||
|
@ -894,7 +926,7 @@ static HRESULT test_primary_3d(LPGUID lpGuid)
|
|||
rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
|
||||
ok(rc==DS_OK&&primary!=NULL,"CreateSoundBuffer failed to create a 3D primary buffer: 0x%lx\n",rc);
|
||||
if (rc==DS_OK&&primary!=NULL) {
|
||||
test_buffer(dso,primary,1,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,0,0,0);
|
||||
test_buffer(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,0,0,0);
|
||||
ref=IDirectSoundBuffer_Release(primary);
|
||||
ok(ref==0,"IDirectSoundBuffer_Release primary has %d references, should have 0\n",ref);
|
||||
}
|
||||
|
@ -971,7 +1003,7 @@ static HRESULT test_primary_3d_with_listener(LPGUID lpGuid)
|
|||
ok(ref==1,"IDirectSoundBuffer_Release has %d references, should have 1\n",ref);
|
||||
|
||||
/* Testing the buffer */
|
||||
test_buffer(dso,primary,1,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,listener,0,0);
|
||||
test_buffer(dso,primary,1,FALSE,0,FALSE,0,winetest_interactive && !(dscaps.dwFlags & DSCAPS_EMULDRIVER),0,listener,0,0);
|
||||
}
|
||||
|
||||
/* Testing the reference counting */
|
||||
|
|
|
@ -1891,7 +1891,10 @@ static DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
|
|||
right = (HIWORD(dwParam) * 100) / 0xFFFFl;
|
||||
volume = left + (right << 8);
|
||||
|
||||
if (wDevID >= numOutDev) return MMSYSERR_INVALPARAM;
|
||||
if (wDevID >= numOutDev) {
|
||||
WARN("invalid parameter: wDevID > %d\n", numOutDev);
|
||||
return MMSYSERR_INVALPARAM;
|
||||
}
|
||||
|
||||
if ((mixer = open(WOutDev[wDevID].ossdev->mixer_name, O_WRONLY|O_NDELAY)) < 0) {
|
||||
WARN("mixer device not available !\n");
|
||||
|
@ -2138,9 +2141,17 @@ static HRESULT WINAPI IDsDriverBufferImpl_SetFrequency(PIDSDRIVERBUFFER iface, D
|
|||
|
||||
static HRESULT WINAPI IDsDriverBufferImpl_SetVolumePan(PIDSDRIVERBUFFER iface, PDSVOLUMEPAN pVolPan)
|
||||
{
|
||||
/* ICOM_THIS(IDsDriverBufferImpl,iface); */
|
||||
FIXME("(%p,%p): stub!\n",iface,pVolPan);
|
||||
/* FIXME: the dsound software mixer does this for us so don't return an error */
|
||||
DWORD vol;
|
||||
ICOM_THIS(IDsDriverBufferImpl,iface);
|
||||
TRACE("(%p,%p)\n",This,pVolPan);
|
||||
|
||||
vol = pVolPan->dwTotalLeftAmpFactor | (pVolPan->dwTotalRightAmpFactor << 16);
|
||||
|
||||
if (wodSetVolume(This->drv->wDevID, vol) != MMSYSERR_NOERROR) {
|
||||
WARN("wodSetVolume failed\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue