dsound: Use relative velocity to compute Doppler shift.

It's less physically correct but closer to the native behavior.
This commit is contained in:
Anton Baskanov 2023-04-24 00:19:44 +07:00 committed by Alexandre Julliard
parent 8c26e7e592
commit 81feccb7e3
2 changed files with 8 additions and 12 deletions

View file

@ -167,7 +167,8 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb)
int i, num_main_speakers;
float a, ingain;
/* doppler shift related stuff */
D3DVALUE flFreq, flBufferVel, flListenerVel;
D3DVECTOR vRelativeVel;
D3DVALUE flFreq, flRelativeVel;
TRACE("(%p)\n",dsb);
@ -292,6 +293,7 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb)
dsb->freq = dsb->ds3db_freq;
/* doppler shift*/
vRelativeVel = VectorBetweenTwoPoints(&dsb->device->ds3dl.vVelocity, &dsb->ds3db_ds3db.vVelocity);
if (!VectorMagnitude(&dsb->ds3db_ds3db.vVelocity) && !VectorMagnitude(&dsb->device->ds3dl.vVelocity))
{
TRACE("doppler: Buffer and Listener don't have velocities\n");
@ -301,18 +303,14 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb)
dsb->ds3db_ds3db.vVelocity.z == dsb->device->ds3dl.vVelocity.z) &&
!(vDistance.x == 0.0f && vDistance.y == 0.0f && vDistance.z == 0.0f))
{
/* calculate length of ds3db_ds3db.vVelocity component which causes Doppler Effect
/* calculate length of vRelativeVel component which causes Doppler Effect
NOTE: if buffer moves TOWARDS the listener, its velocity component is NEGATIVE
if buffer moves AWAY from listener, its velocity component is POSITIVE */
flBufferVel = ProjectVector(&dsb->ds3db_ds3db.vVelocity, &vDistance);
/* calculate length of ds3dl.vVelocity component which causes Doppler Effect
NOTE: if listener moves TOWARDS the buffer, its velocity component is POSITIVE
if listener moves AWAY from buffer, its velocity component is NEGATIVE */
flListenerVel = ProjectVector(&dsb->device->ds3dl.vVelocity, &vDistance);
flRelativeVel = ProjectVector(&vRelativeVel, &vDistance);
/* formula taken from Gianicoli D.: Physics, 4th edition: */
flFreq = dsb->ds3db_freq * ((DEFAULT_VELOCITY + flListenerVel)/(DEFAULT_VELOCITY + flBufferVel));
TRACE("doppler: Buffer velocity (component) = %f, Listener velocity (component) = %f => Doppler shift: %ld Hz -> %f Hz\n",
flBufferVel, flListenerVel, dsb->ds3db_freq, flFreq);
flFreq = dsb->ds3db_freq * (DEFAULT_VELOCITY/(DEFAULT_VELOCITY + flRelativeVel));
TRACE("doppler: Relative velocity (component) = %f => Doppler shift: %ld Hz -> %f Hz\n",
flRelativeVel, dsb->ds3db_freq, flFreq);
dsb->freq = flFreq;
}

View file

@ -1442,9 +1442,7 @@ static void test_doppler(GUID *guid, BOOL play)
check_doppler(dsound, listener, play, DS3DMODE_NORMAL, 0, 0, 0, -90, 22050, 22050);
/* The Doppler shift does not depend on the frame of reference. */
/* Wine TODO: The frequency is too low. */
check_doppler(dsound, listener, play, DS3DMODE_NORMAL, 0, 90, 1, 0, 22050, 29400);
/* Wine TODO: The frequency is too low. */
check_doppler(dsound, listener, play, DS3DMODE_NORMAL, 0, -90, 1, 0, 22050, 17640);
IDirectSound3DListener_Release(listener);