Jump to content
The Dark Mod Forums

Getting started with the EFX room reverb system (wip)


peter_spy
 Share

Recommended Posts

1. A large outdoor environment

2. A series of small underground caves/tunnels

3. A typical series of indoor rooms

4. A large ballroom or other indoor space

+1, I will add this to my Elixir WIP, so EFX can be added to the list of things that mappers can learn from this map!

 

@Judith I will PM you so we can work it before you add it to your OP if thats ok?

Edited by Bikerdude
  • Like 2
Link to comment
Share on other sites

Some kind of simplified instructions are desperately needed, so thanks for taking this on.

 

As a mapper, what I'd love to have are a set of values for typical TDM environments. For example, what values would a mapper use to create:

 

1. A large outdoor environment

2. A series of small underground caves/tunnels

3. A typical series of indoor rooms

4. A large ballroom or other indoor space

etc

 

My thoughts exactly, we need a set of templates and guidelines, so mappers can start with something, and then adjust values to their liking.

 

 

+1 so I will add this to my Elixir WIP, so EFX can be added to the list of things that mappers can learn from this map!

 

@Judith I will PM you so we can work it before you added it to your OP if thats ok?

 

Sure! Again, I can't say I understand how all values work (I still haven't touched stuff like environment size or environment diffusion), but we should be able to come up with something by just using main values.

Link to comment
Share on other sites

Also, testing these settings can be time-consuming; for now we don't have other means than restarting the game (reloadengine, map) to see any changes.

I have already made changes in SVN, so that "reloadSounds" command reloads the EFX file too.

So unless it gets into the "missed the train and has to wait for the next train" category, I hope it would be in 2.06 :D

 

Create 'efxs' folder in your project root folder, create a text file map_name.efx, and open it. Now, first thing EFX system needs is a version number, so every .efx file needs start with Version 1 (I don't think any other number works).

This is correct, according to what I see in the code.

No idea why "Version 1" is necessary, since no other version number is accepted :laugh:

 

It seems like you don't need to include every parameter you see in the Wiki reference. Some variables don't do much or hardly do anything. Even if you delete something, the system will use the default value. You can have an empty set like above, and you won't break anything. You can also change the order of parameters, e.g. if you have your own workflow.

This seems to be right.

When you specify a parameter, TDM asks OpenAL to take it into account (using alEffectfv method). When you don't specify it, or you specify wrong value, then TDM simply does not tell OpenAL about it. Most likely OpenAL takes default value in this case. If you specify wrong value, you will see a warning in console.

 

 

Main values

Well, I can try to explain how to read official docs on these values.

 

First of all, open page 66 of Effects Extentions Guide of OpenAL. Here you see the table of parameters for AL_EFFECT_EAXREVERB. They are mostly the same as the parameters described in EFX file, with two differences:

  • Names are a bit different. Everything starting with "reverb" maps to LATE_REVERB, some names without last word map to GAIN (e.g. "reflections" maps to AL_EAXREVERB_REFLECTIONS_GAIN), "room" maps to "GAIN", etc.
  • Everything looking like "gain" must be specified in millibels in EFX file, while in OpenAL EFX they are described by gain factor. So keep in mind that values are quite different for such parameters.

And for code-literate geeks, here is the exact code which converts EFX file parameters into OpenAL EFX parameters:

 

if ( token == "environment" ) {

// <+KittyCat> the "environment" token should be ignored (efx has nothing equatable to it)

src.ParseInt();

} else if ( token == "environment size" ) {

float size = src.ParseFloat();

efxf(AL_EAXREVERB_DENSITY, (size < 2.0f) ? (size - 1.0f) : 1.0f);

} else if ( token == "environment diffusion" ) {

efxf(AL_EAXREVERB_DIFFUSION, src.ParseFloat());

} else if ( token == "room" ) {

efxf(AL_EAXREVERB_GAIN, mB_to_gain(src.ParseInt(), GAIN));

} else if ( token == "room hf" ) {

efxf(AL_EAXREVERB_GAINHF, mB_to_gain(src.ParseInt(), GAINHF));

} else if ( token == "room lf" ) {

efxf(AL_EAXREVERB_GAINLF, mB_to_gain(src.ParseInt(), GAINLF));

} else if ( token == "decay time" ) {

efxf(AL_EAXREVERB_DECAY_TIME, src.ParseFloat());

} else if ( token == "decay hf ratio" ) {

efxf(AL_EAXREVERB_DECAY_HFRATIO, src.ParseFloat());

} else if ( token == "decay lf ratio" ) {

efxf(AL_EAXREVERB_DECAY_LFRATIO, src.ParseFloat());

} else if ( token == "reflections" ) {

efxf(AL_EAXREVERB_REFLECTIONS_GAIN, mB_to_gain(src.ParseInt(), REFLECTIONS_GAIN));

} else if ( token == "reflections delay" ) {

efxf(AL_EAXREVERB_REFLECTIONS_DELAY, src.ParseFloat());

} else if ( token == "reflections pan" ) {

efxfv(AL_EAXREVERB_REFLECTIONS_PAN, src.ParseFloat(), src.ParseFloat(), src.ParseFloat());

} else if ( token == "reverb" ) {

efxf(AL_EAXREVERB_LATE_REVERB_GAIN, mB_to_gain(src.ParseInt(), LATE_REVERB_GAIN));

} else if ( token == "reverb delay" ) {

efxf(AL_EAXREVERB_LATE_REVERB_DELAY, src.ParseFloat());

} else if ( token == "reverb pan" ) {

efxfv(AL_EAXREVERB_LATE_REVERB_PAN, src.ParseFloat(), src.ParseFloat(), src.ParseFloat());

} else if ( token == "echo time" ) {

efxf(AL_EAXREVERB_ECHO_TIME, src.ParseFloat());

} else if ( token == "echo depth" ) {

efxf(AL_EAXREVERB_ECHO_DEPTH, src.ParseFloat());

} else if ( token == "modulation time" ) {

efxf(AL_EAXREVERB_MODULATION_TIME, src.ParseFloat());

} else if ( token == "modulation depth" ) {

efxf(AL_EAXREVERB_MODULATION_DEPTH, src.ParseFloat());

} else if ( token == "air absorption hf" ) {

efxf(AL_EAXREVERB_AIR_ABSORPTION_GAINHF, mB_to_gain(src.ParseFloat(), AIR_ABSORPTION_GAINHF));

} else if ( token == "hf reference" ) {

efxf(AL_EAXREVERB_HFREFERENCE, src.ParseFloat());

} else if ( token == "lf reference" ) {

efxf(AL_EAXREVERB_LFREFERENCE, src.ParseFloat());

} else if ( token == "room rolloff factor" ) {

efxf(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR, src.ParseFloat());

} else if ( token == "flags" ) {

src.ReadTokenOnLine( &token );

unsigned int flags = token.GetUnsignedIntValue();

 

efxi(AL_EAXREVERB_DECAY_HFLIMIT, (flags & 0x20) ? AL_TRUE : AL_FALSE);

// the other SCALE flags have no equivalent in efx

} else {

src.ReadTokenOnLine( &token );

src.Error( "idEFXFile::ReadEffect: Invalid parameter in reverb definition" );

}

 

 

 

I hope this would help to write better docs.

 

  • Like 3
Link to comment
Share on other sites

Thanks for the info, stgatilov! This guide might be helpful. Also, I've been watching a few Twitch livestreams by proffessonal audio engineers amd musicans on how to use Delay and Reverb. Since our EFX parameters are similar to Audition's Reverb plugin, it should help me understand which values do what, how they affect each other etc. Then I want to establish a clear workflow, so everyone will know what they're doing.

 

I have already made changes in SVN, so that "reloadSounds" command reloads the EFX file too.
So unless it gets into the "missed the train and has to wait for the next train" category, I hope it would be in 2.06 :D

 

Yes! I almost jumped with joy when I saw that entry resolved in the bug tracker! :D Please, please, please include this in final 2.06 release! You'll save us hours of tedious work, seriously.

Edited by Judith
  • Like 1
Link to comment
Share on other sites

Actually that Effect Extension Guide proved to be very useful. I went through most values in the Appendix on page 120 and further. Despite some differences in names ("room" is basically "gain" and value ranges can be a bit different), everything seems to be correct. Some values, like Reverb density, were probably added in Version 2 or later, so they don't work. Still, even stuff listed in .efx definitions on our Wiki page as "undocumented", like "echo depth" or "echo time" – they actually work. Some of these values just need to be grouped and adjusted together so you can hear the difference.

 

Now I'll need some time to wrap my head around this, and try to decide which of these parameters should be treated as primary and secondary, as it gets complicated pretty quick.

Link to comment
Share on other sites

Kind of just a random passing through. I was searching for stuff on EFX and signed up specifically to make this comment, but as far as I can tell no one has mentioned that there are labelled presets for a couple of different environments here: https://github.com/kcat/openal-soft/blob/master/include/AL/efx-presets.h and it seemed like that could be helpful here

  • Like 3
Link to comment
Share on other sites

Using guide provided by Stgatilov and presets found by Xircspheroth, I made a comparison of values used in Open AL docs and in our documentation. If we take out orange ones, which are incompatible, and blue ones which share the same range, we end up with 6 parameters that need conversion from one range to another. Could have been worse :)

 

obraz.png

  • Like 1
Link to comment
Share on other sites

Using guide provided by Stgatilov and presets found by Xircspheroth, I made a comparison of values used in Open AL docs and in our documentation. If we take out orange ones, which are incompatible, and blue ones which share the same range, we end up with 6 parameters that need conversion from one range to another. Could have been worse :)

These are the parameters which express "gain".

All of them are converted between TDM and OpenAL the same way.

 

In OpenAL, you specify the gain factor F. It means something like "the loudness of this thing is F times greater than the generic loudness of the sound". So, it is just a plain ratio between two volumes, i.e. the sound pressure.

In TDM, you specify things in millibels, which is 1/100 of decibel. Decibel is logarithmic value typical to measure difference in sounds volume.

 

Here is the conversion:

  • each 2000 additional millibels increases gain in 10 times
  • each 200 additional millibels increases gain in pow(10, 1/10) = 1.258... times
  • each 20 additional millibels increases gain in pow(10, 1/100) = 1.0232... times

For example, -2000 millibels converts to 1/10 gain factor, -4000 millibels converts to 1/100 gain factor, and -6000 millibels converts to 1/1000 gain factor.

  • Like 2
Link to comment
Share on other sites

Yeah, I'm a math dummy, I was trying to convert these values as if ranges were linear ;)

 

And I think they changed ranges in white to more sensible scales in later versions. Range from -100 db to 0, +10, or +20 db isn't terribly useful. I mean, on a scale from 0 to -100 db, you'll won't hear much (or anything) beyond -60, -70 db (typically, this is the self-noise floor for microphones). Since we're talking about volume of reflections and reverberation, it's safe to assume you won't hear anything beyond -50 db, because of the foreground sound sources. Besides, values like room, reverb, and reflections (gain) need to be adjusted manually anyway, either to a specific map, or just because TDM sounds seem a bit louder than in other games.

 

Also TDM default EFX settings are not exactly "neutral". I'd say it's something close to a "medium dead room", so you have to take that into account as well.

 

I'm not sayin these presets are useless. But, I'm trying to create something more like "EFX for dummies" guide, not "here, use these presets". Maybe like a question system, e.g.: 1) how big is your room? Use X for small rooms, Y for medium rooms, and Z for large rooms, etc. So people can take these values and understand (roughly) what they do, and they won't have problems with changing them later.

  • Like 1
Link to comment
Share on other sites

Kind of just a random passing through. I was searching for stuff on EFX and signed up specifically to make this comment, but as far as I can tell no one has mentioned that there are labelled presets for a couple of different environments here: https://github.com/kcat/openal-soft/blob/master/include/AL/efx-presets.h and it seemed like that could be helpful here

Welcome to the forums :-)

  • Like 1
Link to comment
Share on other sites

I'm not sayin these presets are useless. But, I'm trying to create something more like "EFX for dummies" guide, not "here, use these presets". Maybe like a question system, e.g.: 1) how big is your room? Use X for small rooms, Y for medium rooms, and Z for large rooms, etc. So people can take these values and understand (roughly) what they do, and they won't have problems with changing them later.

 

On second thought, maybe it will be better to do both. First, let's have enough generic presets for people who just want to put these in a map and be done.

Link to comment
Share on other sites

Somebody ought to edit the EFX wiki page to add the info a mapper needs, especially if anything changes with what we have now, and be sure to put a link on the Location Settings wiki page.

What do you see when you turn out the light? I can't tell you but I know that it's mine.

Link to comment
Share on other sites

I don't have Wiki credentials, but maybe we should wait until we have the 2.06 ready, or at least stuff like no_efx spawnarg support in current beta. I also wanted to make some more user friendly explanations for the values, and a small tutorial for creating a reverb definition from scratch, if anyone feels like it.

  • Like 1
Link to comment
Share on other sites

  • 4 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share


  • Recent Status Updates

    • Nort

      I did it! I finally did it! After 48 hours of frustration and confusion, I managed to finally sort out how to attach equipment to NPC:s properly, and write down coherent instructions on how to do it, both in my manual, and in this forum.
      I can finally rest. I can finally eat breakfast.
      · 0 replies
    • Nort

      Spent most of the day learning and writing about AI navigation. It's stuff I already know, but the magic about writing something down as clearly formulated as possible, is that you then see things that much more clearly. You also find what's unclear to you, and then you figure out exactly how things work. I was hoping to get through it all within just a day, but it looks like this will take tomorrow as well, at this rate. There's also plenty of other nonsense I have to get through as well. Everything's a chore.
      · 0 replies
    • Nort

      I want to be a fish, but I'm not a fish. My mom wants to be a fish too, and so she's killing herself eating plankton and sh***ng blood, and tells me to stop nagging her about taking her medication. I spent several hours today, just lying in bed, having anxiety over just existing, and not being a fish. You fish, you don't know how lucky you are. You can eat all the plankton you want. I tried eating plankton again yesterday, and I just got sick. I hate being a shark.
      · 0 replies
    • Nort

      I just gave myself vertigo. A pleasant kind of vertigo, like the world has been lifted off my shoulders. I'll explain:
      Yesterday I saw to my dismay, that I had made my entire map two - two - units too short on every level - that every set01 piece was sticking 2 units into the ceiling. That's basically 402 brushes that needs to be realigned (minus the ground floor brushes).
      I knew enough about selections to do all of that in a very tense five minutes, and it compiled without leaks. (Thank you so much, Dark Radiant devs, for making an editor with such care for precision that you can align hundreds of brushes perfectly at once (which is not something I can say for Valve's Hammer editor, which has some serious issues on that front, which actually made me just quit it in disgust).) However, the result is that the entire level has now been stretched a barely noticable 2 units, and it will take some getting used to psychologically.
      · 0 replies
    • Nort

      My workflow is basically running from a chain of disasters, eventually trying to seek shelter in former disasters. It's not ideal - it's just my life.
      When I abandoned my first map, it was out of a typical mental breakdown, and so I returned to find a skybox void where the kitchen door should have been (due to a misplaced visportal) and two overlapping brushes Z-fighting on the kitchen floor.
      I've now cleaned up the last bit of mess, by cleanly separating every floor into its own layer. Now I can finally work on each floor in peace.
      ...not that I really needed to. Once you get skilled enough, the orthographic messes, well, I'll let this video speak for itself:
       
      · 1 reply
×
×
  • Create New...