Added patch to fix calculation of 3D sound source.

This commit is contained in:
Sebastian Lackner
2015-03-28 21:38:50 +01:00
parent 9cfd7972d9
commit 41f41a7c98
5 changed files with 116 additions and 28 deletions

View File

@@ -0,0 +1,66 @@
From a0b63f4c0c9695606fe8466cb9574ebfb9230d7b Mon Sep 17 00:00:00 2001
From: Stas Cymbalov <dummyunit@gmail.com>
Date: Sun, 22 Mar 2015 18:22:49 +0300
Subject: dsound: Fix angle to sound source calculation.
This patch fixes incorrect sound positioning in dsound.
As of now, angle to sound source is calculated as angle between
vDistance and vOrientFront.
This leads to incorrect results for all sources that are not in the
same plane as speakers.
In extreme case: for sources directly above or below origin, angle is
calculated to -90 degrees, and they are played in the left speaker.
This patch changes angle calculation: angle to sound source is
calculated as angle between vDistance and plane given by vectors
vOrientFront and vOrientTop.
---
dlls/dsound/sound3d.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/dlls/dsound/sound3d.c b/dlls/dsound/sound3d.c
index 9a0226a..ffd4d45 100644
--- a/dlls/dsound/sound3d.c
+++ b/dlls/dsound/sound3d.c
@@ -112,7 +112,6 @@ static inline D3DVALUE AngleBetweenVectorsRad (const D3DVECTOR *a, const D3DVECT
cos = product/(la*lb);
angle = acos(cos);
- if (cos < 0.0f) { angle -= M_PI; }
TRACE("angle between (%f,%f,%f) and (%f,%f,%f) = %f radians (%f degrees)\n", a->x, a->y, a->z, b->x,
b->y, b->z, angle, RadToDeg(angle));
return angle;
@@ -264,16 +263,20 @@ void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb)
else
{
vLeft = VectorProduct(&dsb->device->ds3dl.vOrientFront, &dsb->device->ds3dl.vOrientTop);
- flAngle = AngleBetweenVectorsRad(&dsb->device->ds3dl.vOrientFront, &vDistance);
- flAngle2 = AngleBetweenVectorsRad(&vLeft, &vDistance);
-
- /* AngleBetweenVectorsRad performs a dot product, which gives us the cosine of the angle
- * between two vectors. Unfortunately, because cos(theta) = cos(-theta), we've no idea from
- * this whether the sound is to our left or to our right. We have to perform another dot
- * product, with a vector at right angles to the initial one, to get the correct angle.
- * The angle should be between -180 degrees and 180 degrees. */
- if (flAngle < 0.0f) { flAngle += M_PI; }
- if (flAngle2 > 0.0f) { flAngle = -flAngle; }
+ /* To calculate angle to sound source we need to:
+ * 1) Get angle between vDistance and a plane on which angle to sound source should be 0.
+ * Such a plane is given by vectors vOrientFront and vOrientTop, and angle between vector
+ * and a plane equals to M_PI_2 - angle between vector and normal to this plane (vLeft in this case).
+ * 2) Determine if the source is behind or in front of us by calculating angle between vDistance
+ * and vOrientFront.
+ */
+ flAngle = AngleBetweenVectorsRad(&vLeft, &vDistance);
+ flAngle2 = AngleBetweenVectorsRad(&dsb->device->ds3dl.vOrientFront, &vDistance);
+ if (flAngle2 > M_PI_2)
+ flAngle = -flAngle;
+ flAngle -= M_PI_2;
+ if (flAngle < -M_PI)
+ flAngle += 2*M_PI;
}
TRACE("panning: Angle = %f rad, lPan = %d\n", flAngle, dsb->volpan.lPan);
--
2.3.3

View File

@@ -0,0 +1 @@
Fixes: [38041] Fix calculation of 3D sound source