Skip to content

Commit 62e62aa

Browse files
authored
Merge pull request #2428 from capdevon/capdevon-Environment
com.jme3.audio.Environment: javadoc
2 parents 9e2a2ef + 27788bf commit 62e62aa

File tree

1 file changed

+153
-53
lines changed

1 file changed

+153
-53
lines changed

jme3-core/src/main/java/com/jme3/audio/Environment.java

Lines changed: 153 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2012 jMonkeyEngine
2+
* Copyright (c) 2009-2025 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -34,49 +34,80 @@
3434
import com.jme3.math.FastMath;
3535

3636
/**
37-
* Audio environment, for reverb effects.
37+
* Represents an audio environment, primarily used to define reverb effects.
38+
* This class provides parameters that correspond to the properties controllable
39+
* through the OpenAL EFX (Environmental Effects Extension) library.
40+
* By adjusting these parameters, developers can simulate various acoustic spaces
41+
* like rooms, caves, and concert halls, adding depth and realism to the audio experience.
42+
*
3843
* @author Kirill
3944
*/
4045
public class Environment {
4146

42-
private float airAbsorbGainHf = 0.99426f;
47+
/** High-frequency air absorption gain (0.0f to 1.0f). */
48+
private float airAbsorbGainHf = 0.99426f;
49+
/** Factor controlling room effect rolloff with distance. */
4350
private float roomRolloffFactor = 0;
44-
45-
private float decayTime = 1.49f;
46-
private float decayHFRatio = 0.54f;
47-
48-
private float density = 1.0f;
49-
private float diffusion = 0.3f;
50-
51-
private float gain = 0.316f;
52-
private float gainHf = 0.022f;
53-
54-
private float lateReverbDelay = 0.088f;
55-
private float lateReverbGain = 0.768f;
56-
57-
private float reflectDelay = 0.162f;
58-
private float reflectGain = 0.052f;
59-
60-
private boolean decayHfLimit = true;
61-
62-
public static final Environment Garage, Dungeon, Cavern, AcousticLab, Closet;
63-
64-
static {
65-
Garage = new Environment(1, 1, 1, 1, .9f, .5f, .751f, .0039f, .661f, .0137f);
66-
Dungeon = new Environment(.75f, 1, 1, .75f, 1.6f, 1, 0.95f, 0.0026f, 0.93f, 0.0103f);
67-
Cavern = new Environment(.5f, 1, 1, .5f, 2.25f, 1, .908f, .0103f, .93f, .041f);
68-
AcousticLab = new Environment(.5f, 1, 1, 1, .28f, 1, .87f, .002f, .81f, .008f);
69-
Closet = new Environment(1, 1, 1, 1, .15f, 1, .6f, .0025f, .5f, .0006f);
70-
}
71-
51+
/** Overall decay time of the reverberation (in seconds). */
52+
private float decayTime = 1.49f;
53+
/** Ratio of high-frequency decay time to overall decay time (0.0f to 1.0f). */
54+
private float decayHFRatio = 0.54f;
55+
/** Density of the medium affecting reverb smoothness (0.0f to 1.0f). */
56+
private float density = 1.0f;
57+
/** Diffusion of reflections affecting echo distinctness (0.0f to 1.0f). */
58+
private float diffusion = 0.3f;
59+
/** Overall gain of the environment effect (linear scale). */
60+
private float gain = 0.316f;
61+
/** High-frequency gain of the environment effect (linear scale). */
62+
private float gainHf = 0.022f;
63+
/** Delay time for late reverberation relative to early reflections (in seconds). */
64+
private float lateReverbDelay = 0.088f;
65+
/** Gain of the late reverberation (linear scale). */
66+
private float lateReverbGain = 0.768f;
67+
/** Delay time for the initial reflections (in seconds). */
68+
private float reflectDelay = 0.162f;
69+
/** Gain of the initial reflections (linear scale). */
70+
private float reflectGain = 0.052f;
71+
/** Flag limiting high-frequency decay by the overall decay time. */
72+
private boolean decayHfLimit = true;
73+
74+
public static final Environment Garage = new Environment(
75+
1, 1, 1, 1, .9f, .5f, .751f, .0039f, .661f, .0137f);
76+
public static final Environment Dungeon = new Environment(
77+
.75f, 1, 1, .75f, 1.6f, 1, 0.95f, 0.0026f, 0.93f, 0.0103f);
78+
public static final Environment Cavern = new Environment(
79+
.5f, 1, 1, .5f, 2.25f, 1, .908f, .0103f, .93f, .041f);
80+
public static final Environment AcousticLab = new Environment(
81+
.5f, 1, 1, 1, .28f, 1, .87f, .002f, .81f, .008f);
82+
public static final Environment Closet = new Environment(
83+
1, 1, 1, 1, .15f, 1, .6f, .0025f, .5f, .0006f);
84+
85+
/**
86+
* Utility method to convert an EAX decibel value to an amplitude factor.
87+
* EAX often expresses gain and attenuation in decibels scaled by 1000.
88+
* This method performs the reverse of that conversion to obtain a linear
89+
* amplitude value suitable for OpenAL.
90+
*
91+
* @param eaxDb The EAX decibel value (scaled by 1000).
92+
* @return The corresponding amplitude factor.
93+
*/
7294
private static float eaxDbToAmp(float eaxDb) {
7395
float dB = eaxDb / 2000f;
7496
return FastMath.pow(10f, dB);
7597
}
7698

99+
/**
100+
* Constructs a new, default {@code Environment}. The default values are
101+
* typically chosen to represent a neutral or common acoustic space.
102+
*/
77103
public Environment() {
78104
}
79105

106+
/**
107+
* Creates a new {@code Environment} as a copy of the provided {@code Environment}.
108+
*
109+
* @param source The {@code Environment} to copy the settings from.
110+
*/
80111
public Environment(Environment source) {
81112
this.airAbsorbGainHf = source.airAbsorbGainHf;
82113
this.roomRolloffFactor = source.roomRolloffFactor;
@@ -93,9 +124,24 @@ public Environment(Environment source) {
93124
this.decayHfLimit = source.decayHfLimit;
94125
}
95126

127+
/**
128+
* Creates a new {@code Environment} with the specified parameters. These parameters
129+
* directly influence the properties of the reverb effect as managed by OpenAL EFX.
130+
*
131+
* @param density The density of the medium.
132+
* @param diffusion The diffusion of the reflections.
133+
* @param gain Overall gain applied to the environment effect.
134+
* @param gainHf High-frequency gain applied to the environment effect.
135+
* @param decayTime The overall decay time of the reflected sound.
136+
* @param decayHf Ratio of high-frequency decay time to the overall decay time.
137+
* @param reflectGain Gain applied to the initial reflections.
138+
* @param reflectDelay Delay time for the initial reflections.
139+
* @param lateGain Gain applied to the late reverberation.
140+
* @param lateDelay Delay time for the late reverberation.
141+
*/
96142
public Environment(float density, float diffusion, float gain, float gainHf,
97-
float decayTime, float decayHf, float reflectGain,
98-
float reflectDelay, float lateGain, float lateDelay) {
143+
float decayTime, float decayHf, float reflectGain, float reflectDelay,
144+
float lateGain, float lateDelay) {
99145
this.decayTime = decayTime;
100146
this.decayHFRatio = decayHf;
101147
this.density = density;
@@ -108,6 +154,16 @@ public Environment(float density, float diffusion, float gain, float gainHf,
108154
this.reflectGain = reflectGain;
109155
}
110156

157+
/**
158+
* Creates a new {@code Environment} by interpreting an array of 28 float values
159+
* as an EAX preset. This constructor attempts to map the EAX preset values to
160+
* the corresponding OpenAL EFX parameters. Note that not all EAX parameters
161+
* have a direct equivalent in standard OpenAL EFX, so some values might be
162+
* approximated or ignored.
163+
*
164+
* @param e An array of 28 float values representing an EAX preset.
165+
* @throws IllegalArgumentException If the provided array does not have a length of 28.
166+
*/
111167
public Environment(float[] e) {
112168
if (e.length != 28)
113169
throw new IllegalArgumentException("Not an EAX preset");
@@ -254,27 +310,71 @@ public void setRoomRolloffFactor(float roomRolloffFactor) {
254310
}
255311

256312
@Override
257-
public boolean equals(Object env2) {
258-
if (env2 == null)
313+
public boolean equals(Object obj) {
314+
315+
if (!(obj instanceof Environment))
259316
return false;
260-
if (env2 == this)
317+
318+
if (obj == this)
261319
return true;
262-
if (!(env2 instanceof Environment))
263-
return false;
264320

265-
Environment e2 = (Environment) env2;
266-
return (e2.airAbsorbGainHf == airAbsorbGainHf
267-
&& e2.decayHFRatio == decayHFRatio
268-
&& e2.decayHfLimit == decayHfLimit
269-
&& e2.decayTime == decayTime
270-
&& e2.density == density
271-
&& e2.diffusion == diffusion
272-
&& e2.gain == gain
273-
&& e2.gainHf == gainHf
274-
&& e2.lateReverbDelay == lateReverbDelay
275-
&& e2.lateReverbGain == lateReverbGain
276-
&& e2.reflectDelay == reflectDelay
277-
&& e2.reflectGain == reflectGain
278-
&& e2.roomRolloffFactor == roomRolloffFactor);
279-
}
321+
Environment other = (Environment) obj;
322+
float epsilon = 1e-6f;
323+
324+
float[] thisFloats = {
325+
this.airAbsorbGainHf,
326+
this.decayHFRatio,
327+
this.decayTime,
328+
this.density,
329+
this.diffusion,
330+
this.gain,
331+
this.gainHf,
332+
this.lateReverbDelay,
333+
this.lateReverbGain,
334+
this.reflectDelay,
335+
this.reflectGain,
336+
this.roomRolloffFactor
337+
};
338+
339+
float[] otherFloats = {
340+
other.airAbsorbGainHf,
341+
other.decayHFRatio,
342+
other.decayTime,
343+
other.density,
344+
other.diffusion,
345+
other.gain,
346+
other.gainHf,
347+
other.lateReverbDelay,
348+
other.lateReverbGain,
349+
other.reflectDelay,
350+
other.reflectGain,
351+
other.roomRolloffFactor
352+
};
353+
354+
for (int i = 0; i < thisFloats.length; i++) {
355+
if (Math.abs(thisFloats[i] - otherFloats[i]) >= epsilon) {
356+
return false;
357+
}
358+
}
359+
360+
return this.decayHfLimit == other.decayHfLimit;
361+
}
362+
363+
@Override
364+
public int hashCode() {
365+
int result = (airAbsorbGainHf != +0.0f ? Float.floatToIntBits(airAbsorbGainHf) : 0);
366+
result = 31 * result + (roomRolloffFactor != +0.0f ? Float.floatToIntBits(roomRolloffFactor) : 0);
367+
result = 31 * result + (decayTime != +0.0f ? Float.floatToIntBits(decayTime) : 0);
368+
result = 31 * result + (decayHFRatio != +0.0f ? Float.floatToIntBits(decayHFRatio) : 0);
369+
result = 31 * result + (density != +0.0f ? Float.floatToIntBits(density) : 0);
370+
result = 31 * result + (diffusion != +0.0f ? Float.floatToIntBits(diffusion) : 0);
371+
result = 31 * result + (gain != +0.0f ? Float.floatToIntBits(gain) : 0);
372+
result = 31 * result + (gainHf != +0.0f ? Float.floatToIntBits(gainHf) : 0);
373+
result = 31 * result + (lateReverbDelay != +0.0f ? Float.floatToIntBits(lateReverbDelay) : 0);
374+
result = 31 * result + (lateReverbGain != +0.0f ? Float.floatToIntBits(lateReverbGain) : 0);
375+
result = 31 * result + (reflectDelay != +0.0f ? Float.floatToIntBits(reflectDelay) : 0);
376+
result = 31 * result + (reflectGain != +0.0f ? Float.floatToIntBits(reflectGain) : 0);
377+
result = 31 * result + (decayHfLimit ? 1 : 0);
378+
return result;
379+
}
280380
}

0 commit comments

Comments
 (0)