Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore EAX effects through OpenAL's EFX. #1000

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Deledrius
Copy link
Member

This re-implements the supported EAX effects using OpenAL's EFX. Some features (such as occlusion effects) are currently unsupported by OpenAL and required conversion or local implementation.

Copy link
Member

@Hoikas Hoikas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These single byte string literals will be reinterpreted as UCS-2 on 3ds Max >= 2013, resulting in garbled UI strings.

static int oldTime = timeGetTime(); // Get starting time
int newTime;
EFXEAXREVERBPROPERTIES finalProps;
static auto oldTime = std::chrono::steady_clock::now(); // Get starting time
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be using something from hsTimer instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bump

// change due to opt out(caching) feature.
if(bMorphing)
{
newTime = timeGetTime();
auto newTime = std::chrono::steady_clock::now();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hsTimer?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bump

Comment on lines 214 to 239
s->WriteLE32((uint32_t)eaxListenerProps->ulEnvironment);
s->WriteLEFloat(eaxListenerProps->flEnvironmentSize);
s->WriteLEFloat(eaxListenerProps->flEnvironmentDiffusion);
s->WriteLE32((int32_t)eaxListenerProps->lRoom);
s->WriteLE32((int32_t)eaxListenerProps->lRoomHF);
s->WriteLE32((int32_t)eaxListenerProps->lRoomLF);
s->WriteLEFloat(eaxListenerProps->flDecayTime);
s->WriteLEFloat(eaxListenerProps->flDecayHFRatio);
s->WriteLEFloat(eaxListenerProps->flDecayLFRatio);
s->WriteLE32((int32_t)eaxListenerProps->lReflections);
s->WriteLEFloat(eaxListenerProps->flReflectionsDelay);
//s->WriteLEFloat( eaxListenerProps->vReflectionsPan; // early reflections panning vector
s->WriteLE32((int32_t)eaxListenerProps->lReverb); // late reverberation level relative to room effect
s->WriteLEFloat(eaxListenerProps->flReverbDelay);
//s->WriteLEFloat( eaxListenerProps->vReverbPan; // late reverberation panning vector
s->WriteLEFloat(eaxListenerProps->flEchoTime);
s->WriteLEFloat(eaxListenerProps->flEchoDepth);
s->WriteLEFloat(eaxListenerProps->flModulationTime);
s->WriteLEFloat(eaxListenerProps->flModulationDepth);
s->WriteLEFloat(eaxListenerProps->flAirAbsorptionHF);
s->WriteLEFloat(eaxListenerProps->flHFReference);
s->WriteLEFloat(eaxListenerProps->flLFReference);
s->WriteLEFloat(eaxListenerProps->flRoomRolloffFactor);
s->WriteLE32((uint32_t)eaxListenerProps->ulFlags);

delete eaxListenerProps;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
s->WriteLE32((uint32_t)eaxListenerProps->ulEnvironment);
s->WriteLEFloat(eaxListenerProps->flEnvironmentSize);
s->WriteLEFloat(eaxListenerProps->flEnvironmentDiffusion);
s->WriteLE32((int32_t)eaxListenerProps->lRoom);
s->WriteLE32((int32_t)eaxListenerProps->lRoomHF);
s->WriteLE32((int32_t)eaxListenerProps->lRoomLF);
s->WriteLEFloat(eaxListenerProps->flDecayTime);
s->WriteLEFloat(eaxListenerProps->flDecayHFRatio);
s->WriteLEFloat(eaxListenerProps->flDecayLFRatio);
s->WriteLE32((int32_t)eaxListenerProps->lReflections);
s->WriteLEFloat(eaxListenerProps->flReflectionsDelay);
//s->WriteLEFloat( eaxListenerProps->vReflectionsPan; // early reflections panning vector
s->WriteLE32((int32_t)eaxListenerProps->lReverb); // late reverberation level relative to room effect
s->WriteLEFloat(eaxListenerProps->flReverbDelay);
//s->WriteLEFloat( eaxListenerProps->vReverbPan; // late reverberation panning vector
s->WriteLEFloat(eaxListenerProps->flEchoTime);
s->WriteLEFloat(eaxListenerProps->flEchoDepth);
s->WriteLEFloat(eaxListenerProps->flModulationTime);
s->WriteLEFloat(eaxListenerProps->flModulationDepth);
s->WriteLEFloat(eaxListenerProps->flAirAbsorptionHF);
s->WriteLEFloat(eaxListenerProps->flHFReference);
s->WriteLEFloat(eaxListenerProps->flLFReference);
s->WriteLEFloat(eaxListenerProps->flRoomRolloffFactor);
s->WriteLE32((uint32_t)eaxListenerProps->ulFlags);
delete eaxListenerProps;
s->WriteLE32((uint32_t)eaxListenerProps.ulEnvironment);
s->WriteLEFloat(eaxListenerProps.flEnvironmentSize);
s->WriteLEFloat(eaxListenerProps.flEnvironmentDiffusion);
s->WriteLE32((int32_t)eaxListenerProps.lRoom);
s->WriteLE32((int32_t)eaxListenerProps.lRoomHF);
s->WriteLE32((int32_t)eaxListenerProps.lRoomLF);
s->WriteLEFloat(eaxListenerProps.flDecayTime);
s->WriteLEFloat(eaxListenerProps.flDecayHFRatio);
s->WriteLEFloat(eaxListenerProps.flDecayLFRatio);
s->WriteLE32((int32_t)eaxListenerProps.lReflections);
s->WriteLEFloat(eaxListenerProps.flReflectionsDelay);
//s->WriteLEFloat( eaxListenerProps.vReflectionsPan; // early reflections panning vector
s->WriteLE32((int32_t)eaxListenerProps.lReverb); // late reverberation level relative to room effect
s->WriteLEFloat(eaxListenerProps.flReverbDelay);
//s->WriteLEFloat( eaxListenerProps.vReverbPan; // late reverberation panning vector
s->WriteLEFloat(eaxListenerProps.flEchoTime);
s->WriteLEFloat(eaxListenerProps.flEchoDepth);
s->WriteLEFloat(eaxListenerProps.flModulationTime);
s->WriteLEFloat(eaxListenerProps.flModulationDepth);
s->WriteLEFloat(eaxListenerProps.flAirAbsorptionHF);
s->WriteLEFloat(eaxListenerProps.flHFReference);
s->WriteLEFloat(eaxListenerProps.flLFReference);
s->WriteLEFloat(eaxListenerProps.flRoomRolloffFactor);
s->WriteLE32((uint32_t)eaxListenerProps.ulFlags);

}


void plEAXListenerMod::SetFromPreset( uint32_t preset )
void plEAXListenerMod::SetFromEFXPreset(EFXEAXREVERBPROPERTIES preset)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void plEAXListenerMod::SetFromEFXPreset(EFXEAXREVERBPROPERTIES preset)
void plEAXListenerMod::SetFromEFXPreset(const EFXEAXREVERBPROPERTIES& preset)

EAXREVERBPROPERTIES * GetListenerProps() { return fListenerProps; }
void SetFromPreset( uint32_t preset );
EFXEAXREVERBPROPERTIES *GetListenerProps() { return fListenerProps; }
void SetFromEFXPreset(EFXEAXREVERBPROPERTIES preset);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
void SetFromEFXPreset(EFXEAXREVERBPROPERTIES preset);
void SetFromEFXPreset(const EFXEAXREVERBPROPERTIES& preset);

Comment on lines 2996 to 2997
// Set params based on artist selections
EAXREVERBPROPERTIES *eaxProps = new EAXREVERBPROPERTIES;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Set params based on artist selections
EAXREVERBPROPERTIES *eaxProps = new EAXREVERBPROPERTIES;
// Set params based on artist selections
EAXREVERBPROPERTIES eaxProps;

Comment on lines 3000 to 3026
eaxProps->flEnvironmentSize = fCompPB->GetFloat( (ParamID)kRefEnvironmentSize );
eaxProps->flEnvironmentDiffusion = fCompPB->GetFloat( (ParamID)kRefEnvironmentDiffusion );
eaxProps->lRoom = fCompPB->GetInt( (ParamID)kRefRoom );
eaxProps->lRoomHF = fCompPB->GetInt( (ParamID)kRefRoomHF );
eaxProps->lRoomLF = fCompPB->GetInt( (ParamID)kRefRoomLF );
eaxProps->flDecayTime = fCompPB->GetFloat( (ParamID)kRefDecayTime );
eaxProps->flDecayHFRatio = fCompPB->GetFloat( (ParamID)kRefDecayHFRatio );
eaxProps->flDecayLFRatio = fCompPB->GetFloat( (ParamID)kRefDecayLFRatio );
eaxProps->lReflections = fCompPB->GetInt( (ParamID)kRefReflections );
eaxProps->flReflectionsDelay = fCompPB->GetFloat( (ParamID)kRefReflectionsDelay );
//eaxProps->vReflectionsPan; // early reflections panning vector
eaxProps->lReverb = fCompPB->GetInt( (ParamID)kRefReverb ); // late reverberation level relative to room effect
eaxProps->flReverbDelay = fCompPB->GetFloat( (ParamID)kRefReverbDelay );
//eaxProps->vReverbPan; // late reverberation panning vector
eaxProps->flEchoTime = fCompPB->GetFloat( (ParamID)kRefEchoTime );
eaxProps->flEchoDepth = fCompPB->GetFloat( (ParamID)kRefEchoDepth );
eaxProps->flModulationTime = fCompPB->GetFloat( (ParamID)kRefModulationTime );
eaxProps->flModulationDepth = fCompPB->GetFloat( (ParamID)kRefModulationDepth );
eaxProps->flAirAbsorptionHF = fCompPB->GetFloat( (ParamID)kRefAirAbsorptionHF );
eaxProps->flHFReference = fCompPB->GetFloat( (ParamID)kRefHFReference );
eaxProps->flLFReference = fCompPB->GetFloat( (ParamID)kRefLFReference );
eaxProps->flRoomRolloffFactor = fCompPB->GetFloat( (ParamID)kRefRoomRolloffFactor );
eaxProps->ulFlags = fCompPB->GetInt( (ParamID)kRefFlags );

// Convert to EFX and store them
plEAXListenerMod::ConvertEAXToEFX(eaxProps, listener->GetListenerProps());
delete eaxProps;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
eaxProps->flEnvironmentSize = fCompPB->GetFloat( (ParamID)kRefEnvironmentSize );
eaxProps->flEnvironmentDiffusion = fCompPB->GetFloat( (ParamID)kRefEnvironmentDiffusion );
eaxProps->lRoom = fCompPB->GetInt( (ParamID)kRefRoom );
eaxProps->lRoomHF = fCompPB->GetInt( (ParamID)kRefRoomHF );
eaxProps->lRoomLF = fCompPB->GetInt( (ParamID)kRefRoomLF );
eaxProps->flDecayTime = fCompPB->GetFloat( (ParamID)kRefDecayTime );
eaxProps->flDecayHFRatio = fCompPB->GetFloat( (ParamID)kRefDecayHFRatio );
eaxProps->flDecayLFRatio = fCompPB->GetFloat( (ParamID)kRefDecayLFRatio );
eaxProps->lReflections = fCompPB->GetInt( (ParamID)kRefReflections );
eaxProps->flReflectionsDelay = fCompPB->GetFloat( (ParamID)kRefReflectionsDelay );
//eaxProps->vReflectionsPan; // early reflections panning vector
eaxProps->lReverb = fCompPB->GetInt( (ParamID)kRefReverb ); // late reverberation level relative to room effect
eaxProps->flReverbDelay = fCompPB->GetFloat( (ParamID)kRefReverbDelay );
//eaxProps->vReverbPan; // late reverberation panning vector
eaxProps->flEchoTime = fCompPB->GetFloat( (ParamID)kRefEchoTime );
eaxProps->flEchoDepth = fCompPB->GetFloat( (ParamID)kRefEchoDepth );
eaxProps->flModulationTime = fCompPB->GetFloat( (ParamID)kRefModulationTime );
eaxProps->flModulationDepth = fCompPB->GetFloat( (ParamID)kRefModulationDepth );
eaxProps->flAirAbsorptionHF = fCompPB->GetFloat( (ParamID)kRefAirAbsorptionHF );
eaxProps->flHFReference = fCompPB->GetFloat( (ParamID)kRefHFReference );
eaxProps->flLFReference = fCompPB->GetFloat( (ParamID)kRefLFReference );
eaxProps->flRoomRolloffFactor = fCompPB->GetFloat( (ParamID)kRefRoomRolloffFactor );
eaxProps->ulFlags = fCompPB->GetInt( (ParamID)kRefFlags );
// Convert to EFX and store them
plEAXListenerMod::ConvertEAXToEFX(eaxProps, listener->GetListenerProps());
delete eaxProps;
eaxProps.flEnvironmentSize = fCompPB->GetFloat( (ParamID)kRefEnvironmentSize );
eaxProps.flEnvironmentDiffusion = fCompPB->GetFloat( (ParamID)kRefEnvironmentDiffusion );
eaxProps.lRoom = fCompPB->GetInt( (ParamID)kRefRoom );
eaxProps.lRoomHF = fCompPB->GetInt( (ParamID)kRefRoomHF );
eaxProps.lRoomLF = fCompPB->GetInt( (ParamID)kRefRoomLF );
eaxProps.flDecayTime = fCompPB->GetFloat( (ParamID)kRefDecayTime );
eaxProps.flDecayHFRatio = fCompPB->GetFloat( (ParamID)kRefDecayHFRatio );
eaxProps.flDecayLFRatio = fCompPB->GetFloat( (ParamID)kRefDecayLFRatio );
eaxProps.lReflections = fCompPB->GetInt( (ParamID)kRefReflections );
eaxProps.flReflectionsDelay = fCompPB->GetFloat( (ParamID)kRefReflectionsDelay );
//eaxProps.vReflectionsPan; // early reflections panning vector
eaxProps.lReverb = fCompPB->GetInt( (ParamID)kRefReverb ); // late reverberation level relative to room effect
eaxProps.flReverbDelay = fCompPB->GetFloat( (ParamID)kRefReverbDelay );
//eaxProps.vReverbPan; // late reverberation panning vector
eaxProps.flEchoTime = fCompPB->GetFloat( (ParamID)kRefEchoTime );
eaxProps.flEchoDepth = fCompPB->GetFloat( (ParamID)kRefEchoDepth );
eaxProps.flModulationTime = fCompPB->GetFloat( (ParamID)kRefModulationTime );
eaxProps.flModulationDepth = fCompPB->GetFloat( (ParamID)kRefModulationDepth );
eaxProps.flAirAbsorptionHF = fCompPB->GetFloat( (ParamID)kRefAirAbsorptionHF );
eaxProps.flHFReference = fCompPB->GetFloat( (ParamID)kRefHFReference );
eaxProps.flLFReference = fCompPB->GetFloat( (ParamID)kRefLFReference );
eaxProps.flRoomRolloffFactor = fCompPB->GetFloat( (ParamID)kRefRoomRolloffFactor );
eaxProps.ulFlags = fCompPB->GetInt( (ParamID)kRefFlags );
// Convert to EFX and store them
plEAXListenerMod::ConvertEAXToEFX(&eaxProps, listener->GetListenerProps());

@patmauro
Copy link
Contributor

patmauro commented Jul 21, 2023

If there's any interest in dusting this one off again, I would love to help in any way I can, depending on what the current blockers may be. This feature in particular is very near and dear to me - URU has never quite felt like URU without it, and getting this functionality restored even partially would be a tremendously huge W. So again, please let me know if I can be of any assistance here; my C++ is a little rusty, but I'm certainly no stranger to reviewing scripts and running tests.

Here's a thought - on the front-end side, in addition to the simple change of "Enable EAX" to "Enable EFX" in the options menu (there doesn't really seem to be room in the GUI for a description more detailed than that, unfortunately), we'll probably want to replace that "EAX ADVANCED HD" graphic at the bottom of the audio menu with a more generic OpenAL one as well. This would require a modification to the xoptionsguicomponents texture contained inside GUI_District_OptionsMenuGUI.prp - we don't have a source for this one (the version of this we have in the source files is from CC and is quite different), so as usual, the trick here would be figuring out how to modify this texture without introducing any new compression artifacts to the rest of the texture sheet. (Granted - this wouldn't be covered by this PR and would require a separate PR to moul-assets, but it seemed relevant to mention here.) (Edit: addressed by H-uru/moul-assets#251)

@Deledrius
Copy link
Member Author

Deledrius commented Jul 21, 2023

No dusting off necessary, I've been actively working on this.

Updating the in-game text and graphics will definitely be something we'll need. I'll let you know when I get close to that stage!

@patmauro
Copy link
Contributor

patmauro commented Jul 21, 2023

No dusting off necessary, I've been actively working on this.

Updating the in-game text and graphics will definitely be something we'll need. I'll let you know when I get close to that stage!

Sounds good. 🙂 In any case, the offer stands; happy to make myself available if you need an extra set of hands.

I may go ahead and look into a PR for that graphic in moul-assets unless there's any objection... seems like it might not be a bad idea to start ditching the user-facing EAX references anyway, regardless of the status of the EFX project. 🤔 (Edit: addressed by H-uru/moul-assets#251)

@Deledrius
Copy link
Member Author

Sure, go ahead. We can replace that texture with a lossless one if it isn't already, so additional edits won't introduce any generational loss. I can't check on this at the moment, but feel free to start on a plan for it!

Copy link
Member

@dpogue dpogue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it seem feasible to wrap this in USE_EFX conditionally, or is that going to turn into a mess of ifdefs everywhere? The AL_AUXILIARY_SEND_FILTER stuff seems like the worst in terms of wrapping, but maybe we can turn that into a conditional macro?

Comment on lines -44 to -46
#ifdef USE_EFX
# include <efx.h>
#endif
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To slightly complicate things, there are some OpenAL implementations (Apple) that don't ship the EFX header, which is why this was conditionally detected.

All of our builds use vcpkg which uses openal-soft, which includes EFX, but it would be nice to still gracefully fall back to no effects if EFX can't be found

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that's unfortunate. I did this assuming we'd be using the same library across the different platforms, where OpenAL-soft provides this for us without variability.

It does complicate things, but I can see about re-introducing proper conditional support.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it turns out to be a mess, we're probably okay to mandate OpenAL-Soft.

It's just nice to fallback to system libraries on weird old systems where you don't feel like trying to compile extra dependencies 😛

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's a good idea. I just assumed I could simplify that code a bit and took the opportunity to clean it out. ;)

@patmauro
Copy link
Contributor

Loading in this latest draft and testing it out put an enormous smile on my face. You've done something important here, @Deledrius, and should feel very proud.

One note - since the Audio.UseEAX syntax has been changed to Audio.UseEFX, the app will throw an error if an existing audio.ini config file exists in local AppData with the old syntax - even if you "press OK to continue parsing files," it seemingly won't, and will launch in 800x600 with no sound - I had to purge the existing (username)/AppData/Local/Uru Live/ dir and let it regenerate to get it to cooperate. May not be a bad idea to gracefully handle the old ini syntax to account for this (even if it just specifically calls this out as something to ignore).

@dpogue
Copy link
Member

dpogue commented Feb 21, 2025

One note - since the Audio.UseEAX syntax has been changed to Audio.UseEFX, the app will throw an error if an existing audio.ini config file exists in local AppData with the old syntax

I was thinking about this and almost left a comment when I reviewed the code last night, but thought "EAX hasn't worked for years, how likely is it that anyone even has MOULa config files with that option enabled?"

I guess it is a possibility, and maybe supporting both commands (or at least support parsing the UseEAX one with no implementation) might be best.

@Deledrius
Copy link
Member Author

Deledrius commented Feb 21, 2025

"EAX hasn't worked for years, how likely is it that anyone even has MOULa config files with that option enabled?"

That was my thinking, too, when I changed it; but I'm fairly certain I changed code that's been writing out the old settings (as false) all this time, so the answer is probably "everyone".

Sounds like the correct solution here is to figure out why we're not ignoring it gracefully and fix that. It should simply be able to ignore an unknown value and continue without nuking everything.

Thanks for catching this. These conceptual issues are useful at this stage of the WIP. :)

@Hoikas
Copy link
Member

Hoikas commented Feb 22, 2025

Given that we have lots of config files running around out there that use the command Audio.UseEAX, I think it's critical that the command remain named thusly. I realize that this is a someone inaccurate name, but sometimes we have to make concessions for ease of use. Further, we can't really control what client the user is running at all, so it's important that we don't start dumping Audio.UseEFX into files as well. If the user runs an old client, and the file contains that command, their old client will error. This will even happen on even slightly out of date H'uru clients. We don't want that.

We don't want to remove this error either. That error is coming from the pfConsole command parser. We want the console to tell us when it receives an invalid input. We don't want it to simply drop unknown commands on the floor. This is an indication that something is wrong. Like someone has edited the FNI file and misspelled something.

I think I would actually go a step farther than this and say since the classes are all still named plEAXWhatever, and we're leaving the console command as Audio.UseEAX, that we shouldn't change any of the engine's function or variable names at all to EFX from EAX. While this change does clarify the underlying backend for environmental audio effects, in practice it muddies the water significantly for anyone who wants to maintain something like a Python script for both TPotS and H'uru. However, we should definitely update the user facing strings to refer to EFX.

Copy link
Member

@Hoikas Hoikas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some additional review items on top of the concerns from the PR comment about naming. Also, it would be nice if we could cull the no-op whitespace changes to make reviewing easier.


inline float lerp(float start, float finish, float ratio) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
inline float lerp(float start, float finish, float ratio) {
constexpr static float lerp(float start, float finish, float ratio) {


plEAXListener &plEAXListener::GetInstance()
bool ReverbPropsInterpolate(LPEFXEAXREVERBPROPERTIES lpStart, LPEFXEAXREVERBPROPERTIES lpFinish,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool ReverbPropsInterpolate(LPEFXEAXREVERBPROPERTIES lpStart, LPEFXEAXREVERBPROPERTIES lpFinish,
static bool ReverbPropsInterpolate(LPEFXEAXREVERBPROPERTIES lpStart, LPEFXEAXREVERBPROPERTIES lpFinish,

Comment on lines +98 to +105
lpResult->flDecayTime = (float)exp(lerp(log(lpStart->flDecayTime), log(lpFinish->flDecayTime), flRatio));
lpResult->flDecayHFRatio = (float)exp(lerp(log(lpStart->flDecayHFRatio), log(lpFinish->flDecayHFRatio), flRatio));
lpResult->flDecayLFRatio = (float)exp(lerp(log(lpStart->flDecayLFRatio), log(lpFinish->flDecayLFRatio), flRatio));
lpResult->flReflectionsGain = lerp(lpStart->flReflectionsGain, lpFinish->flReflectionsGain, flRatio);
lpResult->flReflectionsDelay = (float)exp(lerp(log(lpStart->flReflectionsDelay), log(lpFinish->flReflectionsDelay), flRatio));
lpResult->flLateReverbGain = lerp(lpStart->flLateReverbGain, lpFinish->flLateReverbGain, flRatio);
lpResult->flLateReverbDelay = (float)exp(lerp(log(lpStart->flLateReverbDelay), log(lpFinish->flLateReverbDelay), flRatio));
lpResult->flEchoTime = (float)exp(lerp(log(lpStart->flEchoTime), log(lpFinish->flEchoTime), flRatio));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
lpResult->flDecayTime = (float)exp(lerp(log(lpStart->flDecayTime), log(lpFinish->flDecayTime), flRatio));
lpResult->flDecayHFRatio = (float)exp(lerp(log(lpStart->flDecayHFRatio), log(lpFinish->flDecayHFRatio), flRatio));
lpResult->flDecayLFRatio = (float)exp(lerp(log(lpStart->flDecayLFRatio), log(lpFinish->flDecayLFRatio), flRatio));
lpResult->flReflectionsGain = lerp(lpStart->flReflectionsGain, lpFinish->flReflectionsGain, flRatio);
lpResult->flReflectionsDelay = (float)exp(lerp(log(lpStart->flReflectionsDelay), log(lpFinish->flReflectionsDelay), flRatio));
lpResult->flLateReverbGain = lerp(lpStart->flLateReverbGain, lpFinish->flLateReverbGain, flRatio);
lpResult->flLateReverbDelay = (float)exp(lerp(log(lpStart->flLateReverbDelay), log(lpFinish->flLateReverbDelay), flRatio));
lpResult->flEchoTime = (float)exp(lerp(log(lpStart->flEchoTime), log(lpFinish->flEchoTime), flRatio));
lpResult->flDecayTime = expf(lerp(logf(lpStart->flDecayTime), logf(lpFinish->flDecayTime), flRatio));
lpResult->flDecayHFRatio = expf(lerp(logf(lpStart->flDecayHFRatio), logf(lpFinish->flDecayHFRatio), flRatio));
lpResult->flDecayLFRatio = expf(lerp(logf(lpStart->flDecayLFRatio), logf(lpFinish->flDecayLFRatio), flRatio));
lpResult->flReflectionsGain = lerp(lpStart->flReflectionsGain, lpFinish->flReflectionsGain, flRatio);
lpResult->flReflectionsDelay = expf(lerp(logf(lpStart->flReflectionsDelay), logf(lpFinish->flReflectionsDelay), flRatio));
lpResult->flLateReverbGain = lerp(lpStart->flLateReverbGain, lpFinish->flLateReverbGain, flRatio);
lpResult->flLateReverbDelay = expf(lerp(logf(lpStart->flLateReverbDelay), logf(lpFinish->flLateReverbDelay), flRatio));
lpResult->flEchoTime = expf(lerp(logf(lpStart->flEchoTime), logf(lpFinish->flEchoTime), flRatio));

lpResult->flLateReverbDelay = (float)exp(lerp(log(lpStart->flLateReverbDelay), log(lpFinish->flLateReverbDelay), flRatio));
lpResult->flEchoTime = (float)exp(lerp(log(lpStart->flEchoTime), log(lpFinish->flEchoTime), flRatio));
lpResult->flEchoDepth = lerp(lpStart->flEchoDepth, lpFinish->flEchoDepth, flRatio);
lpResult->flModulationTime = (float)exp(lerp(log(lpStart->flModulationTime), log(lpFinish->flModulationTime), flRatio));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
lpResult->flModulationTime = (float)exp(lerp(log(lpStart->flModulationTime), log(lpFinish->flModulationTime), flRatio));
lpResult->flModulationTime = expf(lerp(log(lpStart->flModulationTime), logf(lpFinish->flModulationTime), flRatio));

Comment on lines +110 to +111
lpResult->flHFReference = (float)exp(lerp(log(lpStart->flHFReference), log(lpFinish->flHFReference), flRatio));
lpResult->flLFReference = (float)exp(lerp(log(lpStart->flLFReference), log(lpFinish->flLFReference), flRatio));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
lpResult->flHFReference = (float)exp(lerp(log(lpStart->flHFReference), log(lpFinish->flHFReference), flRatio));
lpResult->flLFReference = (float)exp(lerp(log(lpStart->flLFReference), log(lpFinish->flLFReference), flRatio));
lpResult->flHFReference = expf(lerp(logf(lpStart->flHFReference), logf(lpFinish->flHFReference), flRatio));
lpResult->flLFReference = expf(lerp(logf(lpStart->flLFReference), logf(lpFinish->flLFReference), flRatio));

@@ -201,18 +189,16 @@ class plEAXSource
friend class plEAXSourceSettings;
friend class plEAXSourceSoftSettings;

plEAXSource();
virtual ~plEAXSource();
plEAXSource() : fInit(false) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bump


/* Helper functions for converting to EFX from deprecated EAX values */

#include <math.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this include to the top of the file.

return 2000.0f * log10f(gain);
}

LPEFXEAXREVERBPROPERTIES ConvertEAXToEFX(const LPEAXLISTENERPROPERTIES eax)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LPEFXEAXREVERBPROPERTIES ConvertEAXToEFX(const LPEAXLISTENERPROPERTIES eax)
static LPEFXEAXREVERBPROPERTIES ConvertEAXToEFX(const LPEAXLISTENERPROPERTIES eax)

return efx;
}

LPEAXLISTENERPROPERTIES ConvertEFXToEAX(const LPEFXEAXREVERBPROPERTIES efx)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LPEAXLISTENERPROPERTIES ConvertEFXToEAX(const LPEFXEAXREVERBPROPERTIES efx)
static LPEAXLISTENERPROPERTIES ConvertEFXToEAX(const LPEFXEAXREVERBPROPERTIES efx)

Comment on lines +55 to +56
#include <efx.h>
#include <efx-presets.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to avoid including this library header in our headers. Are there any forward declarations we can use?

@patmauro
Copy link
Contributor

Given that we have lots of config files running around out there that use the command Audio.UseEAX, I think it's critical that the command remain named thusly. I realize that this is a someone inaccurate name, but sometimes we have to make concessions for ease of use.

Just FYI, I noticed that the "old" ini I cleared out appeared to already have entries for both Audio.UseEAX and Audio.UseEFX - so it seems like this had already been happily working in parallel prior to this PR, and something about the specific changes here may have simply rendered the "EAX" syntax invalid - not to mention, it seems to suggest that the config file seems to have made it through the switchover to the "EFX" syntax with no issues, so long as the legacy term was still considered valid.

So it might be sufficient to revert whatever did that, but - to your point, maybe consistently using the legacy term (at least internally) would be best. In any case, just wanted to provide that additional context - I trust you guys will determine what makes the most sense here. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cleanup sound to remove EAX dependencies
5 participants