[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