FMOD documentation error - calculatePannerAttributes

Hi,
I am using a function from the fmod doc to pan the sound: calculatePannerAttributes.
However, it turned out that calculatePannerAttributes has errors.
I tried to fix these errors and at first everything seemed to be working fine.
However, when I placed the sound source position in the listener position and started to turn the listener, the sound could be heard depending on the degree of rotation once from the right speaker and once from the left speaker.
I noticed that pannerAttributes.relative.position.x and pannerAttributes.relative.position.z change their values to positive or negative even though they should be 0.
I am convinced that the error is in my corrected calculatePannerAttributes function, so please indicate it.
Below I put the calculatePannerAttributes function from the documentation with the commandments indicating errors, and below it calculatePannerAttributes corrected by me.

Documentation function:


void calculatePannerAttributes(const FMOD_3D_ATTRIBUTES &listenerAttributes, const FMOD_3D_ATTRIBUTES &emitterAttributes, FMOD_DSP_PARAMETER_3DATTRIBUTES &pannerAttributes)
{
    // pannerAttributes.relative is the emitter position and orientation transformed into the listener's space:

    // First we need the 3D transformation for the listener.
    Vec3f right = crossProduct(listenerAttributes.up, listenerAttributes.forward);

    Matrix44f listenerTransform;
    listenerTransform.X = Vec4f(right, 0.0f);
    listenerTransform.Y = Vec4f(up, 0.0f); // here is mistake
    listenerTransform.Z = Vec4f(forward, 0.0f); //here is mistake
    listenerTransform.W = Vec4f(listener.position, 1.0f); //here is mistake

    // Now we use the inverse of the listener's 3D transformation to transform the emitter attributes into the listener's space:
    Matrix44f invListenerTransform = inverse(listenerTransform);

    Vec4f position = invListenerTransform * Vec4f(emitterAttributes.position, 1.0f);

    // Setting the w component of the 4D vector to zero means the matrix multiplication will only rotate the vector.
    Vec4f forward = invListenerTransform * Vec4f(emitterAttributes.forward, 0.0f);
    Vec4f up = invListenerTransform * Vec4f(emitterAttributes.up, 0.0f);
    Vec4f velocity = Vec4f(listenerAttributes.velocity, 0.0f) + invListenerTransform * Vec4f(emitterAttributes.velocity, 0.0f);

    // We are now done computing the relative attributes.
    position.toFMOD(pannerAttributes.relative.position);
    velocity.toFMOD(pannerAttributes.relative.forward); //there must be a mistake
    up.toFMOD(pannerAttributes.relative.up);
    velocity.toFMOD(pannerAttributes.relative.velocity);

    // pannerAttributes.absolute is simply the emitter position and orientation:
    pannerAttributes.absolute = emitterAttributes;
}

Corrected by me function:


void calculatePannerAttributes(const FMOD_3D_ATTRIBUTES &listenerAttributes, const FMOD_3D_ATTRIBUTES &emitterAttributes, FMOD_DSP_PARAMETER_3DATTRIBUTES_MULTI &pannerAttributes)
{
// pannerAttributes.relative is the emitter position and orientation transformed into the listener's space:

// First we need the 3D transformation for the listener.
Vec3f right = crossProduct( listenerAttributes.up, listenerAttributes.forward);

Matrix44f listenerTransform = {};
listenerTransform.x = Vec4f(right, 0.0f);
listenerTransform.y = Vec4f(listenerAttributes.up, 0.0f);
listenerTransform.z = Vec4f(listenerAttributes.forward, 0.0f);
listenerTransform.w = Vec4f(listenerAttributes.position, 1.0f);

// Now we use the inverse of the listener's 3D transformation to transform the emitter attributes into the listener's space:
Matrix44f invListenerTransform = inverse(listenerTransform);

Vec4f position = invListenerTransform * Vec4f(emitterAttributes.position, 1.0f);

// Setting the w component of the 4D vector to zero means the matrix multiplication will only rotate the vector.
Vec4f forward = invListenerTransform * Vec4f(emitterAttributes.forward, 0.0f);
Vec4f up = invListenerTransform * Vec4f(emitterAttributes.up, 0.0f);
Vec4f velocity = Vec4f( listenerAttributes.velocity, 0.0f) + invListenerTransform * Vec4f(emitterAttributes.velocity, 0.0f);

// We are now done computing the relative attributes.
position.toFMOD(pannerAttributes.relative[0].position);
forward.toFMOD(pannerAttributes.relative[0].forward);
up.toFMOD(pannerAttributes.relative[0].up);
velocity.toFMOD(pannerAttributes.relative[0].velocity);


// pannerAttributes.absolute is simply the emitter position and orientation:
pannerAttributes.absolute = emitterAttributes;

}

Thanks for reporting this, I have added a task to correct this.

I’m glad that I could help, although I still have a problem.
I think I will wait until the documentation is corrected, maybe then I will know how to fix my bug.
Do you know how much time it may take to improve the documentation?