dsound: Use array for channel volumes.

This commit is contained in:
Mark Harmstone 2014-12-27 21:32:24 +00:00 committed by Alexandre Julliard
parent b7a2f0879c
commit 25b13178de
3 changed files with 96 additions and 125 deletions

View File

@ -30,6 +30,8 @@
#include "wine/list.h"
#define DS_MAX_CHANNELS 2
extern int ds_hel_buflen DECLSPEC_HIDDEN;
extern int ds_snd_queue_max DECLSPEC_HIDDEN;
@ -50,8 +52,7 @@ extern const normfunc normfunctions[5] DECLSPEC_HIDDEN;
typedef struct _DSVOLUMEPAN
{
DWORD dwTotalLeftAmpFactor;
DWORD dwTotalRightAmpFactor;
DWORD dwTotalAmpFactor[DS_MAX_CHANNELS];
LONG lVolume;
LONG lPan;
} DSVOLUMEPAN,*PDSVOLUMEPAN;

View File

@ -54,11 +54,11 @@ void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan)
/* 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) * 0xffff);
volpan->dwTotalAmpFactor[0] = (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) * 0xffff);
volpan->dwTotalAmpFactor[1] = (ULONG) (pow(2.0, temp / 600.0) * 0xffff);
TRACE("left = %x, right = %x\n", volpan->dwTotalLeftAmpFactor, volpan->dwTotalRightAmpFactor);
TRACE("left = %x, right = %x\n", volpan->dwTotalAmpFactor[0], volpan->dwTotalAmpFactor[1]);
}
void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan)
@ -66,15 +66,15 @@ void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan)
double left,right;
TRACE("(%p)\n",volpan);
TRACE("left=%x, right=%x\n",volpan->dwTotalLeftAmpFactor,volpan->dwTotalRightAmpFactor);
if (volpan->dwTotalLeftAmpFactor==0)
TRACE("left=%x, right=%x\n",volpan->dwTotalAmpFactor[0],volpan->dwTotalAmpFactor[1]);
if (volpan->dwTotalAmpFactor[0]==0)
left=-10000;
else
left=600 * log(((double)volpan->dwTotalLeftAmpFactor) / 0xffff) / log(2);
if (volpan->dwTotalRightAmpFactor==0)
left=600 * log(((double)volpan->dwTotalAmpFactor[0]) / 0xffff) / log(2);
if (volpan->dwTotalAmpFactor[1]==0)
right=-10000;
else
right=600 * log(((double)volpan->dwTotalRightAmpFactor) / 0xffff) / log(2);
right=600 * log(((double)volpan->dwTotalAmpFactor[1]) / 0xffff) / log(2);
if (left<right)
volpan->lVolume=right;
else
@ -399,32 +399,30 @@ static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames)
static void DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT frames)
{
INT i;
float vLeft, vRight;
float vols[DS_MAX_CHANNELS];
UINT channels = dsb->device->pwfx->nChannels, chan;
TRACE("(%p,%d)\n",dsb,frames);
TRACE("left = %x, right = %x\n", dsb->volpan.dwTotalLeftAmpFactor,
dsb->volpan.dwTotalRightAmpFactor);
TRACE("left = %x, right = %x\n", dsb->volpan.dwTotalAmpFactor[0],
dsb->volpan.dwTotalAmpFactor[1]);
if ((!(dsb->dsbd.dwFlags & DSBCAPS_CTRLPAN) || (dsb->volpan.lPan == 0)) &&
(!(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME) || (dsb->volpan.lVolume == 0)) &&
!(dsb->dsbd.dwFlags & DSBCAPS_CTRL3D))
return; /* Nothing to do */
if (channels != 1 && channels != 2)
if (channels > DS_MAX_CHANNELS)
{
FIXME("There is no support for %u channels\n", channels);
return;
}
vLeft = dsb->volpan.dwTotalLeftAmpFactor / ((float)0xFFFF);
vRight = dsb->volpan.dwTotalRightAmpFactor / ((float)0xFFFF);
for (i = 0; i < channels; ++i)
vols[i] = dsb->volpan.dwTotalAmpFactor[i] / ((float)0xFFFF);
for(i = 0; i < frames; ++i){
for(chan = 0; chan < channels; ++chan){
if(chan == 0)
dsb->device->tmp_buffer[i * channels + chan] *= vLeft;
else
dsb->device->tmp_buffer[i * channels + chan] *= vRight;
dsb->device->tmp_buffer[i * channels + chan] *= vols[chan];
}
}
}

View File

@ -570,7 +570,8 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume(IDirectSoundBuffer *iface, LON
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
DirectSoundDevice *device = This->device;
HRESULT hr;
float lvol, rvol;
float fvol;
int i;
TRACE("(%p,%d)\n", iface, vol);
@ -587,45 +588,34 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume(IDirectSoundBuffer *iface, LON
/* **** */
EnterCriticalSection(&device->mixlock);
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
for (i = 0; i < DS_MAX_CHANNELS; i++) {
if (device->pwfx->nChannels > i){
hr = IAudioStreamVolume_GetChannelVolume(device->volume, i, &fvol);
if (FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
} else
fvol=1.0f;
device->volpan.dwTotalAmpFactor[i]=((UINT16)(fvol * (DWORD)0xFFFF));
}
if(device->pwfx->nChannels > 1){
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
}else
rvol = 1;
device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF));
device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF));
DSOUND_AmpFactorToVolPan(&device->volpan);
if (vol != device->volpan.lVolume) {
device->volpan.lVolume=vol;
DSOUND_RecalcVolPan(&device->volpan);
lvol = (float)((DWORD)(device->volpan.dwTotalLeftAmpFactor & 0xFFFF) / (float)0xFFFF);
hr = IAudioStreamVolume_SetChannelVolume(device->volume, 0, lvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("SetChannelVolume failed: %08x\n", hr);
return hr;
}
if(device->pwfx->nChannels > 1){
rvol = (float)((DWORD)(device->volpan.dwTotalRightAmpFactor & 0xFFFF) / (float)0xFFFF);
hr = IAudioStreamVolume_SetChannelVolume(device->volume, 1, rvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("SetChannelVolume failed: %08x\n", hr);
return hr;
for (i = 0; i < DS_MAX_CHANNELS; i++) {
if (device->pwfx->nChannels > i){
fvol = (float)((DWORD)(device->volpan.dwTotalAmpFactor[i] & 0xFFFF) / (float)0xFFFF);
hr = IAudioStreamVolume_SetChannelVolume(device->volume, i, fvol);
if (FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("SetChannelVolume failed: %08x\n", hr);
return hr;
}
}
}
}
@ -640,8 +630,10 @@ static HRESULT WINAPI PrimaryBufferImpl_GetVolume(IDirectSoundBuffer *iface, LON
{
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
DirectSoundDevice *device = This->device;
float lvol, rvol;
float fvol;
HRESULT hr;
int i;
TRACE("(%p,%p)\n", iface, vol);
if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
@ -656,25 +648,19 @@ static HRESULT WINAPI PrimaryBufferImpl_GetVolume(IDirectSoundBuffer *iface, LON
EnterCriticalSection(&device->mixlock);
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
for (i = 0; i < DS_MAX_CHANNELS; i++) {
if (device->pwfx->nChannels > i){
hr = IAudioStreamVolume_GetChannelVolume(device->volume, i, &fvol);
if (FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
} else
fvol = 1;
if(device->pwfx->nChannels > 1){
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
}else
rvol = 1;
device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF));
device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF));
device->volpan.dwTotalAmpFactor[i] = ((UINT16)(fvol * (DWORD)0xFFFF));
}
DSOUND_AmpFactorToVolPan(&device->volpan);
*vol = device->volpan.lVolume;
@ -950,8 +936,10 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan(IDirectSoundBuffer *iface, LONG p
{
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
DirectSoundDevice *device = This->device;
float lvol, rvol;
float fvol;
HRESULT hr;
int i;
TRACE("(%p,%d)\n", iface, pan);
if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
@ -967,46 +955,34 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan(IDirectSoundBuffer *iface, LONG p
/* **** */
EnterCriticalSection(&device->mixlock);
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
for (i = 0; i < DS_MAX_CHANNELS; i++) {
if (device->pwfx->nChannels > i){
hr = IAudioStreamVolume_GetChannelVolume(device->volume, i, &fvol);
if (FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
} else
fvol = 1;
device->volpan.dwTotalAmpFactor[i] = ((UINT16)(fvol * (DWORD)0xFFFF));
}
if(device->pwfx->nChannels > 1){
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
}else
rvol = 1;
device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF));
device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF));
DSOUND_AmpFactorToVolPan(&device->volpan);
if (pan != device->volpan.lPan) {
device->volpan.lPan=pan;
DSOUND_RecalcVolPan(&device->volpan);
lvol = (float)((DWORD)(device->volpan.dwTotalLeftAmpFactor & 0xFFFF) / (float)0xFFFF);
hr = IAudioStreamVolume_SetChannelVolume(device->volume, 0, lvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("SetChannelVolume failed: %08x\n", hr);
return hr;
}
if(device->pwfx->nChannels > 1){
rvol = (float)((DWORD)(device->volpan.dwTotalRightAmpFactor & 0xFFFF) / (float)0xFFFF);
hr = IAudioStreamVolume_SetChannelVolume(device->volume, 1, rvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("SetChannelVolume failed: %08x\n", hr);
return hr;
for (i = 0; i < DS_MAX_CHANNELS; i++) {
if (device->pwfx->nChannels > i) {
fvol = (float)((DWORD)(device->volpan.dwTotalAmpFactor[i] & 0xFFFF) / (float)0xFFFF);
hr = IAudioStreamVolume_SetChannelVolume(device->volume, i, fvol);
if (FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("SetChannelVolume failed: %08x\n", hr);
return hr;
}
}
}
}
@ -1021,8 +997,10 @@ static HRESULT WINAPI PrimaryBufferImpl_GetPan(IDirectSoundBuffer *iface, LONG *
{
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
DirectSoundDevice *device = This->device;
float lvol, rvol;
float fvol;
HRESULT hr;
int i;
TRACE("(%p,%p)\n", iface, pan);
if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
@ -1037,25 +1015,19 @@ static HRESULT WINAPI PrimaryBufferImpl_GetPan(IDirectSoundBuffer *iface, LONG *
EnterCriticalSection(&device->mixlock);
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
for (i = 0; i < DS_MAX_CHANNELS; i++) {
if (device->pwfx->nChannels > i) {
hr = IAudioStreamVolume_GetChannelVolume(device->volume, i, &fvol);
if (FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
} else
fvol = 1;
if(device->pwfx->nChannels > 1){
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol);
if(FAILED(hr)){
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
}else
rvol = 1;
device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF));
device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF));
device->volpan.dwTotalAmpFactor[i] = ((UINT16)(fvol * (DWORD)0xFFFF));
}
DSOUND_AmpFactorToVolPan(&device->volpan);
*pan = device->volpan.lPan;