Home Tutorials Hints & Tips


Getting Started in Android Development

Part 26 - The Android SoundPool Builder

The Android SoundPool is optimized for short sounds such as sound effects for games or sounds for button clicks and the like. There are other Android sound resources we can use. Media player is ideal for playing music, and Audiotrack is optimized for the playback of Pulse Code Modulated (PCM) data such that found in uncompressed .WAV files or synthesized waveforms. I have tutorials on each: Mediaplayer, AudioTrack.

The SoundPool constructor was deprecated in API 21 (Lollipop) and replaced with SoundPool Builder. Therefore, we need to handle these changes in our tutorial so that we can used the new code, but make sure that any device running lower API version supports the functionality.

In essence with SoundPool, we are setting aside an area of device memory and preloading sounds into the SoundPool. The sounds can be of any supported audio format. In my experience I have found that the open container format (.OGG files) produces better results than MP3 files. This is something worth trying if the sounds are not working as desired. Each sound is then given an index in the SoundPool and we simply need to access that index to play the sound.

In our example, we will work with two sound effects that can be played concurrently. Like all other music or audio files, they are placed in the ‘raw’ folder within the resources. The sounds we will work with are for an explosion and a spring.

The Android Studio raw folder location

A simple layout was constructed with just two buttons. The code for this layout is shown below:

Code

Start by declaring some variables. One of type SoundPool and two integer variables representing the index for each sound.

SoundPool ourSounds;
int soundExplosion;
int soundSpring;

Each button should have an onClickListenser set.

The bulk of the code is focused on setting up the SoundPool ourSounds.

For API 21 or greater, first you can tell the system about the sounds you are using. The type of sounds and what they are used for. This is information is passed to the system in the form of an AudioAttributes Builder. The code we use for this example is shown below:


AudioAttributes audioAttributes = new AudioAttributes.Builder()
     .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
     .setUsage(AudioAttributes.USAGE_GAME)
     .build();

You can find more information about Audio Attributes here.

The next task is to setup the SoundPool builder. We used the code below for our example:

ourSounds = new SoundPool.Builder()
      .setMaxStreams(2)
      .setAudioAttributes(audioAttributes)
      .build();

The key here is to set the maximum number of concurrent streams that need to be played. Two is this example.

One last task is to then associate each index with the actual sound file stored in the ‘raw’ folder.

soundExplosion = ourSounds.load(this, R.raw.explosion, 1);
soundSpring = ourSounds.load(this, R.raw.spring, 1);

The final parameter is set to 1. This is a priority that is currently unused, but should be set for future compatibility.

For API versions less than 21, you continue to use the old SoundPool constructor without the audio attributes. The code is below. The indexes are mapped to the sound file using the same code as for API 21.

ourSounds = new SoundPool(2, AudioManager.STREAM_MUSIC, 1);
soundExplosion = ourSounds.load(this, R.raw.explosion, 1);
soundSpring = ourSounds.load(this, R.raw.spring, 1);

The parameters of SoundPool method are:

It is worth taking some time to look at the code used to detect the API version of the device and select the appropriate block of code to execute. This is done with an ‘if..else’ statement:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
     //code greater or equal to API 21 (lollipop)
} else {
    //code for all other versions
}

The final task is the place the code to play each sound within the onClick methods for each button. The format is below:

ourSounds.play (soundExplosion, 0.9f, 0.9f, 1, 0, 1);
ourSounds.play (soundSpring, 0.9f, 0.9f, 1, 0, 1);

We call the index to select the desired sound: soundExplosion or soundSpring. The two floating point numbers represent the left and right channel volumes. They can be set between 0.0f and 1.0f. The next parameter is the priority. The next is whether to set the sound to loop or not. Zero being no loop and ‘-1’ is forever. The final parameter is the speed of playback. 1.0 being normal and the range can be between 0.5 and 2.0.

After this tutorial your SoundPoolActivity.java file should look similar to the one below:


After this tutorial your AndroidManifest file should look similar to the one below:

After this tutorial your ListViewActivity.java file should look similar to the one below:


Download Download tutorial set 1



Privacy and Cookies Disclaimer Copyright
© 2015 - 2018 North Border Tech Training All rights reserved