OldUnreal / UnrealTournamentPatches

Other
999 stars 29 forks source link

[469c] OpenAL spatialized (HRTF) sound shifting #1338

Closed main-exe closed 1 year ago

main-exe commented 1 year ago

Sound has a sudden shift when "OpenAL 3D" audio driver is used with HRTF on. Easily noticeable by moving mouse up-down when opponent is shooting minigun in front.

Same behavior with "469b" and "469c" patches. Tested different "OpenAL32.dll" versions and default HRTF, same behavior.

There is a way to restore original "A3D" audio by using - "Galaxy 3D" + "A3D Alchemy" + "DSOAL" + "OpenAL".
It is a bit tricky to make it work, but it does not have this sound shifting issue.

Other games that use "OpenAL" are fine, so most likely the bug is in "ALAudio.dll".

To reproduce:

Since HRTF is being used, listening must be done with headphones.

All audio enhancing must be turned off i.e. Windows Sonic for Headphones, Steelseries Sonar, Creative enhancements, Razer 7.1 Surround Sound, ... Otherwise proper 3D spatial audio might not be heard.

First 26s of this video provide a guide and audio test: https://www.youtube.com/watch?v=VCXQp7swp5k

  1. Extract attached files based on your sound card's sample rate to game's "System" folder _"alsoft.ini" forces HRTF on and "irc_1037xxxxx.mhr" to be used

  2. Set "Audio Driver" in "Preferences - Audio" to "OpenAL 3D"

  3. Start some match and move mouse cursor up-down while opponent is shooting with minigun. Can notice sudden frequency shifts near i.e. torches too (easier noticeable with "irc_1037" HRTF than default HRTF).

44100.zip 48000.zip

https://github.com/OldUnreal/UnrealTournamentPatches/assets/123046382/a245e2fa-849f-48e8-86f0-9a00ec7cfd36

https://github.com/OldUnreal/UnrealTournamentPatches/assets/123046382/7541f9f0-e5dc-4189-9504-c038ae90183d

In UT4 (UE4) OpenAL audio module had coordinate transformation issue too. I fixed it and compiled it for Windows version of UT4 (UT4-OpenAL). OpenAL originally was only used in Linux version.

Matrix based transformation is being used to change from UE's coordinates to OpenAL's coordinates. Obviously UE1 is old, but maybe the way it is done in UE4 could be useful to resolve this.

I could post code how it is done in UT4 if that could help.

SeriousBuggie commented 1 year ago

From discord conversation:

Issue come from code in LAudioSoundInstance::UpdateEmission:

    // Update source's position and velocity.
    if ( (Slot == SLOT_Ambient) && (Radius > 1) )
    {
        // Higor's whacky formulas for ambient despatialization
        FLOAT MinRadius = Min<FLOAT>( 10 + appSqrt(Radius), (Radius-1500) * 0.5 );
        FVector RelativePosition = Actor->Location - ListenerCoords.Origin;
        FVector TransformedPosition = RelativePosition.TransformVectorBy(ListenerCoords);

        FLOAT Distance = RelativePosition.Size();
        FLOAT AmbientDirectionality = Clamp<FLOAT>( (Distance - MinRadius) / (Radius - MinRadius), 0, 0.99f);

        // Push upwards or downwards.
        if (AmbientDirectionality > 0.f)
        {
            FLOAT YTransform = appSqrt( Square(TransformedPosition.X) + Square(TransformedPosition.Z)) * (1.0f - AmbientDirectionality) / AmbientDirectionality;
            if ( TransformedPosition.Y < 0 )
                RelativePosition -= ListenerCoords.YAxis * YTransform;
            else
                RelativePosition += ListenerCoords.YAxis * YTransform;
        }
        // Fix distance
        SetLocation( ListenerCoords.Origin + RelativePosition.SafeNormal() * Distance);
    }
    else
        SetLocation(Actor->Location);
    SetVelocity(Actor->Velocity);

Which look as some hack added by @CacoFFF If comment out whole if (AmbientDirectionality > 0.f) then sound location not changed. And sound not float, when you turn camera. However not clear what reason for introduce such hack and what problem it intended to solve.

There example of jumpy coordinates when rotate camera:

https://cdn.discordapp.com/attachments/645560317086269441/1143063589415043072/sound_bug.mp4

And image which show, how location of sound changed, when camera cross horizon:

scr_1692598091

Also here changes for RelativePosition in SetLocation( ListenerCoords.Origin + RelativePosition.SafeNormal() * Distance); when cross horizon. scr_1692601960

SeriousBuggie commented 1 year ago

Example of implementation:

https://cdn.discordapp.com/attachments/645560317086269441/1147581859698581605/test_snd2.mp4

main-exe commented 1 year ago

Good, position does not shift anymore