I have now implemented a JadeSound class that seems to be working very well. There WAS a hitch in the use of MediaPlayer.
I kind of assumed that when you called MediaPlayer.release(), the instance of Media Player would be set to null. Not so.
Although a failed create set mp to null, if I reset and released the mp, and then didn't create a new one, the next time I entered the method, mp would still have the value of the released mp and a new reset() caused a fault.
package uk.co.amazonsystems.jade;
import java.util.ArrayList;
import android.content.Context;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.media.AudioManager;
public class JadeSound
{
// This class handles all sounds. There are two sound sources. Use soundpool for short
// transient sounds. A single soundpool does all the sounds.
// For background music and ambient sound, Use MediaPlayer. Each sound is a new mediaplayer.
// Only one sound can be running at a time. All such sounds are looped.
public static final int OK_SOUND = 0;
public static final int BAD_SOUND = 1;
public static final int NOSUCH_SOUND = 2;
public static final int BAD_PLAY = 3;
private SoundPool soundpool = null;
private static int CHANNS = 4; // Sound Channels
private String soundName; // current ambient sound name
private int [] SFX = new int[CHANNS]; // Stream IDs
private int priority = 1;
private int soundid[]; // Sound IDs
private Context thiscontext;
private MediaPlayer mp;
private ArrayList soundfiles;
private int buggins;
private boolean soundstate = true;
// Initialise
public JadeSound(Context JadeContext, ArrayList SFXFiles)
{
thiscontext = JadeContext;
soundfiles = SFXFiles;
if (soundpool != null) soundpool.release();
soundpool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
int temp = soundfiles.size();
soundid = new int [temp];
for (int ii = 0; ii < temp; ii++)
{
int resid = getRaw(thiscontext, soundfiles.get(ii));
if (resid == 0)
{
soundid[ii] = 0;
}
else
{
soundid[ii] = soundpool.load(thiscontext, resid, priority);
}
}
for (int ii = 0; ii < CHANNS; ii++)
{
SFX[ii] = -1;
}
buggins = 0;
}
public int playSFX(String name)
{
return playSFX(name, 0);
}
public int playSFX(String name, int Loop)
{
int index = soundfiles.indexOf(name);
if (index == -1)
{
return NOSUCH_SOUND;
}
else
{
soundpool.stop(SFX[buggins]);
if (soundid[index] != 0)
{
int reply = soundpool.play(soundid[index], 1, 1, priority, Loop, 1);
if (reply == 0) return BAD_PLAY;
SFX[buggins] = reply;
buggins++;
if (buggins >= CHANNS)
{
buggins = 0;
}
}
else return BAD_SOUND;
}
return OK_SOUND;
}
public int playAmbient(String name)
{
// if the same sound name, just exit immediately
// we use the same mp we used last time, and keep playing the same song
if (soundName != null)
{
if (soundName.equals(name))
{
return OK_SOUND;
}
}
// if the media player still in use, reset it, release it and null it
if (mp != null)
{
mp.reset();
mp.release();
mp = null;
}
// remember the new sound name for next call
soundName = name;
// find the sound file in raw
int resid = getRaw(thiscontext, name);
// if it's not there, return
if (resid == 0)
{
return BAD_SOUND;
}
// Finally, create a media player
mp = MediaPlayer.create(thiscontext, resid);
// if it doesn't work, return
if (mp == null) return BAD_SOUND;
// Ambient always loops
mp.setLooping(true);
// start the playback
mp.start();
// if the song flag is false, pause it
// we may have to start it later
if (!getSoundState())
pauseAmbient();
return OK_SOUND;
}
public void pauseAmbient()
{
if (mp != null)
{
mp.pause();
}
}
public void resumeAmbient()
{
if (getSoundState())
{
if (mp != null)
{
mp.start();
}
}
}
public void pauseAll()
{
if (soundpool != null) soundpool.autoPause();
pauseAmbient();
}
public void resumeAll()
{
if (soundpool != null) soundpool.autoResume();
resumeAmbient();
}
public void closeSound()
{
if (soundpool != null)
{
soundpool.release();
soundpool = null;
}
if (mp != null)
{
mp.reset();
mp.release();
mp = null;
}
}
public void setSoundState(boolean state)
{
soundstate = state;
}
public boolean getSoundState()
{
return soundstate;
}
// Helper method that translates a filename in res/raw to a resource id
public static int getRaw(Context context, String name)
{
return context.getResources().getIdentifier(name,
"raw", context.getPackageName());
}
}