Commit 25b13178 authored by Mark Harmstone's avatar Mark Harmstone Committed by Alexandre Julliard

dsound: Use array for channel volumes.

parent b7a2f087
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include "wine/list.h" #include "wine/list.h"
#define DS_MAX_CHANNELS 2
extern int ds_hel_buflen DECLSPEC_HIDDEN; extern int ds_hel_buflen DECLSPEC_HIDDEN;
extern int ds_snd_queue_max DECLSPEC_HIDDEN; extern int ds_snd_queue_max DECLSPEC_HIDDEN;
...@@ -50,8 +52,7 @@ extern const normfunc normfunctions[5] DECLSPEC_HIDDEN; ...@@ -50,8 +52,7 @@ extern const normfunc normfunctions[5] DECLSPEC_HIDDEN;
typedef struct _DSVOLUMEPAN typedef struct _DSVOLUMEPAN
{ {
DWORD dwTotalLeftAmpFactor; DWORD dwTotalAmpFactor[DS_MAX_CHANNELS];
DWORD dwTotalRightAmpFactor;
LONG lVolume; LONG lVolume;
LONG lPan; LONG lPan;
} DSVOLUMEPAN,*PDSVOLUMEPAN; } DSVOLUMEPAN,*PDSVOLUMEPAN;
......
...@@ -54,11 +54,11 @@ void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan) ...@@ -54,11 +54,11 @@ void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan)
/* FIXME: use calculated vol and pan ampfactors */ /* FIXME: use calculated vol and pan ampfactors */
temp = (double) (volpan->lVolume - (volpan->lPan > 0 ? volpan->lPan : 0)); 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)); 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) void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan)
...@@ -66,15 +66,15 @@ void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan) ...@@ -66,15 +66,15 @@ void DSOUND_AmpFactorToVolPan(PDSVOLUMEPAN volpan)
double left,right; double left,right;
TRACE("(%p)\n",volpan); TRACE("(%p)\n",volpan);
TRACE("left=%x, right=%x\n",volpan->dwTotalLeftAmpFactor,volpan->dwTotalRightAmpFactor); TRACE("left=%x, right=%x\n",volpan->dwTotalAmpFactor[0],volpan->dwTotalAmpFactor[1]);
if (volpan->dwTotalLeftAmpFactor==0) if (volpan->dwTotalAmpFactor[0]==0)
left=-10000; left=-10000;
else else
left=600 * log(((double)volpan->dwTotalLeftAmpFactor) / 0xffff) / log(2); left=600 * log(((double)volpan->dwTotalAmpFactor[0]) / 0xffff) / log(2);
if (volpan->dwTotalRightAmpFactor==0) if (volpan->dwTotalAmpFactor[1]==0)
right=-10000; right=-10000;
else else
right=600 * log(((double)volpan->dwTotalRightAmpFactor) / 0xffff) / log(2); right=600 * log(((double)volpan->dwTotalAmpFactor[1]) / 0xffff) / log(2);
if (left<right) if (left<right)
volpan->lVolume=right; volpan->lVolume=right;
else else
...@@ -399,32 +399,30 @@ static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames) ...@@ -399,32 +399,30 @@ static void DSOUND_MixToTemporary(IDirectSoundBufferImpl *dsb, DWORD frames)
static void DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT frames) static void DSOUND_MixerVol(const IDirectSoundBufferImpl *dsb, INT frames)
{ {
INT i; INT i;
float vLeft, vRight; float vols[DS_MAX_CHANNELS];
UINT channels = dsb->device->pwfx->nChannels, chan; UINT channels = dsb->device->pwfx->nChannels, chan;
TRACE("(%p,%d)\n",dsb,frames); TRACE("(%p,%d)\n",dsb,frames);
TRACE("left = %x, right = %x\n", dsb->volpan.dwTotalLeftAmpFactor, TRACE("left = %x, right = %x\n", dsb->volpan.dwTotalAmpFactor[0],
dsb->volpan.dwTotalRightAmpFactor); dsb->volpan.dwTotalAmpFactor[1]);
if ((!(dsb->dsbd.dwFlags & DSBCAPS_CTRLPAN) || (dsb->volpan.lPan == 0)) && if ((!(dsb->dsbd.dwFlags & DSBCAPS_CTRLPAN) || (dsb->volpan.lPan == 0)) &&
(!(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME) || (dsb->volpan.lVolume == 0)) && (!(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME) || (dsb->volpan.lVolume == 0)) &&
!(dsb->dsbd.dwFlags & DSBCAPS_CTRL3D)) !(dsb->dsbd.dwFlags & DSBCAPS_CTRL3D))
return; /* Nothing to do */ return; /* Nothing to do */
if (channels != 1 && channels != 2) if (channels > DS_MAX_CHANNELS)
{ {
FIXME("There is no support for %u channels\n", channels); FIXME("There is no support for %u channels\n", channels);
return; return;
} }
vLeft = dsb->volpan.dwTotalLeftAmpFactor / ((float)0xFFFF); for (i = 0; i < channels; ++i)
vRight = dsb->volpan.dwTotalRightAmpFactor / ((float)0xFFFF); vols[i] = dsb->volpan.dwTotalAmpFactor[i] / ((float)0xFFFF);
for(i = 0; i < frames; ++i){ for(i = 0; i < frames; ++i){
for(chan = 0; chan < channels; ++chan){ for(chan = 0; chan < channels; ++chan){
if(chan == 0) dsb->device->tmp_buffer[i * channels + chan] *= vols[chan];
dsb->device->tmp_buffer[i * channels + chan] *= vLeft;
else
dsb->device->tmp_buffer[i * channels + chan] *= vRight;
} }
} }
} }
......
...@@ -570,7 +570,8 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume(IDirectSoundBuffer *iface, LON ...@@ -570,7 +570,8 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume(IDirectSoundBuffer *iface, LON
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface); IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
DirectSoundDevice *device = This->device; DirectSoundDevice *device = This->device;
HRESULT hr; HRESULT hr;
float lvol, rvol; float fvol;
int i;
TRACE("(%p,%d)\n", iface, vol); TRACE("(%p,%d)\n", iface, vol);
...@@ -587,45 +588,34 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume(IDirectSoundBuffer *iface, LON ...@@ -587,45 +588,34 @@ static HRESULT WINAPI PrimaryBufferImpl_SetVolume(IDirectSoundBuffer *iface, LON
/* **** */ /* **** */
EnterCriticalSection(&device->mixlock); EnterCriticalSection(&device->mixlock);
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol); for (i = 0; i < DS_MAX_CHANNELS; i++) {
if(FAILED(hr)){ if (device->pwfx->nChannels > i){
LeaveCriticalSection(&device->mixlock); hr = IAudioStreamVolume_GetChannelVolume(device->volume, i, &fvol);
WARN("GetChannelVolume failed: %08x\n", hr); if (FAILED(hr)){
return hr; LeaveCriticalSection(&device->mixlock);
} WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
if(device->pwfx->nChannels > 1){ }
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol); } else
if(FAILED(hr)){ fvol=1.0f;
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
}else
rvol = 1;
device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF)); device->volpan.dwTotalAmpFactor[i]=((UINT16)(fvol * (DWORD)0xFFFF));
device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF)); }
DSOUND_AmpFactorToVolPan(&device->volpan); DSOUND_AmpFactorToVolPan(&device->volpan);
if (vol != device->volpan.lVolume) { if (vol != device->volpan.lVolume) {
device->volpan.lVolume=vol; device->volpan.lVolume=vol;
DSOUND_RecalcVolPan(&device->volpan); 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){ for (i = 0; i < DS_MAX_CHANNELS; i++) {
rvol = (float)((DWORD)(device->volpan.dwTotalRightAmpFactor & 0xFFFF) / (float)0xFFFF); if (device->pwfx->nChannels > i){
hr = IAudioStreamVolume_SetChannelVolume(device->volume, 1, rvol); fvol = (float)((DWORD)(device->volpan.dwTotalAmpFactor[i] & 0xFFFF) / (float)0xFFFF);
if(FAILED(hr)){ hr = IAudioStreamVolume_SetChannelVolume(device->volume, i, fvol);
LeaveCriticalSection(&device->mixlock); if (FAILED(hr)){
WARN("SetChannelVolume failed: %08x\n", hr); LeaveCriticalSection(&device->mixlock);
return hr; WARN("SetChannelVolume failed: %08x\n", hr);
return hr;
}
} }
} }
} }
...@@ -640,8 +630,10 @@ static HRESULT WINAPI PrimaryBufferImpl_GetVolume(IDirectSoundBuffer *iface, LON ...@@ -640,8 +630,10 @@ static HRESULT WINAPI PrimaryBufferImpl_GetVolume(IDirectSoundBuffer *iface, LON
{ {
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface); IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
DirectSoundDevice *device = This->device; DirectSoundDevice *device = This->device;
float lvol, rvol; float fvol;
HRESULT hr; HRESULT hr;
int i;
TRACE("(%p,%p)\n", iface, vol); TRACE("(%p,%p)\n", iface, vol);
if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) { if (!(This->dsbd.dwFlags & DSBCAPS_CTRLVOLUME)) {
...@@ -656,25 +648,19 @@ static HRESULT WINAPI PrimaryBufferImpl_GetVolume(IDirectSoundBuffer *iface, LON ...@@ -656,25 +648,19 @@ static HRESULT WINAPI PrimaryBufferImpl_GetVolume(IDirectSoundBuffer *iface, LON
EnterCriticalSection(&device->mixlock); EnterCriticalSection(&device->mixlock);
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol); for (i = 0; i < DS_MAX_CHANNELS; i++) {
if(FAILED(hr)){ if (device->pwfx->nChannels > i){
LeaveCriticalSection(&device->mixlock); hr = IAudioStreamVolume_GetChannelVolume(device->volume, i, &fvol);
WARN("GetChannelVolume failed: %08x\n", hr); if (FAILED(hr)){
return hr; LeaveCriticalSection(&device->mixlock);
} WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
if(device->pwfx->nChannels > 1){ }
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol); } else
if(FAILED(hr)){ fvol = 1;
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
}else
rvol = 1;
device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF)); device->volpan.dwTotalAmpFactor[i] = ((UINT16)(fvol * (DWORD)0xFFFF));
device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF)); }
DSOUND_AmpFactorToVolPan(&device->volpan); DSOUND_AmpFactorToVolPan(&device->volpan);
*vol = device->volpan.lVolume; *vol = device->volpan.lVolume;
...@@ -950,8 +936,10 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan(IDirectSoundBuffer *iface, LONG p ...@@ -950,8 +936,10 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan(IDirectSoundBuffer *iface, LONG p
{ {
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface); IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
DirectSoundDevice *device = This->device; DirectSoundDevice *device = This->device;
float lvol, rvol; float fvol;
HRESULT hr; HRESULT hr;
int i;
TRACE("(%p,%d)\n", iface, pan); TRACE("(%p,%d)\n", iface, pan);
if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) { if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
...@@ -967,46 +955,34 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan(IDirectSoundBuffer *iface, LONG p ...@@ -967,46 +955,34 @@ static HRESULT WINAPI PrimaryBufferImpl_SetPan(IDirectSoundBuffer *iface, LONG p
/* **** */ /* **** */
EnterCriticalSection(&device->mixlock); EnterCriticalSection(&device->mixlock);
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol); for (i = 0; i < DS_MAX_CHANNELS; i++) {
if(FAILED(hr)){ if (device->pwfx->nChannels > i){
LeaveCriticalSection(&device->mixlock); hr = IAudioStreamVolume_GetChannelVolume(device->volume, i, &fvol);
WARN("GetChannelVolume failed: %08x\n", hr); if (FAILED(hr)){
return hr; LeaveCriticalSection(&device->mixlock);
} WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
if(device->pwfx->nChannels > 1){ }
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol); } else
if(FAILED(hr)){ fvol = 1;
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
}else
rvol = 1;
device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF)); device->volpan.dwTotalAmpFactor[i] = ((UINT16)(fvol * (DWORD)0xFFFF));
device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF)); }
DSOUND_AmpFactorToVolPan(&device->volpan); DSOUND_AmpFactorToVolPan(&device->volpan);
if (pan != device->volpan.lPan) { if (pan != device->volpan.lPan) {
device->volpan.lPan=pan; device->volpan.lPan=pan;
DSOUND_RecalcVolPan(&device->volpan); DSOUND_RecalcVolPan(&device->volpan);
lvol = (float)((DWORD)(device->volpan.dwTotalLeftAmpFactor & 0xFFFF) / (float)0xFFFF); for (i = 0; i < DS_MAX_CHANNELS; i++) {
hr = IAudioStreamVolume_SetChannelVolume(device->volume, 0, lvol); if (device->pwfx->nChannels > i) {
if(FAILED(hr)){ fvol = (float)((DWORD)(device->volpan.dwTotalAmpFactor[i] & 0xFFFF) / (float)0xFFFF);
LeaveCriticalSection(&device->mixlock); hr = IAudioStreamVolume_SetChannelVolume(device->volume, i, fvol);
WARN("SetChannelVolume failed: %08x\n", hr); if (FAILED(hr)){
return 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;
} }
} }
} }
...@@ -1021,8 +997,10 @@ static HRESULT WINAPI PrimaryBufferImpl_GetPan(IDirectSoundBuffer *iface, LONG * ...@@ -1021,8 +997,10 @@ static HRESULT WINAPI PrimaryBufferImpl_GetPan(IDirectSoundBuffer *iface, LONG *
{ {
IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface); IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer(iface);
DirectSoundDevice *device = This->device; DirectSoundDevice *device = This->device;
float lvol, rvol; float fvol;
HRESULT hr; HRESULT hr;
int i;
TRACE("(%p,%p)\n", iface, pan); TRACE("(%p,%p)\n", iface, pan);
if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) { if (!(This->dsbd.dwFlags & DSBCAPS_CTRLPAN)) {
...@@ -1037,25 +1015,19 @@ static HRESULT WINAPI PrimaryBufferImpl_GetPan(IDirectSoundBuffer *iface, LONG * ...@@ -1037,25 +1015,19 @@ static HRESULT WINAPI PrimaryBufferImpl_GetPan(IDirectSoundBuffer *iface, LONG *
EnterCriticalSection(&device->mixlock); EnterCriticalSection(&device->mixlock);
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 0, &lvol); for (i = 0; i < DS_MAX_CHANNELS; i++) {
if(FAILED(hr)){ if (device->pwfx->nChannels > i) {
LeaveCriticalSection(&device->mixlock); hr = IAudioStreamVolume_GetChannelVolume(device->volume, i, &fvol);
WARN("GetChannelVolume failed: %08x\n", hr); if (FAILED(hr)){
return hr; LeaveCriticalSection(&device->mixlock);
} WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
if(device->pwfx->nChannels > 1){ }
hr = IAudioStreamVolume_GetChannelVolume(device->volume, 1, &rvol); } else
if(FAILED(hr)){ fvol = 1;
LeaveCriticalSection(&device->mixlock);
WARN("GetChannelVolume failed: %08x\n", hr);
return hr;
}
}else
rvol = 1;
device->volpan.dwTotalLeftAmpFactor = ((UINT16)(lvol * (DWORD)0xFFFF)); device->volpan.dwTotalAmpFactor[i] = ((UINT16)(fvol * (DWORD)0xFFFF));
device->volpan.dwTotalRightAmpFactor = ((UINT16)(rvol * (DWORD)0xFFFF)); }
DSOUND_AmpFactorToVolPan(&device->volpan); DSOUND_AmpFactorToVolPan(&device->volpan);
*pan = device->volpan.lPan; *pan = device->volpan.lPan;
......
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