Search code examples
androidsoundpool

How to speed up SoundPool in Android?


I am attempting to create a simple Morse code application. When the user presses a button the Morse sound should start before ending when released.

The problem is the latency- the Morse sound does not start until roughly 400ms after the user presses the button. I am not sure why this is exactly but after researching the problem i think it is the way my code is structured. The file i am trying to play is in Mp3 format and is located in the raw folder.

I had this completed using the Media Player but i ran into the same problem in regard it not being responsive enough so i opted to try and use Sound pool. Does anyone have any advice/suggestions as to how i can speed up the operation? This is new territory to me in regards development.

public int S1 = R.raw.morse;

private SoundPool soundPool;

private boolean loaded;

static int x;

public void initSounds(Context context) {

    soundPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 0);

    final int y = soundPool.load(context, R.raw.morse, 1);

    soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
        @Override
        public void onLoadComplete(SoundPool soundPool, int sampleId,
                                   int status) {
            loaded = true;

            playSound(y);

        }
    });
}


public void playSound(int soundID) {

    if(loaded) {
        x = soundPool.play(soundID, 0.5f, 0.5f, 1, 0, 1f);
    }

}

   //Calling code
   pad.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            if (event.getAction() == MotionEvent.ACTION_DOWN)
            {
                //State of a toggle button
                if(audioOnOff==true) {

       //Sound pool object is created and initialized as a global variabe
                    sp.initSounds(getApplicationContext());

                }
             }

Solution

  • It looks to me like what's happening here is that each time the button is pressed, you're loading the sound, waiting for it to finish loading, then playing it. What you actually want is to load the sound once, then just play it each time the button is pressed.

    So instead of calling initSounds in your onTouchListener, call initSounds somewhere else before the button is pressed. Then in your onTouchListener you just call your playSound method.

    Finally, make sure you remove the playSound method call from your onLoadCompleteListener so you don't get a mysterious noise when you initially load up the sound ;)