[PATCH 0/5] MR2715: dsound: Doppler shift (part 1)
From: Anton Baskanov <baskanov(a)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; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2715
From: Anton Baskanov <baskanov(a)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); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2715
From: Anton Baskanov <baskanov(a)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; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2715
From: Anton Baskanov <baskanov(a)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; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2715
From: Anton Baskanov <baskanov(a)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; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/2715
This merge request was approved by Huw Davies. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/2715
participants (3)
-
Anton Baskanov -
Anton Baskanov (@baskanov) -
Huw Davies (@huw)