Development branch: https://gitlab.winehq.org/baskanov/wine/-/commits/dsound-doppler/
From: Anton Baskanov baskanov@gmail.com
--- dlls/dsound/buffer.c | 3 --- dlls/dsound/dsound_private.h | 1 - 2 files changed, 4 deletions(-)
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c index b3238b8918e..9f68752232f 100644 --- a/dlls/dsound/buffer.c +++ b/dlls/dsound/buffer.c @@ -293,7 +293,6 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(IDirectSoundBuffer8 *i if (freq != oldFreq) { This->freqAdjustNum = This->freq; This->freqAdjustDen = This->device->pwfx->nSamplesPerSec; - This->nAvgBytesPerSec = freq * This->pwfx->nBlockAlign; DSOUND_RecalcFormat(This);
newcommitted = realloc(This->committedbuff, This->writelead); @@ -1114,8 +1113,6 @@ HRESULT secondarybuffer_create(DirectSoundDevice *device, const DSBUFFERDESC *ds
dsb->freqAdjustNum = dsb->freq; dsb->freqAdjustDen = device->pwfx->nSamplesPerSec; - dsb->nAvgBytesPerSec = dsb->freq * - dsbd->lpwfxFormat->nBlockAlign;
/* calculate fragment size and write lead */ DSOUND_RecalcFormat(dsb); diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index e12baadf650..4d8cf84385d 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -141,7 +141,6 @@ struct IDirectSoundBufferImpl BufferMemory* buffer; DWORD playflags,state,leadin; DWORD writelead,buflen; - DWORD nAvgBytesPerSec; DWORD freq; DSVOLUMEPAN volpan; DSBUFFERDESC dsbd;
From: Anton Baskanov baskanov@gmail.com
--- dlls/dsound/buffer.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c index 9f68752232f..403c88c2c95 100644 --- a/dlls/dsound/buffer.c +++ b/dlls/dsound/buffer.c @@ -291,8 +291,6 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(IDirectSoundBuffer8 *i oldFreq = This->freq; This->freq = freq; if (freq != oldFreq) { - This->freqAdjustNum = This->freq; - This->freqAdjustDen = This->device->pwfx->nSamplesPerSec; DSOUND_RecalcFormat(This);
newcommitted = realloc(This->committedbuff, This->writelead); @@ -1111,9 +1109,6 @@ HRESULT secondarybuffer_create(DirectSoundDevice *device, const DSBUFFERDESC *ds dsb->sec_mixpos = 0; dsb->state = STATE_STOPPED;
- dsb->freqAdjustNum = dsb->freq; - dsb->freqAdjustDen = device->pwfx->nSamplesPerSec; - /* calculate fragment size and write lead */ DSOUND_RecalcFormat(dsb);
From: Anton Baskanov baskanov@gmail.com
Resetting it results in position discontinuity. With frequent SetFrequency() calls, this produces audible crackling. The issue affects pedestrian voices in GTA: San Andreas. --- dlls/dsound/mixer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index dbef1bc40fa..4d0c54735cf 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -96,6 +96,7 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) { DWORD ichannels = dsb->pwfx->nChannels; DWORD ochannels = dsb->device->pwfx->nChannels; + LONG64 oldFreqAdjustDen = dsb->freqAdjustDen; WAVEFORMATEXTENSIBLE *pwfxe; BOOL ieee = FALSE;
@@ -130,7 +131,8 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb) /* calculate the 10ms write lead */ dsb->writelead = (dsb->freq / 100) * dsb->pwfx->nBlockAlign;
- dsb->freqAccNum = 0; + if (oldFreqAdjustDen) + dsb->freqAccNum = (dsb->freqAccNum * dsb->freqAdjustDen + oldFreqAdjustDen / 2) / oldFreqAdjustDen;
dsb->get_aux = ieee ? getbpp[4] : getbpp[dsb->pwfx->wBitsPerSample/8 - 1]; dsb->put_aux = putieee32;
From: Anton Baskanov baskanov@gmail.com
--- dlls/dsound/sound3d.c | 55 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
diff --git a/dlls/dsound/sound3d.c b/dlls/dsound/sound3d.c index 48febdeb307..939e0091815 100644 --- a/dlls/dsound/sound3d.c +++ b/dlls/dsound/sound3d.c @@ -363,11 +363,13 @@ static void DSOUND_ChangeListener(IDirectSoundBufferImpl *ds3dl) TRACE("(%p)\n",ds3dl); for (i = 0; i < ds3dl->device->nrofbuffers; i++) { + AcquireSRWLockExclusive(&ds3dl->device->buffers[i]->lock); /* check if this buffer is waiting for recalculation */ if (ds3dl->device->buffers[i]->ds3db_need_recalc) { DSOUND_Mix3DBuffer(ds3dl->device->buffers[i]); } + ReleaseSRWLockExclusive(&ds3dl->device->buffers[i]->lock); } }
@@ -545,6 +547,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetAllParameters(IDirectSound3DBu }
TRACE("setting: all parameters; dwApply = %ld\n", dwApply); + + AcquireSRWLockExclusive(&This->lock); + This->ds3db_ds3db = *lpcDs3dBuffer;
if (dwApply == DS3D_IMMEDIATE) @@ -554,6 +559,8 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetAllParameters(IDirectSound3DBu This->ds3db_need_recalc = TRUE; status = DS_OK;
+ ReleaseSRWLockExclusive(&This->lock); + return status; }
@@ -564,11 +571,17 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeAngles(IDirectSound3DBuffe
TRACE("setting: Inside Cone Angle = %ld; Outside Cone Angle = %ld; dwApply = %ld\n", dwInsideConeAngle, dwOutsideConeAngle, dwApply); + + AcquireSRWLockExclusive(&This->lock); + This->ds3db_ds3db.dwInsideConeAngle = dwInsideConeAngle; This->ds3db_ds3db.dwOutsideConeAngle = dwOutsideConeAngle; if (dwApply == DS3D_IMMEDIATE) DSOUND_Mix3DBuffer(This); This->ds3db_need_recalc = TRUE; + + ReleaseSRWLockExclusive(&This->lock); + return DS_OK; }
@@ -578,6 +591,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOrientation(IDirectSound3D IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
TRACE("setting: Cone Orientation vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply); + + AcquireSRWLockExclusive(&This->lock); + This->ds3db_ds3db.vConeOrientation.x = x; This->ds3db_ds3db.vConeOrientation.y = y; This->ds3db_ds3db.vConeOrientation.z = z; @@ -587,6 +603,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOrientation(IDirectSound3D DSOUND_Mix3DBuffer(This); } This->ds3db_need_recalc = TRUE; + + ReleaseSRWLockExclusive(&This->lock); + return DS_OK; }
@@ -596,6 +615,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOutsideVolume(IDirectSound IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
TRACE("setting: ConeOutsideVolume = %ld; dwApply = %ld\n", lConeOutsideVolume, dwApply); + + AcquireSRWLockExclusive(&This->lock); + This->ds3db_ds3db.lConeOutsideVolume = lConeOutsideVolume; if (dwApply == DS3D_IMMEDIATE) { @@ -603,6 +625,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOutsideVolume(IDirectSound DSOUND_Mix3DBuffer(This); } This->ds3db_need_recalc = TRUE; + + ReleaseSRWLockExclusive(&This->lock); + return DS_OK; }
@@ -612,6 +637,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetMaxDistance(IDirectSound3DBuff IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
TRACE("setting: MaxDistance = %f; dwApply = %ld\n", fMaxDistance, dwApply); + + AcquireSRWLockExclusive(&This->lock); + This->ds3db_ds3db.flMaxDistance = fMaxDistance; if (dwApply == DS3D_IMMEDIATE) { @@ -619,6 +647,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetMaxDistance(IDirectSound3DBuff DSOUND_Mix3DBuffer(This); } This->ds3db_need_recalc = TRUE; + + ReleaseSRWLockExclusive(&This->lock); + return DS_OK; }
@@ -628,6 +659,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetMinDistance(IDirectSound3DBuff IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
TRACE("setting: MinDistance = %f; dwApply = %ld\n", fMinDistance, dwApply); + + AcquireSRWLockExclusive(&This->lock); + This->ds3db_ds3db.flMinDistance = fMinDistance; if (dwApply == DS3D_IMMEDIATE) { @@ -635,6 +669,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetMinDistance(IDirectSound3DBuff DSOUND_Mix3DBuffer(This); } This->ds3db_need_recalc = TRUE; + + ReleaseSRWLockExclusive(&This->lock); + return DS_OK; }
@@ -644,6 +681,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetMode(IDirectSound3DBuffer *ifa IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
TRACE("setting: Mode = %ld; dwApply = %ld\n", dwMode, dwApply); + + AcquireSRWLockExclusive(&This->lock); + This->ds3db_ds3db.dwMode = dwMode; if (dwApply == DS3D_IMMEDIATE) { @@ -651,6 +691,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetMode(IDirectSound3DBuffer *ifa DSOUND_Mix3DBuffer(This); } This->ds3db_need_recalc = TRUE; + + ReleaseSRWLockExclusive(&This->lock); + return DS_OK; }
@@ -660,6 +703,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetPosition(IDirectSound3DBuffer IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
TRACE("setting: Position vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply); + + AcquireSRWLockExclusive(&This->lock); + This->ds3db_ds3db.vPosition.x = x; This->ds3db_ds3db.vPosition.y = y; This->ds3db_ds3db.vPosition.z = z; @@ -669,6 +715,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetPosition(IDirectSound3DBuffer DSOUND_Mix3DBuffer(This); } This->ds3db_need_recalc = TRUE; + + ReleaseSRWLockExclusive(&This->lock); + return DS_OK; }
@@ -678,6 +727,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetVelocity(IDirectSound3DBuffer IDirectSoundBufferImpl *This = impl_from_IDirectSound3DBuffer(iface);
TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply); + + AcquireSRWLockExclusive(&This->lock); + This->ds3db_ds3db.vVelocity.x = x; This->ds3db_ds3db.vVelocity.y = y; This->ds3db_ds3db.vVelocity.z = z; @@ -687,6 +739,9 @@ static HRESULT WINAPI IDirectSound3DBufferImpl_SetVelocity(IDirectSound3DBuffer DSOUND_Mix3DBuffer(This); } This->ds3db_need_recalc = TRUE; + + ReleaseSRWLockExclusive(&This->lock); + return DS_OK; }
From: Anton Baskanov baskanov@gmail.com
--- dlls/dsound/buffer.c | 15 +++------------ dlls/dsound/dsound_private.h | 2 +- dlls/dsound/mixer.c | 1 + 3 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/dlls/dsound/buffer.c b/dlls/dsound/buffer.c index 403c88c2c95..7b830604a60 100644 --- a/dlls/dsound/buffer.c +++ b/dlls/dsound/buffer.c @@ -264,7 +264,6 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(IDirectSoundBuffer8 *i { IDirectSoundBufferImpl *This = impl_from_IDirectSoundBuffer8(iface); DWORD oldFreq; - void *newcommitted;
TRACE("(%p,%ld)\n",This,freq);
@@ -290,17 +289,9 @@ static HRESULT WINAPI IDirectSoundBufferImpl_SetFrequency(IDirectSoundBuffer8 *i
oldFreq = This->freq; This->freq = freq; - if (freq != oldFreq) { + if (freq != oldFreq) DSOUND_RecalcFormat(This);
- newcommitted = realloc(This->committedbuff, This->writelead); - if(!newcommitted) { - ReleaseSRWLockExclusive(&This->lock); - return DSERR_OUTOFMEMORY; - } - This->committedbuff = newcommitted; - } - ReleaseSRWLockExclusive(&This->lock);
return DS_OK; @@ -1112,7 +1103,7 @@ HRESULT secondarybuffer_create(DirectSoundDevice *device, const DSBUFFERDESC *ds /* calculate fragment size and write lead */ DSOUND_RecalcFormat(dsb);
- dsb->committedbuff = malloc(dsb->writelead); + dsb->committedbuff = malloc(dsb->maxwritelead); if(!dsb->committedbuff) { IDirectSoundBuffer8_Release(&dsb->IDirectSoundBuffer8_iface); return DSERR_OUTOFMEMORY; @@ -1216,7 +1207,7 @@ HRESULT IDirectSoundBufferImpl_Duplicate( return DSERR_OUTOFMEMORY; }
- committedbuff = malloc(pdsb->writelead); + committedbuff = malloc(pdsb->maxwritelead); if (committedbuff == NULL) { free(dsb); *ppdsb = NULL; diff --git a/dlls/dsound/dsound_private.h b/dlls/dsound/dsound_private.h index 4d8cf84385d..d9f488c25b8 100644 --- a/dlls/dsound/dsound_private.h +++ b/dlls/dsound/dsound_private.h @@ -140,7 +140,7 @@ struct IDirectSoundBufferImpl PWAVEFORMATEX pwfx; BufferMemory* buffer; DWORD playflags,state,leadin; - DWORD writelead,buflen; + DWORD writelead,maxwritelead,buflen; DWORD freq; DSVOLUMEPAN volpan; DSBUFFERDESC dsbd; diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c index 4d0c54735cf..bf05805221b 100644 --- a/dlls/dsound/mixer.c +++ b/dlls/dsound/mixer.c @@ -130,6 +130,7 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
/* calculate the 10ms write lead */ dsb->writelead = (dsb->freq / 100) * dsb->pwfx->nBlockAlign; + dsb->maxwritelead = (DSBFREQUENCY_MAX / 100) * dsb->pwfx->nBlockAlign;
if (oldFreqAdjustDen) dsb->freqAccNum = (dsb->freqAccNum * dsb->freqAdjustDen + oldFreqAdjustDen / 2) / oldFreqAdjustDen;
This merge request was approved by Huw Davies.