Skip to content
152 changes: 152 additions & 0 deletions jme3-core/src/main/java/com/jme3/audio/BandPassFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
* Copyright (c) 2009-2025 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.audio;

import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.util.NativeObject;

import java.io.IOException;

/**
* Represents an OpenAL EFX Band-Pass Filter.
*/
public class BandPassFilter extends Filter {

// Default values based on OpenAL EFX specification defaults
protected float volume = 1.0f;
protected float highFreqVolume = 1.0f;
protected float lowFreqVolume = 1.0f;

/**
* Constructs a band-pass filter with default settings.
* Required for jME deserialization
*/
public BandPassFilter() {}

protected BandPassFilter(int id) {
super(id);
}

public BandPassFilter(float volume, float highFreqVolume, float lowFreqVolume) {
super();
setVolume(volume);
setHighFreqVolume(highFreqVolume);
setLowFreqVolume(lowFreqVolume);
}

public float getVolume() {
return volume;
}

/**
* Sets the overall gain of the Band-Pass filter.
*
* @param volume The gain value (0.0 to 1.0).
*/
public void setVolume(float volume) {
if (volume < 0 || volume > 1)
throw new IllegalArgumentException("Volume must be between 0 and 1");

this.volume = volume;
this.updateNeeded = true;
}

public float getHighFreqVolume() {
return highFreqVolume;
}

/**
* Sets the gain at high frequencies for the Band-Pass filter.
*
* @param highFreqVolume The high-frequency gain value (0.0 to 1.0).
*/
public void setHighFreqVolume(float highFreqVolume) {
if (highFreqVolume < 0 || highFreqVolume > 1)
throw new IllegalArgumentException("High freq volume must be between 0 and 1");

this.highFreqVolume = highFreqVolume;
this.updateNeeded = true;
}

public float getLowFreqVolume() {
return lowFreqVolume;
}

/**
* Sets the gain at low frequencies for the Band-Pass filter.
*
* @param lowFreqVolume The low-frequency gain value (0.0 to 1.0).
*/
public void setLowFreqVolume(float lowFreqVolume) {
if (lowFreqVolume < 0 || lowFreqVolume > 1)
throw new IllegalArgumentException("Low freq volume must be between 0 and 1");

this.lowFreqVolume = lowFreqVolume;
this.updateNeeded = true;
}

@Override
public NativeObject createDestructableClone() {
return new BandPassFilter(this.id);
}

/**
* Retrieves a unique identifier for this filter. Used internally for native object management.
*
* @return a unique long identifier.
*/
@Override
public long getUniqueId() {
return ((long) OBJTYPE_FILTER << 32) | (0xffffffffL & (long) id);
}

@Override
public void write(JmeExporter ex) throws IOException {
super.write(ex);
OutputCapsule oc = ex.getCapsule(this);
oc.write(this.volume, "volume", 1f);
oc.write(this.lowFreqVolume, "lf_volume", 1f);
oc.write(this.highFreqVolume, "hf_volume", 1f);
}

@Override
public void read(JmeImporter im) throws IOException {
super.read(im);
InputCapsule ic = im.getCapsule(this);
this.volume = ic.readFloat("volume", 1f);
this.lowFreqVolume = ic.readFloat("lf_volume", 1f);
this.highFreqVolume = ic.readFloat("hf_volume", 1f);
}
}
131 changes: 131 additions & 0 deletions jme3-core/src/main/java/com/jme3/audio/HighPassFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
* Copyright (c) 2009-2025 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.audio;

import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.util.NativeObject;

import java.io.IOException;

/**
* Represents an OpenAL EFX High-Pass Filter.
*/
public class HighPassFilter extends Filter {

// Default values based on OpenAL EFX specification defaults
protected float volume = 1.0f;
protected float lowFreqVolume = 1.0f;

/**
* Constructs a high-pass filter with default settings.
* Required for jME deserialization
*/
public HighPassFilter(){}

protected HighPassFilter(int id) {
super(id);
}

public HighPassFilter(float volume, float lowFreqVolume) {
super();
setVolume(volume);
setLowFreqVolume(lowFreqVolume);
}

public float getVolume() {
return volume;
}

/**
* Sets the gain of the High-Pass filter.
*
* @param volume The gain value (0.0 to 1.0).
*/
public void setVolume(float volume) {
if (volume < 0 || volume > 1)
throw new IllegalArgumentException("Volume must be between 0 and 1");

this.volume = volume;
this.updateNeeded = true;
}

public float getLowFreqVolume() {
return lowFreqVolume;
}

/**
* Sets the gain at low frequencies for the High-Pass filter.
*
* @param lowFreqVolume The low-frequency gain value (0.0 to 1.0).
*/
public void setLowFreqVolume(float lowFreqVolume) {
if (lowFreqVolume < 0 || lowFreqVolume > 1)
throw new IllegalArgumentException("Low freq volume must be between 0 and 1");

this.lowFreqVolume = lowFreqVolume;
this.updateNeeded = true;
}

@Override
public NativeObject createDestructableClone() {
return new HighPassFilter(this.id);
}

/**
* Retrieves a unique identifier for this filter. Used internally for native object management.
*
* @return a unique long identifier.
*/
@Override
public long getUniqueId() {
return ((long) OBJTYPE_FILTER << 32) | (0xffffffffL & (long) id);
}

@Override
public void write(JmeExporter ex) throws IOException {
super.write(ex);
OutputCapsule oc = ex.getCapsule(this);
oc.write(this.volume, "volume", 1f);
oc.write(this.lowFreqVolume, "lf_volume", 1f);
}

@Override
public void read(JmeImporter im) throws IOException {
super.read(im);
InputCapsule ic = im.getCapsule(this);
this.volume = ic.readFloat("volume", 1f);
this.lowFreqVolume = ic.readFloat("lf_volume", 1f);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@
import static com.jme3.audio.openal.AL.*;

import com.jme3.audio.AudioStream;
import com.jme3.audio.BandPassFilter;
import com.jme3.audio.Environment;
import com.jme3.audio.Filter;
import com.jme3.audio.HighPassFilter;
import com.jme3.audio.Listener;
import com.jme3.audio.ListenerParam;
import com.jme3.audio.LowPassFilter;
Expand Down Expand Up @@ -403,10 +405,25 @@ private void updateFilter(Filter f) {
efx.alFilteri(id, EFX.AL_FILTER_TYPE, EFX.AL_FILTER_LOWPASS);
efx.alFilterf(id, EFX.AL_LOWPASS_GAIN, lowPass.getVolume());
efx.alFilterf(id, EFX.AL_LOWPASS_GAINHF, lowPass.getHighFreqVolume());
f.clearUpdateNeeded();

} else if (f instanceof HighPassFilter) {
HighPassFilter highPass = (HighPassFilter) f;
efx.alFilteri(id, EFX.AL_FILTER_TYPE, EFX.AL_FILTER_HIGHPASS);
efx.alFilterf(id, EFX.AL_HIGHPASS_GAIN, highPass.getVolume());
efx.alFilterf(id, EFX.AL_HIGHPASS_GAINLF, highPass.getLowFreqVolume());

} else if (f instanceof BandPassFilter) {
BandPassFilter bandPass = (BandPassFilter) f;
efx.alFilteri(id, EFX.AL_FILTER_TYPE, EFX.AL_FILTER_BANDPASS);
efx.alFilterf(id, EFX.AL_BANDPASS_GAIN, bandPass.getVolume());
efx.alFilterf(id, EFX.AL_BANDPASS_GAINHF, bandPass.getHighFreqVolume());
efx.alFilterf(id, EFX.AL_BANDPASS_GAINLF, bandPass.getLowFreqVolume());

} else {
throw new UnsupportedOperationException("Unsupported filter type: " + f.getClass().getName());
}

f.clearUpdateNeeded();
}

/**
Expand Down
52 changes: 26 additions & 26 deletions jme3-core/src/main/java/com/jme3/audio/openal/EFX.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ public interface EFX {
/* Effect properties. */

/* Reverb effect parameters */
public static final int AL_REVERB_DENSITY = 0x0001;
public static final int AL_REVERB_DIFFUSION = 0x0002;
public static final int AL_REVERB_GAIN = 0x0003;
public static final int AL_REVERB_GAINHF = 0x0004;
public static final int AL_REVERB_DECAY_TIME = 0x0005;
public static final int AL_REVERB_DECAY_HFRATIO = 0x0006;
public static final int AL_REVERB_REFLECTIONS_GAIN = 0x0007;
public static final int AL_REVERB_REFLECTIONS_DELAY = 0x0008;
public static final int AL_REVERB_LATE_REVERB_GAIN = 0x0009;
public static final int AL_REVERB_LATE_REVERB_DELAY = 0x000A;
public static final int AL_REVERB_DENSITY = 0x0001;
public static final int AL_REVERB_DIFFUSION = 0x0002;
public static final int AL_REVERB_GAIN = 0x0003;
public static final int AL_REVERB_GAINHF = 0x0004;
public static final int AL_REVERB_DECAY_TIME = 0x0005;
public static final int AL_REVERB_DECAY_HFRATIO = 0x0006;
public static final int AL_REVERB_REFLECTIONS_GAIN = 0x0007;
public static final int AL_REVERB_REFLECTIONS_DELAY = 0x0008;
public static final int AL_REVERB_LATE_REVERB_GAIN = 0x0009;
public static final int AL_REVERB_LATE_REVERB_DELAY = 0x000A;
public static final int AL_REVERB_AIR_ABSORPTION_GAINHF = 0x000B;
public static final int AL_REVERB_ROOM_ROLLOFF_FACTOR = 0x000C;
public static final int AL_REVERB_DECAY_HFLIMIT = 0x000D;
public static final int AL_REVERB_ROOM_ROLLOFF_FACTOR = 0x000C;
public static final int AL_REVERB_DECAY_HFLIMIT = 0x000D;

/* EAX Reverb effect parameters */
//#define AL_EAXREVERB_DENSITY 0x0001
Expand Down Expand Up @@ -171,28 +171,28 @@ public interface EFX {
///* Filter properties. */

/* Lowpass filter parameters */
public static final int AL_LOWPASS_GAIN = 0x0001;
public static final int AL_LOWPASS_GAINHF = 0x0002;
public static final int AL_LOWPASS_GAIN = 0x0001;
public static final int AL_LOWPASS_GAINHF = 0x0002;

///* Highpass filter parameters */
//#define AL_HIGHPASS_GAIN 0x0001
//#define AL_HIGHPASS_GAINLF 0x0002
// * Highpass filter parameters */
public static final int AL_HIGHPASS_GAIN = 0x0001;
public static final int AL_HIGHPASS_GAINLF = 0x0002;

///* Bandpass filter parameters */
//#define AL_BANDPASS_GAIN 0x0001
//#define AL_BANDPASS_GAINLF 0x0002
//#define AL_BANDPASS_GAINHF 0x0003
// * Bandpass filter parameters */
public static final int AL_BANDPASS_GAIN = 0x0001;
public static final int AL_BANDPASS_GAINLF = 0x0002;
public static final int AL_BANDPASS_GAINHF = 0x0003;

/* Filter type */
//#define AL_FILTER_FIRST_PARAMETER 0x0000
//#define AL_FILTER_LAST_PARAMETER 0x8000
public static final int AL_FILTER_TYPE = 0x8001;
public static final int AL_FILTER_TYPE = 0x8001;

/* Filter types, used with the AL_FILTER_TYPE property */
public static final int AL_FILTER_NULL = 0x0000;
public static final int AL_FILTER_LOWPASS = 0x0001;
public static final int AL_FILTER_HIGHPASS = 0x0002;
//#define AL_FILTER_BANDPASS 0x0003
public static final int AL_FILTER_NULL = 0x0000;
public static final int AL_FILTER_LOWPASS = 0x0001;
public static final int AL_FILTER_HIGHPASS = 0x0002;
public static final int AL_FILTER_BANDPASS = 0x0003;

///* Filter ranges and defaults. */
//
Expand Down
Loading