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
3434import 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 */
4045public 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