Commit 18aeb901 authored by Francois Gouget's avatar Francois Gouget Committed by Alexandre Julliard

Fix the volume and balance of primary buffers so it is the system's

volume and balance, like on Windows.
parent b90d590d
......@@ -922,10 +922,6 @@ HRESULT WINAPI IDirectSoundImpl_Create(
pDS->drvcaps.dwPrimaryBuffers = 1;
}
pDS->volpan.lVolume = 0;
pDS->volpan.lPan = 0;
DSOUND_RecalcVolPan(&(pDS->volpan));
InitializeCriticalSection(&(pDS->mixlock));
RtlInitializeResource(&(pDS->lock));
......
......@@ -91,7 +91,6 @@ struct IDirectSoundImpl
IDirectSoundBufferImpl** buffers;
RTL_RWLOCK lock;
CRITICAL_SECTION mixlock;
DSVOLUMEPAN volpan;
PrimaryBufferImpl* primary;
DSBUFFERDESC dsbd;
DWORD speaker_config;
......@@ -450,6 +449,7 @@ extern IClassFactoryImpl DSOUND_CAPTURE_CF;
extern IClassFactoryImpl DSOUND_FULLDUPLEX_CF;
void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan);
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan);
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb);
/* primary.c */
......
......@@ -20,6 +20,7 @@
*/
#include "config.h"
#define _GNU_SOURCE /* for round() in math.h */
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
......@@ -54,6 +55,7 @@ void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan)
double temp;
TRACE("(%p)\n",volpan);
TRACE("Vol=%ld Pan=%ld\n", volpan->lVolume, volpan->lPan);
/* the AmpFactors are expressed in 16.16 fixed point */
volpan->dwVolAmpFactor = (ULONG) (pow(2.0, volpan->lVolume / 600.0) * 0xffff);
/* FIXME: dwPan{Left|Right}AmpFactor */
......@@ -67,6 +69,39 @@ void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan)
TRACE("left = %lx, right = %lx\n", volpan->dwTotalLeftAmpFactor, volpan->dwTotalRightAmpFactor);
}
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan)
{
double left,right;
TRACE("(%p)\n",volpan);
TRACE("left=%lx, right=%lx\n",volpan->dwTotalLeftAmpFactor,volpan->dwTotalRightAmpFactor);
if (volpan->dwTotalLeftAmpFactor==0)
left=-10000;
else
left=600 * log(((double)volpan->dwTotalLeftAmpFactor) / 0xffff) / log(2);
if (volpan->dwTotalRightAmpFactor==0)
right=-10000;
else
right=600 * log(((double)volpan->dwTotalRightAmpFactor) / 0xffff) / log(2);
if (left<right)
{
volpan->lVolume=round(right);
volpan->dwVolAmpFactor=volpan->dwTotalRightAmpFactor;
}
else
{
volpan->lVolume=round(left);
volpan->dwVolAmpFactor=volpan->dwTotalLeftAmpFactor;
}
if (volpan->lVolume < -10000)
volpan->lVolume=-10000;
volpan->lPan=round(right-left);
if (volpan->lPan < -10000)
volpan->lPan=-10000;
TRACE("Vol=%ld Pan=%ld\n", volpan->lVolume, volpan->lPan);
}
void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
{
DWORD sw;
......
......@@ -74,8 +74,6 @@ 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->driver) {
LPBYTE newbuf;
......@@ -135,11 +133,6 @@ 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 {
if (!This->hwbuf) {
err = IDsDriver_CreateSoundBuffer(This->driver,&(This->wfx),
......@@ -154,7 +147,6 @@ static HRESULT DSOUND_PrimaryOpen(IDirectSoundImpl *This)
if (dsound->state == STATE_PLAYING) dsound->state = STATE_STARTING;
else if (dsound->state == STATE_STOPPING) dsound->state = STATE_STOPPED;
}
err = IDsDriverBuffer_SetVolumePan(This->hwbuf, &(This->volpan));
}
return err;
......@@ -458,7 +450,8 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume(
) {
ICOM_THIS(PrimaryBufferImpl,iface);
IDirectSoundImpl* dsound = This->dsound;
LONG oldVol;
DWORD ampfactors;
DSVOLUMEPAN volpan;
TRACE("(%p,%ld)\n",This,vol);
......@@ -475,24 +468,26 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume(
/* **** */
EnterCriticalSection(&(dsound->mixlock));
oldVol = dsound->volpan.lVolume;
dsound->volpan.lVolume = vol;
DSOUND_RecalcVolPan(&dsound->volpan);
if (vol != oldVol) {
if (dsound->hwbuf) {
HRESULT hres;
hres = IDsDriverBuffer_SetVolumePan(dsound->hwbuf, &(dsound->volpan));
if (hres != DS_OK) {
LeaveCriticalSection(&(dsound->mixlock));
WARN("IDsDriverBuffer_SetVolumePan failed\n");
return hres;
}
} else {
DWORD vol = (dsound->volpan.dwTotalLeftAmpFactor & 0xffff) | (dsound->volpan.dwTotalRightAmpFactor << 16);
waveOutSetVolume(dsound->hwo, vol);
}
}
waveOutGetVolume(dsound->hwo, &ampfactors);
volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
volpan.dwTotalRightAmpFactor=ampfactors >> 16;
DSOUND_AmpFactorToVolPan(&volpan);
if (vol != volpan.lVolume) {
volpan.lVolume=vol;
DSOUND_RecalcVolPan(&volpan);
if (dsound->hwbuf) {
HRESULT hres;
hres = IDsDriverBuffer_SetVolumePan(dsound->hwbuf, &volpan);
if (hres != DS_OK) {
LeaveCriticalSection(&(dsound->mixlock));
WARN("IDsDriverBuffer_SetVolumePan failed\n");
return hres;
}
} else {
ampfactors = (volpan.dwTotalLeftAmpFactor & 0xffff) | (volpan.dwTotalRightAmpFactor << 16);
waveOutSetVolume(dsound->hwo, ampfactors);
}
}
LeaveCriticalSection(&(dsound->mixlock));
/* **** */
......@@ -504,6 +499,8 @@ static HRESULT WINAPI PrimaryBufferImpl_GetVolume(
LPDIRECTSOUNDBUFFER8 iface,LPLONG vol
) {
ICOM_THIS(PrimaryBufferImpl,iface);
DWORD ampfactors;
DSVOLUMEPAN volpan;
TRACE("(%p,%p)\n",This,vol);
if (!(This->dsound->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
......@@ -516,7 +513,11 @@ static HRESULT WINAPI PrimaryBufferImpl_GetVolume(
return DSERR_INVALIDPARAM;
}
*vol = This->dsound->volpan.lVolume;
waveOutGetVolume(dsound->hwo, &ampfactors);
volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
volpan.dwTotalRightAmpFactor=ampfactors >> 16;
DSOUND_AmpFactorToVolPan(&volpan);
*vol = volpan.lVolume;
return DS_OK;
}
......@@ -769,7 +770,8 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan(
) {
ICOM_THIS(PrimaryBufferImpl,iface);
IDirectSoundImpl* dsound = This->dsound;
LONG oldPan;
DWORD ampfactors;
DSVOLUMEPAN volpan;
TRACE("(%p,%ld)\n",This,pan);
......@@ -786,25 +788,27 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan(
/* **** */
EnterCriticalSection(&(dsound->mixlock));
oldPan = dsound->volpan.lPan;
dsound->volpan.lPan = pan;
DSOUND_RecalcVolPan(&dsound->volpan);
if (pan != oldPan) {
if (dsound->hwbuf) {
HRESULT hres;
hres = IDsDriverBuffer_SetVolumePan(dsound->hwbuf, &(dsound->volpan));
if (hres != DS_OK) {
LeaveCriticalSection(&(dsound->mixlock));
WARN("IDsDriverBuffer_SetVolumePan failed\n");
return hres;
}
}
else {
DWORD vol = (dsound->volpan.dwTotalLeftAmpFactor & 0xffff) | (dsound->volpan.dwTotalRightAmpFactor << 16);
waveOutSetVolume(dsound->hwo, vol);
}
}
waveOutGetVolume(dsound->hwo, &ampfactors);
volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
volpan.dwTotalRightAmpFactor=ampfactors >> 16;
DSOUND_AmpFactorToVolPan(&volpan);
if (pan != volpan.lPan) {
volpan.lPan=pan;
DSOUND_RecalcVolPan(&volpan);
if (dsound->hwbuf) {
HRESULT hres;
hres = IDsDriverBuffer_SetVolumePan(dsound->hwbuf, &volpan);
if (hres != DS_OK) {
LeaveCriticalSection(&(dsound->mixlock));
WARN("IDsDriverBuffer_SetVolumePan failed\n");
return hres;
}
}
else {
ampfactors = (volpan.dwTotalLeftAmpFactor & 0xffff) | (volpan.dwTotalRightAmpFactor << 16);
waveOutSetVolume(dsound->hwo, ampfactors);
}
}
LeaveCriticalSection(&(dsound->mixlock));
/* **** */
......@@ -816,6 +820,8 @@ static HRESULT WINAPI PrimaryBufferImpl_GetPan(
LPDIRECTSOUNDBUFFER8 iface,LPLONG pan
) {
ICOM_THIS(PrimaryBufferImpl,iface);
DWORD ampfactors;
DSVOLUMEPAN volpan;
TRACE("(%p,%p)\n",This,pan);
if (!(This->dsound->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
......@@ -828,8 +834,11 @@ static HRESULT WINAPI PrimaryBufferImpl_GetPan(
return DSERR_INVALIDPARAM;
}
*pan = This->dsound->volpan.lPan;
waveOutGetVolume(dsound->hwo, &ampfactors);
volpan.dwTotalLeftAmpFactor=ampfactors & 0xffff;
volpan.dwTotalRightAmpFactor=ampfactors >> 16;
DSOUND_AmpFactorToVolPan(&volpan);
*pan = volpan.lPan;
return DS_OK;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment