Skip to content

Android: Soundpool vs MediaPlayer (focus on soundboards and memory problems)

by mat on August 18th, 2010

I get a fair few emails asking for help on making soundboards because I have a few out on the market currently, so this is one of a few mini-tutorials I am creating to explain some of the difficulties to overcome.

So there are two methods for playing sounds in android SoundPool and MediaPlayer.

SoundPool

SoundPool is designed for short clips which can be kept in memory decompressed for quick access, this is best suited for sound effects in apps or games. Using this method with soundboards is a bad idea as you will be loading lots of “medium” sized sounds into the memory and you may exceed your limit (16Mb) and get an OutOfMemoryException.

MediaPlayer

MediaPlayer is designed for longer sound files or streams, this is best suited for music files or larger files. The files will be loaded from disk each time create is called, this will save on memory space but introduce a small delay (not really noticeable).

So lets have a look how to use Media Player instead of SoundPool

MediaPlayer Usage

MediaPlayer mp = MediaPlayer.create(ClassName.this, R.raw.sound);
mp.start();

Where ClassName.this should be the name of your class (Hint: this should be the name of the java file you are editing)

You can pause the sound playing and then use start to start the sound playing again.

mp.pause(); // Stop
mp.start();   // Start from place paused

To stop the sound playing use stop, using start now will start playing the sound again from the beginning

mp.stop();    // Stop sound
mp.start();   // Start from beginning

To reset the media player so it can be reinitialised with a another sound

mp.reset();
mp = MediaPlayer.create(ClassName.this, R.raw.sound2);

To release the resources once you are finished media player (free memory)

mp.release();

My Soundboards

Below are a few screenshots of my current soundboards on the market

17 Comments
  1. Aggh permalink

    Hey,

    I’ve been trying to create a soundboard with MediaPlayer but I was hitting some sort of limit and it was crashing after about 8 or so sounds were played…. I got the suggestion of using Ogg files instead of mp3 files and this helped a lot but it still stops playing sounds after 30 or so presses. Would it be possible to see where you create and release your mp object? This is the code I have, it is within an onclicklistener for a gridview after initializing the variables and a switch statement to set resid:

    // Added this bit to try and release mp to stop it crashing
        if (mp != null) {
           mp.release();   
       }
      		      
    // This object is initiated as null before my 
    // switch statement to set resid
       mp = MediaPlayer.create(getBaseContext(), resid); 
       mp.start(); 
    

    Thanks! Nice site btw :-)

  2. You should have your code inside its own function, which the onclicklistner calls, and use a single shared instance of MediaPlayer (one “global” mp). If this is already what you have, try adding reset in there as this is what I use and it works fine:

    	public void playSound(int input){
        	if (mp!=null){
        		mp.reset();
        		mp.release();
        	}
                mp = MediaPlayer.create(ClassName.this, input);
                mp.start();
        }
    

    Where input is the Resource ID of the sound I want to play.

  3. Aggh permalink

    Thanks!

    This works perfect now, also another reminder to me to think more Object Orientated!

    Is there a good way to capture the volume control, at the minute I can only change the media volume when a clip is playing.

  4. Aggh permalink

    Excellent, works perfect, thanks again!

  5. furrykef permalink

    I don’t understand the “AppName.this” idiom. Where does the “AppName” come from? Is it some kind of global instance of the Application class?

  6. @Aggh No prob.

    @furrykef It should really be ClassName.this which is should be the name of the file you are editing. For example my ‘Portal.java’ (public class Portal extends Activity… ) would be Portal.this. Sorry for the confusion.

    *Edited the post to correct this*

  7. furrykef permalink

    @mat
    I was (and am) having the same problem as Aggh. I tried making a class out of this… this is what I have (I hope it gets formatted right):

    import android.content.Context;
    import android.media.MediaPlayer;
    
    public class GlobalMediaPlayer {
        private static MediaPlayer m_mp;
    
        public static void playSound(Context context, int res_id) {
            if(m_mp != null) {
                m_mp.reset();
                m_mp.release();
            }
            m_mp = MediaPlayer.create(context, res_id);
            m_mp.start();
        }
    }

    Basically what I do to test it is I just click like crazy on my soundboard (pretty easy on hardware by dancing your fingers on it, hehe) and eventually the sound just stops working… I had to reboot the phone when I tried this particular version of the code. ^^;

    Any ideas?

  8. furrykef permalink

    @mat
    Ah, I guess I was thrown off by the AppName.this partly because I’d never seen “ClassName.this” (I’d just use “this” — is there a reason not to?), and partly because ’cause I was trying to implement this somewhere other than my Activity code (namely the GlobalMediaPlayer in the preceding post), so I wasn’t inside an Activity. Thanks for clearing it up, though. :)

    I actually wonder if getApplication() might be better than using “this”, too. I’m rather unclear on when to use which, though I do know enough NOT to use “this” when an object may persist beyond its Activity…

  9. @furrykef To be honest I’ve not done much java before android programming, so some of this stuff confuses me. I think the main thing to watch out for it memory leaks that can be cause by passing the wrong context. Perhaps someone with a more in-depth knowledge would like to fill in with something more constructive?

  10. furrykef permalink

    I withdraw my complaint about the code not working. It turned out I wasn’t in the function I thought I was in ’cause I forgot to update some calls… lol…

  11. Jason permalink

    “Below is a few screenshots of my current soundboards on the market”

    A person who mistreats the English language in this way are an idiot.

  12. @Jason, lol fixed.

  13. austin permalink

    THANKS MAT

  14. Sardtok permalink

    I know this post is old, but I saw you guys were asking about ClassName.this. Adding the ClassName in front of this, allows you to access the instance of an outer class with the class ClassName that the instance of an inner class belongs to. That sentence sounds a bit complicated, but if you have an inner class (non-static nested class) of some kind, and the outer and inner class both share variable or method names, you have to refer to ClassName.this to access the outer class’s variables or methods. You can also use ClassName.this to pass the instance of the outer class to another method.

    If you are unsure of inner classes, read: http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html and its sub-chapters.

  15. yasir iqbal permalink

    if we play two sounds together on multitouch event then both sound wil play?

Trackbacks & Pingbacks

  1. Soundpool vs MediaPlayer | ::: engineered eyes

Leave a Reply

Note: I am currently writing my thesis so probably wont have time to reply to your comment
Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS