Skip to content

Commit c110698

Browse files
authored
Merge pull request #2444 from capdevon/capdevon-new-audio-filters
New audio filters: HighPassFilter and BandPassFilter
2 parents c14e3e2 + cb7ad5a commit c110698

File tree

5 files changed

+359
-28
lines changed

5 files changed

+359
-28
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright (c) 2009-2025 jMonkeyEngine
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are
7+
* met:
8+
*
9+
* * Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* * Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
package com.jme3.audio;
33+
34+
import com.jme3.export.InputCapsule;
35+
import com.jme3.export.JmeExporter;
36+
import com.jme3.export.JmeImporter;
37+
import com.jme3.export.OutputCapsule;
38+
import com.jme3.util.NativeObject;
39+
40+
import java.io.IOException;
41+
42+
/**
43+
* Represents an OpenAL EFX Band-Pass Filter.
44+
*/
45+
public class BandPassFilter extends Filter {
46+
47+
// Default values based on OpenAL EFX specification defaults
48+
protected float volume = 1.0f;
49+
protected float highFreqVolume = 1.0f;
50+
protected float lowFreqVolume = 1.0f;
51+
52+
/**
53+
* Constructs a band-pass filter with default settings.
54+
* Required for jME deserialization
55+
*/
56+
public BandPassFilter() {}
57+
58+
protected BandPassFilter(int id) {
59+
super(id);
60+
}
61+
62+
public BandPassFilter(float volume, float highFreqVolume, float lowFreqVolume) {
63+
super();
64+
setVolume(volume);
65+
setHighFreqVolume(highFreqVolume);
66+
setLowFreqVolume(lowFreqVolume);
67+
}
68+
69+
public float getVolume() {
70+
return volume;
71+
}
72+
73+
/**
74+
* Sets the overall gain of the Band-Pass filter.
75+
*
76+
* @param volume The gain value (0.0 to 1.0).
77+
*/
78+
public void setVolume(float volume) {
79+
if (volume < 0 || volume > 1)
80+
throw new IllegalArgumentException("Volume must be between 0 and 1");
81+
82+
this.volume = volume;
83+
this.updateNeeded = true;
84+
}
85+
86+
public float getHighFreqVolume() {
87+
return highFreqVolume;
88+
}
89+
90+
/**
91+
* Sets the gain at high frequencies for the Band-Pass filter.
92+
*
93+
* @param highFreqVolume The high-frequency gain value (0.0 to 1.0).
94+
*/
95+
public void setHighFreqVolume(float highFreqVolume) {
96+
if (highFreqVolume < 0 || highFreqVolume > 1)
97+
throw new IllegalArgumentException("High freq volume must be between 0 and 1");
98+
99+
this.highFreqVolume = highFreqVolume;
100+
this.updateNeeded = true;
101+
}
102+
103+
public float getLowFreqVolume() {
104+
return lowFreqVolume;
105+
}
106+
107+
/**
108+
* Sets the gain at low frequencies for the Band-Pass filter.
109+
*
110+
* @param lowFreqVolume The low-frequency gain value (0.0 to 1.0).
111+
*/
112+
public void setLowFreqVolume(float lowFreqVolume) {
113+
if (lowFreqVolume < 0 || lowFreqVolume > 1)
114+
throw new IllegalArgumentException("Low freq volume must be between 0 and 1");
115+
116+
this.lowFreqVolume = lowFreqVolume;
117+
this.updateNeeded = true;
118+
}
119+
120+
@Override
121+
public NativeObject createDestructableClone() {
122+
return new BandPassFilter(this.id);
123+
}
124+
125+
/**
126+
* Retrieves a unique identifier for this filter. Used internally for native object management.
127+
*
128+
* @return a unique long identifier.
129+
*/
130+
@Override
131+
public long getUniqueId() {
132+
return ((long) OBJTYPE_FILTER << 32) | (0xffffffffL & (long) id);
133+
}
134+
135+
@Override
136+
public void write(JmeExporter ex) throws IOException {
137+
super.write(ex);
138+
OutputCapsule oc = ex.getCapsule(this);
139+
oc.write(this.volume, "volume", 1f);
140+
oc.write(this.lowFreqVolume, "lf_volume", 1f);
141+
oc.write(this.highFreqVolume, "hf_volume", 1f);
142+
}
143+
144+
@Override
145+
public void read(JmeImporter im) throws IOException {
146+
super.read(im);
147+
InputCapsule ic = im.getCapsule(this);
148+
this.volume = ic.readFloat("volume", 1f);
149+
this.lowFreqVolume = ic.readFloat("lf_volume", 1f);
150+
this.highFreqVolume = ic.readFloat("hf_volume", 1f);
151+
}
152+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* Copyright (c) 2009-2025 jMonkeyEngine
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are
7+
* met:
8+
*
9+
* * Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* * Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
package com.jme3.audio;
33+
34+
import com.jme3.export.InputCapsule;
35+
import com.jme3.export.JmeExporter;
36+
import com.jme3.export.JmeImporter;
37+
import com.jme3.export.OutputCapsule;
38+
import com.jme3.util.NativeObject;
39+
40+
import java.io.IOException;
41+
42+
/**
43+
* Represents an OpenAL EFX High-Pass Filter.
44+
*/
45+
public class HighPassFilter extends Filter {
46+
47+
// Default values based on OpenAL EFX specification defaults
48+
protected float volume = 1.0f;
49+
protected float lowFreqVolume = 1.0f;
50+
51+
/**
52+
* Constructs a high-pass filter with default settings.
53+
* Required for jME deserialization
54+
*/
55+
public HighPassFilter(){}
56+
57+
protected HighPassFilter(int id) {
58+
super(id);
59+
}
60+
61+
public HighPassFilter(float volume, float lowFreqVolume) {
62+
super();
63+
setVolume(volume);
64+
setLowFreqVolume(lowFreqVolume);
65+
}
66+
67+
public float getVolume() {
68+
return volume;
69+
}
70+
71+
/**
72+
* Sets the gain of the High-Pass filter.
73+
*
74+
* @param volume The gain value (0.0 to 1.0).
75+
*/
76+
public void setVolume(float volume) {
77+
if (volume < 0 || volume > 1)
78+
throw new IllegalArgumentException("Volume must be between 0 and 1");
79+
80+
this.volume = volume;
81+
this.updateNeeded = true;
82+
}
83+
84+
public float getLowFreqVolume() {
85+
return lowFreqVolume;
86+
}
87+
88+
/**
89+
* Sets the gain at low frequencies for the High-Pass filter.
90+
*
91+
* @param lowFreqVolume The low-frequency gain value (0.0 to 1.0).
92+
*/
93+
public void setLowFreqVolume(float lowFreqVolume) {
94+
if (lowFreqVolume < 0 || lowFreqVolume > 1)
95+
throw new IllegalArgumentException("Low freq volume must be between 0 and 1");
96+
97+
this.lowFreqVolume = lowFreqVolume;
98+
this.updateNeeded = true;
99+
}
100+
101+
@Override
102+
public NativeObject createDestructableClone() {
103+
return new HighPassFilter(this.id);
104+
}
105+
106+
/**
107+
* Retrieves a unique identifier for this filter. Used internally for native object management.
108+
*
109+
* @return a unique long identifier.
110+
*/
111+
@Override
112+
public long getUniqueId() {
113+
return ((long) OBJTYPE_FILTER << 32) | (0xffffffffL & (long) id);
114+
}
115+
116+
@Override
117+
public void write(JmeExporter ex) throws IOException {
118+
super.write(ex);
119+
OutputCapsule oc = ex.getCapsule(this);
120+
oc.write(this.volume, "volume", 1f);
121+
oc.write(this.lowFreqVolume, "lf_volume", 1f);
122+
}
123+
124+
@Override
125+
public void read(JmeImporter im) throws IOException {
126+
super.read(im);
127+
InputCapsule ic = im.getCapsule(this);
128+
this.volume = ic.readFloat("volume", 1f);
129+
this.lowFreqVolume = ic.readFloat("lf_volume", 1f);
130+
}
131+
}

jme3-core/src/main/java/com/jme3/audio/openal/ALAudioRenderer.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@
4040
import static com.jme3.audio.openal.AL.*;
4141

4242
import com.jme3.audio.AudioStream;
43+
import com.jme3.audio.BandPassFilter;
4344
import com.jme3.audio.Environment;
4445
import com.jme3.audio.Filter;
46+
import com.jme3.audio.HighPassFilter;
4547
import com.jme3.audio.Listener;
4648
import com.jme3.audio.ListenerParam;
4749
import com.jme3.audio.LowPassFilter;
@@ -403,10 +405,25 @@ private void updateFilter(Filter f) {
403405
efx.alFilteri(id, EFX.AL_FILTER_TYPE, EFX.AL_FILTER_LOWPASS);
404406
efx.alFilterf(id, EFX.AL_LOWPASS_GAIN, lowPass.getVolume());
405407
efx.alFilterf(id, EFX.AL_LOWPASS_GAINHF, lowPass.getHighFreqVolume());
406-
f.clearUpdateNeeded();
408+
409+
} else if (f instanceof HighPassFilter) {
410+
HighPassFilter highPass = (HighPassFilter) f;
411+
efx.alFilteri(id, EFX.AL_FILTER_TYPE, EFX.AL_FILTER_HIGHPASS);
412+
efx.alFilterf(id, EFX.AL_HIGHPASS_GAIN, highPass.getVolume());
413+
efx.alFilterf(id, EFX.AL_HIGHPASS_GAINLF, highPass.getLowFreqVolume());
414+
415+
} else if (f instanceof BandPassFilter) {
416+
BandPassFilter bandPass = (BandPassFilter) f;
417+
efx.alFilteri(id, EFX.AL_FILTER_TYPE, EFX.AL_FILTER_BANDPASS);
418+
efx.alFilterf(id, EFX.AL_BANDPASS_GAIN, bandPass.getVolume());
419+
efx.alFilterf(id, EFX.AL_BANDPASS_GAINHF, bandPass.getHighFreqVolume());
420+
efx.alFilterf(id, EFX.AL_BANDPASS_GAINLF, bandPass.getLowFreqVolume());
421+
407422
} else {
408423
throw new UnsupportedOperationException("Unsupported filter type: " + f.getClass().getName());
409424
}
425+
426+
f.clearUpdateNeeded();
410427
}
411428

412429
/**

jme3-core/src/main/java/com/jme3/audio/openal/EFX.java

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@ public interface EFX {
2727
/* Effect properties. */
2828

2929
/* Reverb effect parameters */
30-
public static final int AL_REVERB_DENSITY = 0x0001;
31-
public static final int AL_REVERB_DIFFUSION = 0x0002;
32-
public static final int AL_REVERB_GAIN = 0x0003;
33-
public static final int AL_REVERB_GAINHF = 0x0004;
34-
public static final int AL_REVERB_DECAY_TIME = 0x0005;
35-
public static final int AL_REVERB_DECAY_HFRATIO = 0x0006;
36-
public static final int AL_REVERB_REFLECTIONS_GAIN = 0x0007;
37-
public static final int AL_REVERB_REFLECTIONS_DELAY = 0x0008;
38-
public static final int AL_REVERB_LATE_REVERB_GAIN = 0x0009;
39-
public static final int AL_REVERB_LATE_REVERB_DELAY = 0x000A;
30+
public static final int AL_REVERB_DENSITY = 0x0001;
31+
public static final int AL_REVERB_DIFFUSION = 0x0002;
32+
public static final int AL_REVERB_GAIN = 0x0003;
33+
public static final int AL_REVERB_GAINHF = 0x0004;
34+
public static final int AL_REVERB_DECAY_TIME = 0x0005;
35+
public static final int AL_REVERB_DECAY_HFRATIO = 0x0006;
36+
public static final int AL_REVERB_REFLECTIONS_GAIN = 0x0007;
37+
public static final int AL_REVERB_REFLECTIONS_DELAY = 0x0008;
38+
public static final int AL_REVERB_LATE_REVERB_GAIN = 0x0009;
39+
public static final int AL_REVERB_LATE_REVERB_DELAY = 0x000A;
4040
public static final int AL_REVERB_AIR_ABSORPTION_GAINHF = 0x000B;
41-
public static final int AL_REVERB_ROOM_ROLLOFF_FACTOR = 0x000C;
42-
public static final int AL_REVERB_DECAY_HFLIMIT = 0x000D;
41+
public static final int AL_REVERB_ROOM_ROLLOFF_FACTOR = 0x000C;
42+
public static final int AL_REVERB_DECAY_HFLIMIT = 0x000D;
4343

4444
/* EAX Reverb effect parameters */
4545
//#define AL_EAXREVERB_DENSITY 0x0001
@@ -171,28 +171,28 @@ public interface EFX {
171171
///* Filter properties. */
172172

173173
/* Lowpass filter parameters */
174-
public static final int AL_LOWPASS_GAIN = 0x0001;
175-
public static final int AL_LOWPASS_GAINHF = 0x0002;
174+
public static final int AL_LOWPASS_GAIN = 0x0001;
175+
public static final int AL_LOWPASS_GAINHF = 0x0002;
176176

177-
///* Highpass filter parameters */
178-
//#define AL_HIGHPASS_GAIN 0x0001
179-
//#define AL_HIGHPASS_GAINLF 0x0002
177+
// * Highpass filter parameters */
178+
public static final int AL_HIGHPASS_GAIN = 0x0001;
179+
public static final int AL_HIGHPASS_GAINLF = 0x0002;
180180

181-
///* Bandpass filter parameters */
182-
//#define AL_BANDPASS_GAIN 0x0001
183-
//#define AL_BANDPASS_GAINLF 0x0002
184-
//#define AL_BANDPASS_GAINHF 0x0003
181+
// * Bandpass filter parameters */
182+
public static final int AL_BANDPASS_GAIN = 0x0001;
183+
public static final int AL_BANDPASS_GAINLF = 0x0002;
184+
public static final int AL_BANDPASS_GAINHF = 0x0003;
185185

186186
/* Filter type */
187187
//#define AL_FILTER_FIRST_PARAMETER 0x0000
188188
//#define AL_FILTER_LAST_PARAMETER 0x8000
189-
public static final int AL_FILTER_TYPE = 0x8001;
189+
public static final int AL_FILTER_TYPE = 0x8001;
190190

191191
/* Filter types, used with the AL_FILTER_TYPE property */
192-
public static final int AL_FILTER_NULL = 0x0000;
193-
public static final int AL_FILTER_LOWPASS = 0x0001;
194-
public static final int AL_FILTER_HIGHPASS = 0x0002;
195-
//#define AL_FILTER_BANDPASS 0x0003
192+
public static final int AL_FILTER_NULL = 0x0000;
193+
public static final int AL_FILTER_LOWPASS = 0x0001;
194+
public static final int AL_FILTER_HIGHPASS = 0x0002;
195+
public static final int AL_FILTER_BANDPASS = 0x0003;
196196

197197
///* Filter ranges and defaults. */
198198
//

0 commit comments

Comments
 (0)