Question about com.jme3.audio.LowPassFilter

Hello everybody,
running the TestPostWater test class I noticed that there is no change in the sound when the audio filter is applied underwater. Is there something I’m missing or is it possible that something is wrong?

Regards

1 Like

Interesting. Since I usually work with audio disabled, I never noticed that TestPostWater included sound!

The low-pass filter in TestOgg seems to works fine, so I suggest comparing the 2 test apps to figure out what’s different. Please open a new issue at GitHub so this bug doesn’t get forgotten.

1 Like
1 Like

That is because they have Reverb on.

It doesn’t affect the Reverb part of the sound. Turn reverb off and then you can hear the difference once under water.

If you want the reverb ‘on’ which sounds great above the water. I would change the simpleupdate to something like this.

    @Override
    public void simpleUpdate(float tpf) {
        .....
        if (water.isUnderWater() && !uw) {

            waves.setDryFilter(new LowPassFilter(0.5f, 0.1f));
            waves.setVolume(2.5f);    // turning off reverb will lower the sound, atleast on my computer couldn't hear it anymore.
            waves.setReverbEnabled(false);
            uw = true;
        }
        if (!water.isUnderWater() && uw) {
            uw = false;
            waves.setDryFilter(new LowPassFilter(1, 1f));
            waves.setVolume(1f);       //  don't forget to set it back to what it was.
            waves.setReverbEnabled(true);
        }

2 Likes

Thanks for investigating. I invite you to submit a pull request for this change.

I would highly recommend not creating a new lowpass filter every frame though. It would be best to create those in advance and just swap between them.

The code posted so far is not creating one every frame.

1 Like

It shows a new low pass filter being set to the dry filter inside simple update.
Edit: i missed the flag being used to oneshot it. My bad.

Me too, not every frame but every time it changes it does a NEW. Many of the JME examples having things like this and for new beginners that doesn’t know better. It is not a good example of how to do something. I understand it is a quick example of what could be done, but there are tons of NEWS in updates in many of the examples and that is a serious NO NO for me. Limit garbage collection, if the foremost thought.

In the beginning of my own Engine when I did a check, I saw so many NEW and garbage collection that was occuring. I had to go back and change all those calls and that caused a huge speed increase. I never wrote a game or graphics before. 30+ year of business applications history and no game history for me.

So speed was never an issue.

1 Like

In modern Java, short-lived objects are essentially like stack allocated objects in a native language. They do not incur significant GC overhead. So if they are light weight to create and you know they won’t be around long then don’t worry too much about it.

Ironically, holding onto objects for a long time can cause additional problems to be concerned about depending on what they are doing. So it’s not so cut and dry.

In this case, sure, create them in advance and hold them in a field… but it will basically make no difference.

Yes it would, because it would be only 2 objects for the entire game because they do not change, they just get swapped out.

In this example, the only time it changes is when you go under water or above water. So in a game, you probably are not doing that every couple of seconds, so they are hanging around for minutes or even longer. Since in this example the class is static (in a sense).

What issue comes up from long term variable holding in java. I"ve not heard of any issues and did a quick search and I couldn’t locate anyone talking about this.

Objects that hold resources can hit unwary users in subtle ways… to include inducing memory leaks where the “simpler” code might not have. Even worse is how Java non-static inner classes quietly hold a reference to the parent class’s instance. So handing these sorts of objects off to something else keeps a reference around to that parent, etc… (hugely common mistake in Swing applications ‘back in the day’)

It doesn’t matter in this case but an arbitrary “never/rarely allocate stuff” rule cuts both ways. It leads to other kinds of bad habits.

Yes, but they are super tiny objects and just hold two fields. They are just marking objects to tell the audio layer what to do. They don’t actually do anything or hold any native parts or anything.

No reason to be paranoid about creating a new one every now and then.

I find coding style to use inner classes so wrong. It just seems to me “LAZY” (my thoughts) in creating a new file for that class. I don’t code with inner classes.

Inner classes are bad for other reasons.

In this example they are simple classes, but the example is suppose to be about helping “NEW” people learn things about JME and showing things like this is the wrong path for coding styles. (My thoughts)

And are the only good answer in some cases. They are not lazy. They are a good tool like anything else. Sublime when used properly.

Be careful not to let dogma ruin your designs. I’ve been victim of that many times in a 30 year career and it’s always regrettable.

1 Like