dsound: Fix angle to sound source calculation.

Ruslan Kabatsayev b7.10110111 at gmail.com
Tue Mar 24 12:00:40 CDT 2015


As I've tested, this does indeed fix bug 38041.

On Tue, Mar 24, 2015 at 7:31 PM, Andrew Eikum <aeikum at codeweavers.com> wrote:
> Forwarding on to wine-devel, Stas, and Ruslan from Bug 38041.
>
> Any thoughts on the coning breakage, Stas?
>
> Andrew
>
> On Mon, Mar 23, 2015 at 09:52:32PM +0000, Mark Harmstone wrote:
>> Hi,
>>
>> I've had a play with it, and yes, I think he's right. It seems to be a
>> lot more robust than my code. One thing though that I think he's
>> overlooked is that he changes the behaviour of AngleBetweenVectorsRad,
>> which is called by AngleBetweenVectorsDeg and thus the coning code -
>> I think this patch will probably break that.
>>
>> I've not tested it yet, but there's a chance this patch might fix
>> bug 38041.
>>
>> Mark
>>
>> On 23/03/15 14:39, Andrew Eikum wrote:
>> > This seems sane to me, but I never had a good grasp on this to begin
>> > with. Does it look OK to you, Mark?
>> >
>> > Andrew
>> >
>> > On Sun, Mar 22, 2015 at 08:59:15PM +0300, Стас Цымбалов wrote:
>> >> 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(-)
>> >
>> >> From 1ebe3761b0d6acfca58cec17472336a05b7f2679 Mon Sep 17 00:00:00 2001
>> >> From: Stas Cymbalov <dummyunit at gmail.com>
>> >> Date: Sun, 22 Mar 2015 18:22:49 +0300
>> >> Subject: dsound: Fix angle to sound source calculation.
>> >>
>> >> ---
>> >>  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.0.5
>> >>
>> >
>> >>
>> >
>>



More information about the wine-devel mailing list