Search code examples
androidperformancemedia-playerdelay

Playing audio is too slow in Android


I'm having a problem with Android's MediaPlayer in that it is too slow when calling the prepare method. I've tried to simply keep a Vector of the few MediaPlayer objects (with their preloaded data sources) but calling .start() multiple times results in weird issues.

The first issue is it will skip every other play, and sometimes the play will be half (or less) as loud.

The tones played are very very short but need to be played as quickly as possible. My source code is posted below.

Any help is greatly appreciated.

Kevin

package com.atClass.lemon;

import java.util.Vector;

import com.atClass.cardShoe.SettingTools.SETTING_PREF;
import com.atClass.cardShoe.SettingTools.SETTING_STUB;
import com.atClass.cardShoe.SettingTools.SETTING_VALUE;

import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.util.Config;
import android.util.Log;

public class MediaHandler {
    public static int cRepeat;
    public static float cVolume = Integer.valueOf(Prefs.cPrefsGet.getString(SETTING_PREF.annunciator_volume.name()+SETTING_STUB._int.name(), PrefDefaults.getDefault(SETTING_PREF.annunciator_volume,SETTING_STUB._int)));
    public static boolean cVolumeEnabled = !(Prefs.cPrefsGet.getString(SETTING_PREF.annunciator_volume.name()+SETTING_STUB._value.name(),PrefDefaults.getDefault(SETTING_PREF.annunciator_volume)).equals(SETTING_VALUE.disabled.name()));

    static Vector <MediaPlayer> cQuickMediaPlayerList = new Vector<MediaPlayer>();

    public static enum AUDIO_CLIP {
        app_boot_sound(R.raw.windows_hardware_insert),
        app_results_sound(R.raw.windows_exclamation),
        app_warning_sound(R.raw.windows_hardware_fail),
        app_card_draw_sound(R.raw.fs_beep5),
        app_lid_open_sound(R.raw.windows_hardware_fail),
        app_top_tigger_overdraw_sound(R.raw.fs_beep6),
        test(R.raw.fs_beep4);

        private int enumResourceId;
        AUDIO_CLIP(int input){ enumResourceId = input;}
        int getItem(){return enumResourceId;}
    }

    public static int getAudioClipIndex(AUDIO_CLIP iAudioClip){
        for (int i=0; i<AUDIO_CLIP.values().length; i++){
            if (AUDIO_CLIP.values()[i] == iAudioClip){
                return i;
            }
        }

        return 0;
    }


    public static void setupQuickMediaPlayer(){
        cQuickMediaPlayerList.clear();
        for (int i=0; i<AUDIO_CLIP.values().length; i++){

            MediaPlayer lMediaPlayer = new MediaPlayer();
            final AssetFileDescriptor afd = Global.gContext.getResources().openRawResourceFd(AUDIO_CLIP.values()[i].getItem());
            try{
                lMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                afd.close();
                lMediaPlayer.prepare();
            }catch(Exception e){}
            lMediaPlayer.setVolume(cVolume,cVolume);
            lMediaPlayer.setLooping(false);
            lMediaPlayer.setOnCompletionListener(new OnCompletionListener(){
                @Override
                public void onCompletion(MediaPlayer lMediaPlayer) {
                    lMediaPlayer.release();
                    try{lMediaPlayer.prepare();}catch(Exception e){e.printStackTrace();}
                }});
            cQuickMediaPlayerList.add(lMediaPlayer);
        }
    }

    public static void playAudio(AUDIO_CLIP iAudioClip){
        float volume = cVolume;

        volume++;
        volume /= 10;

        playAudio(iAudioClip,volume);
    }

    public static void playAudio(final AUDIO_CLIP iAudioClip, final float iVolume){

        Thread lThread = new Thread(new Runnable(){
            public void run() {
                //int resourceId = iAudioClip.getItem();                
                Log.d(Global.TAG,"--> Playing audio clip: " + iAudioClip.name() + "," + iAudioClip.getItem() + "," + getAudioClipIndex(iAudioClip));

                if (cVolumeEnabled == true){

                    //Log.d(Global.TAG,"--> Supplying volume: " + iVolume);
                    //Works but is too slow
//                  try {
//                      final MediaPlayer lMediaPlayer = new MediaPlayer();
//                      AssetFileDescriptor afd = Global.gContext.getResources().openRawResourceFd(iAudioClip.getItem());
//                      lMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
//                      afd.close();
//                      lMediaPlayer.prepare();
//                      lMediaPlayer.setVolume(iVolume,iVolume);
//                      lMediaPlayer.setLooping(false);
//                      lMediaPlayer.setOnCompletionListener(new OnCompletionListener(){
//                          @Override
//                          public void onCompletion(MediaPlayer arg0) {
//                              lMediaPlayer.release();
//                          }});
//                      lMediaPlayer.start();
//                  }catch(Exception e){}

                    try{
                        //Works half the time
                        cQuickMediaPlayerList.get(getAudioClipIndex(iAudioClip)).start();
                    }catch(Exception e){}
                }
            }
        });
        lThread.setPriority(Thread.MAX_PRIORITY);
        lThread.start();
    }
}

Solution

  • You should use SoundPool instead: http://developer.android.com/reference/android/media/SoundPool.html