[Openal-devel] Doppler effect in recent OpenAL versions
Ed Phillips
ed at udel.edu
Fri Sep 23 22:55:10 PDT 2005
Hi,
On Fri, 23 Sep 2005, Garin Hiebert wrote:
> As near as I can tell, the doppler formula expressed in the Windows
> software 1.1 path seems to handle velocities correctly.
I agree that the doppler formula "handles" the velocities/positions
correctly. However, the doppler formula calculations are not being
performed using the *actual* positions and velocities that the caller
passed in... the source position is being modified before-hand.
First, the source position has the listener position subtracted from it,
then it is multiplied by a matrix which transforms the source position
into the coordinate system formed by the 3 listener orientation vectors
("right", "at" and "up"). Why is this done? It's not part of the 1.1
specification of the doppler forumla.... anyway...
The SourceToListener vector is calculated (in section 4 of the code) based
on this *transformed* source position (not the one passed in by the
caller)... and we *know* that even if everything else remains constant
(the velocities, and the listener position, speed of sound, doppler
velocity), this *transformed* source position will vary in direct relation
to the orientation of the listener (which changes the matrix, which
changes the source position)... SO... the doppler forumla will then
compute a range of pitches based directly on the orientation of the
listener.
And this is the exact behavior I've observed with both 1.0 and 1.1.
There are several solutions I've found to correct this:
1) Pass in positions and velocities relative to the same coordinate system
and then have the OpenAL code transform the velocities using the same
matrix used to transform the source position into listener-relative
coordinates. I've tested this solution in-game and it makes the doppler
effect work correctly - here's a diff of the changes I used for this
solution:
$ diff ALu-orig.c ALu-2.c
228a229
> aluMatrixVector(ListenerVelocity, Matrix);
229a231
> aluMatrixVector(Velocity, Matrix);
2) Change the doppler calculations to use pristine copies of the positions
and velocities (without altering them at all before they are used in the
doppler forumla). I've tested this solution in-game and it also makes the
doppler effect work correctly - here's a diff of the changes I made for
this solution:
$ diff ALu-orig.c ALu-3.c
100a101,102
> ALfloat PositionOrig[3], ListenerPositionOrig[3];
> ALfloat SourceToListenerOrig[3];
112a115
> alGetListenerfv(AL_POSITION,ListenerPositionOrig);
120a124
> alGetSourcefv(source,AL_POSITION,PositionOrig);
229,230c233,238
< flVLS = aluDotproduct(ListenerVelocity, SourceToListener);
< flVSS = aluDotproduct(Velocity, SourceToListener);
---
> SourceToListenerOrig[0]=ListenerPositionOrig[0]-PositionOrig[0];
> SourceToListenerOrig[1]=ListenerPositionOrig[1]-PositionOrig[1];
> SourceToListenerOrig[2]=ListenerPositionOrig[2]-PositionOrig[2];
> aluNormalize(SourceToListenerOrig);
> flVLS = aluDotproduct(ListenerVelocity, SourceToListenerOrig);
> flVSS = aluDotproduct(Velocity, SourceToListenerOrig);
Sorry if I'm not making sense in my ramblings... hopefully this is a bit
clearer. I was suggesting the solution of transforming the velocity
vector of the source, without actually seeing to the core of where the
problem was... solution before the problem... cart before the horse... ;-)
Thanks,
Ed
Ed Phillips <ed at udel.edu> University of Delaware (302) 831-6082
Systems Programmer III, Network and Systems Services
More information about the Openal-devel
mailing list