Sorry about the delay but I have finally managed to find the time to complete the Sound effect Tutorial which I hope you all enjoy.If you have not already check out the first tutorial here before reading this one, as it reuses a lot of the code.

In the previous tutorial we had a basic working sound system, but it was limited in scope. it could only be used in the class it was declared in and could not be used between activity’s easily. Ideally we would like one instance of the Sound Manager that could be used across the entire app life-cycle.

The solution is the Singleton design pattern explained better here.In essence, we will create only one instance of the Sound Manager class that can be accessed anywhere within the application.

The key to getting the singleton pattern to work in Java/Android is the function below.

	/**
	 * Requests the instance of the Sound Manager and creates it
	 * if it does not exist.
	 *
	 * @return Returns the single instance of the SoundManager
	 */
	static synchronized public SoundManager getInstance()
	{
	    if (_instance == null)
	      _instance = new SoundManager();
	    return _instance;
	 }

As the comment says the method checks to see if an instance already exists and creates one if it does not before returning the instance.You should also notice that the method is static which all fields and methods have to be for the singleton pattern to work.With this Method any and all classes within the app can access the direct instance should they need it.

The full class is shown below.

public class SoundManager {
 
	static private SoundManager _instance;
	private static SoundPool mSoundPool;
	private static HashMap mSoundPoolMap;
	private static AudioManager  mAudioManager;
	private static Context mContext;
 
	private SoundManager()
	{
	}
 
	/**
	 * Requests the instance of the Sound Manager and creates it
	 * if it does not exist.
	 *
	 * @return Returns the single instance of the SoundManager
	 */
	static synchronized public SoundManager getInstance()
	{
	    if (_instance == null)
	      _instance = new SoundManager();
	    return _instance;
	 }
 
	/**
	 * Initialises the storage for the sounds
	 *
	 * @param theContext The Application context
	 */
	public static  void initSounds(Context theContext)
	{
		 mContext = theContext;
	     mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
	     mSoundPoolMap = new HashMap();
	     mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
	} 
 
	/**
	 * Add a new Sound to the SoundPool
	 *
	 * @param Index - The Sound Index for Retrieval
	 * @param SoundID - The Android ID for the Sound asset.
	 */
	public static void addSound(int Index,int SoundID)
	{
		mSoundPoolMap.put(Index, mSoundPool.load(mContext, SoundID, 1));
	}
 
	/**
	 * Loads the various sound assets
	 * Currently hardcoded but could easily be changed to be flexible.
	 */
	public static void loadSounds()
	{
		mSoundPoolMap.put(1, mSoundPool.load(mContext, R.raw.starwars, 1));
		mSoundPoolMap.put(2, mSoundPool.load(mContext, R.raw.terminator, 1));
	}
 
	/**
	 * Plays a Sound
	 *
	 * @param index - The Index of the Sound to be played
	 * @param speed - The Speed to play not, not currently used but included for compatibility
	 */
	public static void playSound(int index,float speed)
	{
		     float streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
		     streamVolume = streamVolume / mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
		     mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, speed);
	}
 
	/**
	 * Stop a Sound
	 * @param index - index of the sound to be stopped
	 */
	public static void stopSound(int index)
	{
		mSoundPool.stop(mSoundPoolMap.get(index));
	}
 
	/**
	 * Deallocates the resources and Instance of SoundManager
	 */
	public static void cleanup()
	{
		mSoundPool.release();
		mSoundPool = null;
	    mSoundPoolMap.clear();
	    mAudioManager.unloadSoundEffects();
	    _instance = null;
 
	}
 
}

Now in order to use this Sound Manager in your apps it first needs to be initialised.So in your main Activity use the following code to set it up.

 //Create, Initialise and then load the Sound manager
        SoundManager.getInstance();
        SoundManager.initSounds(this);
        SoundManager.loadSounds();

From now on all that needs to be done to play a sound is to call SoundManager.PlaySound from any part of your code. Make sure to use the clean-up function when the app is destroyed to release the instance.

You can find a sample project for the code Here. The example flips between two activity’s which use the same Sound Manager instance.

Good luck with your projects and I hope this tutorial has been useful for you.

Stephen Flockton

Share