mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
67 lines
3.0 KiB
Diff
67 lines
3.0 KiB
Diff
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
|
|
|