= Audio in jME3
:revnumber: 2.0
:revdate: 2020/07/22
:keywords: sound, documentation, environment

Place audio files in the `assets/Sound/` directory of your project. jME3 supports Ogg Vorbis audio compression (.ogg) and uncompressed PCM Wave (.wav) formats. You can use for example link:https://www.audacityteam.org/download/[Audacity] to convert from other formats.


== Audio Terminology

*  *Streaming:* There are two ways to load audio data: Short audio files are to be stored entirely in memory (prebuffered), while long audio files, such as music, are streamed from the hard drive as it is played.
*  *Looping:* You can play a sound either once and then stop, or repeatedly (continuously) in a loop. +
You cannot loop streamed sounds.
*  *Instance:* If you play the same audio twice, the playing is queued up and jME plays one after the other. If you play instances of sounds, several instances of the same sound can play at the same time.


== Creating Audio Nodes: Streamed or Buffered

The main jME audio class to look at is `com.jme3.audio.AudioNode`. When creating a new audio node you need to declare whether how you want to load this sound:

*  *Buffered:* By default, a new audio node is buffered. This means jME3 loads the whole file into memory before playing. Use this for short sounds. You create a buffered sound  by setting DataType.Buffer, or using no DataType at all:
[source,java]
----
AudioNode boom = new AudioNode(assetManager, "Sound/boom.wav");
AudioNode boom = new AudioNode(assetManager, "Sound/boom.wav", DataType.Buffer);
----

*  *Streamed:* If it is a long file such as music or a dialog, you stream the audio. Streaming means, you load and play in parallel until the sound is done. You cannot loop streams. You create a streamed sound by setting the boolean to true:
[source,java]
----
AudioNode music = new AudioNode(assetManager, "Sound/music.wav", DataType.Stream);
----



== Getting AudioNode Properties

[cols="2", options="header"]
|===

a|AudioNode Method
a|Usage

a|getStatus()
a|Returns either AudioSource.Status.Playing, AudioSource.Status.Stopped, or AudioSource.Status.Paused.

a|getVolume()
a|Returns the volume.

a|getPitch()
a|Returns the pitch.

|===

[NOTE]
====
There are other obvious getters to poll the status of all corresponding setters listed here.
====


== Setting AudioNode Properties

[cols="2", options="header"]
|===

a|AudioNode Method
a|Usage

a|setTimeOffset(0.5f)
a|Play the sound starting at a 0.5 second offset from the beginning. Default is 0.

a|setPitch(1)
a|Makes the sound play in a higher or lower pitch. Default is 1. 2 is twice as high, .5f is half as high.

a|setVolume(1)
a|Sets the volume gain. 1 is the default volume, 2 is twice as loud, etc. 0 is silent/mute.

a|setRefDistance(50f)
a|The reference distance controls how far a sound can still be heard at 50% of its original volume (_this is assuming an exponential fall-off!_). A sound with a high RefDist can be heard loud over wide distances; a sound with a low refDist can only be heard when the listener is close by. Default is 10 world units.

a|setMaxDistance(100f)
a| The 'maximum attenuation distance' specifies how far from the source the sound stops growing more quiet (sounds in nature don't do that). Set this to a smaller value to keep the sound loud even at a distance; set this to higher value to let the sound fade out quickly. Default is 20 world units.

a|setLooping(false)
a|Configures the sound so that, if it is played, it plays once and stops. No looping is the default.

|===


=== Looping & Ambient Sounds

[cols="2", options="header"]
|===

a|AudioNode Method
a|Usage

a|setPositional(false) +
setDirectional(false)
a|All 3D effects switched off. This sound is global and plays in headspace (it appears to come from everywhere). Good for environmental ambient sounds and background music.

a|setLooping(true)
a|Configures the sound to be a loop: After the sound plays, it repeats from the beginning, until you call stop() or pause(). Good for music and ambient background noises. +
*Before 3.1-alpha2, Looping does not work on streamed sounds.*

|===


=== Positional 3D Sounds

[cols="2", options="header"]
|===

a|AudioNode Method
a|Usage

a|setPositional(true) +
setLocalTranslation(…)
a|Activates 3D audio: The sound appears to come from a certain position, where it is loudest. Position the AudioNode in the 3D scene, or move it with mobile players or NPCs.

a|setReverbEnabled(true)
a|Reverb is a 3D echo effect that only makes sense with positional AudioNodes. Use Audio Environments to make scenes sound as if they were "`outdoors`", or "`indoors`" in a large or small room, etc. The reverb effect is defined by the `com.jme3.audio.Environment` that the `audioRenderer` is in. See "`Setting Audio Environment Properties`" below.

|===


[IMPORTANT]
====
Positional 3D sounds require an `AudioListener` object in the scene (representing the player's ears).
====



=== Directional 3D Sounds

[cols="2", options="header"]
|===

a|AudioNode Method
a|Usage

a|setDirectional(true) +
setDirection(…)
a|Activates 3D audio: This sound can only be heard from a certain direction. Specify the direction and angle in the 3D scene if you have setDirectional() true. Use this to restrict noises that should not be heard, for example, through a wall.

a|setInnerAngle() +
setOuterAngle()
a|Set the angle in degrees for the directional audio. The angle is relative to the direction. Note: By default, both angles are 360° and the sound can be heard from all directions!

|===


[IMPORTANT]
====
Directional 3D sounds require an AudioListener object in the scene (representing the player's ears).
====



== Play, Pause, Stop

You play, pause, and stop a node called myAudioNode by using the respective of the following three methods:

[source,java]
----
myAudioNode.play();
----

[source,java]
----
myAudioNode.pause();
----

[source,java]
----
myAudioNode.stop();
----

[NOTE]
====
Whether an Audio Node plays continuously or only once, depends on the Loop properties you have set above!
====

You can also start playing instances of an AudioNode. Use the `playInstance()` method if you need to play the same AudioNode multiple times, possibly simulatenously. Note that changes to the parameters of the original AudioNode do not affect the instances that are already playing!

[source,java]
----
myAudioNode.playInstance();
----


== The Audio Listener

The default AudioListener object `listener` in `SimpleApplication` is the user's ear in the scene. If you use 3D audio (positional or directional sounds), you must move the AudioListener with the player: For example, for a first-person player, you move the listener with the camera. For a third-person player, you move the listener with the player avatar Geometry.

[source,java]
----

  @Override
  public void simpleUpdate(float tpf) {
    // first-person: keep the audio listener moving with the camera
    listener.setLocation(cam.getLocation());
    listener.setRotation(cam.getRotation());
  }

----


== Setting Audio Environment Properties

Optionally, You can choose from the following environmental presets from `com.jme3.audio.Environment`. This presets influence subtle echo effects (reverb) that evoke associations of different environments in your users. That is, it makes you scene sound "`indoors`" or "`outdoors`" etc. You use Audio Environments together with `setReverbEnabled(true)` on positional AudioNodes (see above).

[cols="11", options="header"]
|===

a|Environment
a|density
a|diffusion
a|gain
a|gainHf
a|decayTime
a|decayHf
a|reflGain
a|reflDelay
a|lateGain
a|lateDelay

<a|Garage
a|1.00f
a|1.0f
a|1.0f
a|1.00f
a|0.90f
a|0.5f
a|0.751f
a|0.0039f
a|0.661f
a|0.0137f

<a|Dungeon
a|0.75f
a|1.0f
a|1.0f
a|0.75f
a|1.60f
a|1.0f
a|0.950f
a|0.0026f
a|0.930f
a|0.0103f

<a|Cavern
a|0.50f
a|1.0f
a|1.0f
a|0.50f
a|2.25f
a|1.0f
a|0.908f
a|0.0103f
a|0.930f
a|0.0410f

a|AcousticLab
a|0.50f
a|1.0f
a|1.0f
a|1.00f
a|0.28f
a|1.0f
a|0.870f
a|0.0020f
a|0.810f
a|0.0080f

<a|Closet
a|1.00f
a|1.0f
a|1.0f
a|1.00f
a|0.15f
a|1.0f
a|0.600f
a|0.0025f
a|0.500f
a|0.0006f

|===

.  Activate a Environment preset
**  Either use a default, e.g. make you scene sounds like a dungeon environment:
+
[source,java]
----
audioRenderer.setEnvironment(new Environment(Environment.Dungeon));
----

**  Or activate xref:audio/audio_environment_presets.adoc[custom environment settings] in the Environment constructor:
+
[source,java]
----
audioRenderer.setEnvironment(
        new Environment( density, diffusion, gain, gainHf, decayTime, decayHf,
                reflGain, reflDelay, lateGain, lateDelay ) );
----


.  Activate 3D audio for certain sounds:
+
[source,java]
----
footstepsAudio.setPositional(true);
footstepsAudio.setReverbEnabled(true);
----



[TIP]
====
A sound engineer can create a custom `com.​jme3.​audio.Environment` object and specify custom environment values such as density, diffusion, gain, decay, delay… You can find many xref:audio/audio_environment_presets.adoc[examples of custom audio environment presets] here.
====


Advanced users find more info about OpenAL and its features here: link:http://web.archive.org/web/20130327063429/http://connect.creativelabs.com/openal/Documentation/OpenAL_Programmers_Guide.pdf[OpenAL 1.1 Specification].


[IMPORTANT]
====
It depends on the hardware whether audio effects are supported (if not, you get the message `OpenAL EFX not available! Audio effects won't work.`)
====
