We will get started with the Libgdx sound system by playing short sound effects, also known as SFX. Often, effects go unnoticed, and this is really unfair towards them! As an exercise, try turning the effects' volume down in an action shooter and see how much you enjoy it. It is not the same experience at all, is it?
The sample shown in this recipe will illustrate how to play, pause, resume, and stop sounds. We will map the number keys from 1 to 7 to different sounds. The P key will pause the sounds, R will resume playback, and S will stop playback.
The code for this recipe will be found in the SoundEffectSample
class. Follow these instructions to master how to play back sound effects:
Sound
. An IntMap
of Sound
instances will help us manage the sound collection of our sample. The effects will be played when the user presses the number keys from 1 to 7:private IntMap<Integer, Sound> soundKeys;
create()
method to construct our collections and populate them. Sound
objects are instantiated through the Gdx.audio.newSound()
method passing in the appropriate file handle; we instantiate with all seven effects under the data/sfx
folder. The key sound dictionary will contain the key code from Keys.NUM_1
to Keys.NUM_7
, pointing to the corresponding entries in the sound arrays. Finally, we set our SoundEffectSample
class as the input processor and show the sample controls on the console output:public void create() { sounds = new IntMap<Sound>(); sounds.put(Keys.NUM_1, Gdx.audio.newSound(Gdx.files.internal("data/sfx/sfx_01.wav"))); … Gdx.input.setInputProcessor(this); Gdx.app.log("SoundEffectSample", "Instructions"); … }
Sound
objects need disposing when they are no longer needed so as to avoid nasty resource leaks. We iterate over the sound collections calling dispose()
on all of the entries:public void dispose() { for (Sound sound : sounds.values()) { sound.dispose(); } }
Sound
object can be used to play several instances of itself at the same time. Every time we call its play()
method, the effect will be played and we will get a playID
handle back, which we can use to refer to the instance later.keyDown()
event handler. When a user presses the S key, we need to stop playing all sounds. Calling the stop()
method on a Sound
object will halt all effects that were played from it:if (keycode == Keys.S) { for (Sound sound : sounds.values()) { sound.stop(); } Gdx.app.log("SoundEffectSample", "Sounds stopped"); }
pause()
method:else if (keycode == Keys.P) { for (Sound sound : sounds.values()) { sound.pause(); } Gdx.app.log("SoundEffectSample", "Sounds paused"); }
resume()
method and all the instances to resume the paused sounds:else if (keycode == Keys.R) { for (Sound sound : sounds.values()) { sound.resume(); } Gdx.app.log("SoundEffectSample", "Sounds resumed"); }
sounds
dictionary to see whether there is a sound we should play using the play()
method:else { Sound sound = sounds.get(keycode); if (sound != null) { sound.play(); Gdx.app.log("SoundEffectSample", "Playing sound"); } }
Sound
instance from the array whenever the user touches the screen:public boolean touchDown (int screenX, int screenY, int pointer, int button) { Sound sound = sounds.get(MathUtils.random(sounds.size - 1)); sound.play(); Gdx.app.log("SoundEffectSample", "Playing sound"); return true; }
Libgdx offers an audio interface to let us work with sound effects and music in a platform-agnostic way. Each backend implements it using different resources, as follows:
Several formats are supported for sound effects in Libgdx. Make your choice depending on your needs: WAV, MP3, and OGG (unsupported in iOS).
Quite a few goodies are available to us in the Sound
interface.
We already mentioned that the play()
method returns a handle that we can store to manage effect instances individually later on. The other methods are as follows:
long soundID = sound.play(); sound.pause(soundID); sound.resume(soundID); sound.stop(soundID);
Note that if the effect of the handle references has finished playing, anything that we do with its handle will have no effect and fail silently.
Volume is represented with a float ranging from 0.0f
to 1.0f
. We can set an effect's volume by doing the following:
sound.setVolume(soundID, volume);
To play a sound effect that will keep playing indefinitely, you can make use of the loop()
method, which also returns a handle to reference the instance later on:
long soundID = sound.loop();
You can change your mind at any time and tell an effect to stop looping; in this case, you will have to call setLooping()
with the corresponding handle:
sound.setLooping(soundID, false);
There is a limit on how many sound effects can be played at a time, but such limits are configurable on Android and desktops at application startup time, through the configuration objects passed to the application instance:
AndroidApplicationConfiguration.maxSimultaneousSounds LwglApplicationConfiguration.audioDeviceSimultaneousSources
If your game environment is rich and complex, it is not rare to exceed the sound limit at times. However, you might be quite keen on making sure that very specific instances play above all others. For instance, in an RPG, you might not care if the cow in the background moos, as long as the NPC that gives the player a new quest is properly heard.
Libgdx lets us give the sound system hints on how important an effect request is:
sound.setPriority(soundID, priority);
Priorities are set using integer values indicating their positions on the sound queue, so sounds with a smaller priority will be considered first if the queue is full.
3.129.210.102