Sunday, May 18, 2008

A simple class for playing music and sound effects for android

I think that android has a few problems in the area of sound/music playback. After much digging, the only way that I have found to play back music and sound effects is android.media.MediaPlayer. I wanted to add music and sound effects to my game monolithandroid. So I came up with the following class, aptly named SoundSystem. This class uses a separate thread for playback, because we don't want our sound to slowdown our game rendering.


package org.teacake.monolith;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
public class SoundSystem extends Thread
{
public SoundSystem(android.content.Context context)
{
action = SOUND_DO_NOTHING;
lastEventTime= SystemClock.uptimeMillis();
this.context = context;
try
{
musicPlayer = android.media.MediaPlayer.create(context, R.raw.intro);
soundPlayerRotateBlock = android.media.MediaPlayer.create(context, R.raw.rotate);
soundPlayerExplosion = android.media.MediaPlayer.create(context, R.raw.explosion2);
soundPlayerPlaceBlock = android.media.MediaPlayer.create(context, R.raw.place);
musicPlayer.prepare();
musicPlayer.setLooping(1);
musicPlayer.seekTo(0);
soundPlayerRotateBlock.prepare();
soundPlayerRotateBlock.seekTo(0);
soundPlayerExplosion.prepare();
soundPlayerExplosion.seekTo(0);
}
catch(Exception e)
{
}
}
private void startMusic()
{
if(musicPlayer==null)
{
return;
}
try
{
if(musicPlayer.isPlaying())
{
return;
}
else
{
musicPlayer.start();
}
}
catch(Exception e)
{
}
}
private void stopMusic()
{
if(musicPlayer==null)
{
return;
}
try
{
musicPlayer.stop();
}
catch(Exception e)
{
}
}
private void playRotateBlock()
{
int duration=0;
int currentPosition=0;
if(soundPlayerRotateBlock==null)
{
return;
}
try
{
duration=soundPlayerRotateBlock.getDuration();
currentPosition=soundPlayerRotateBlock.getCurrentPosition();
//if(currentPosition==duration-1)
{
soundPlayerRotateBlock.seekTo(0);
soundPlayerRotateBlock.start();
}
}
catch(Exception e)
{
}
}
private void playExplosion()
{
int duration=0;
int currentPosition=0;
if(soundPlayerExplosion==null)
{
return;
}
try
{
duration=soundPlayerExplosion.getDuration();
currentPosition=soundPlayerExplosion.getCurrentPosition();
//if(currentPosition==duration-1)
{
soundPlayerExplosion.seekTo(0);
soundPlayerExplosion.start();
}
}
catch(Exception e)
{
}
}
private void playPlaceBlock()
{
int duration=0;
int currentPosition=0;
if(soundPlayerPlaceBlock==null)
{
return;
}
try
{
duration=soundPlayerPlaceBlock.getDuration();
currentPosition=soundPlayerPlaceBlock.getCurrentPosition();
//if(currentPosition==duration-1)
{
soundPlayerPlaceBlock.seekTo(0);
soundPlayerPlaceBlock.start();
}
}
catch(Exception e)
{

}
}
@Override
public void run()
{
while(!done)
{
switch(action)
{
case SOUND_START_MUSIC:
startMusic();
break;
case SOUND_STOP_MUSIC:
stopMusic();
break;
case SOUND_PLAY_ROTATE_BLOCK:
playRotateBlock();
break;
case SOUND_PLAY_EXPLOSION:
playExplosion();
break;
case SOUND_PLAY_PLACE_BLOCK:
playPlaceBlock();
break;
}
action=SOUND_DO_NOTHING;
try
{
java.lang.Thread.currentThread().sleep(100);
}
catch(Exception e)
{
}
}
}
public boolean done;
public final Handler messageHandler = new Handler() {
@Override
public void handleMessage(Message msg)
{
try
{
action=msg.what;
}
catch(Exception e)
{
}
}
};
private android.content.Context context;
public long lastEventTime;
public int action;
public static final int SOUND_DO_NOTHING=-1;
public static final int SOUND_START_MUSIC=0;
public static final int SOUND_STOP_MUSIC=1;
public static final int SOUND_PLAY_ROTATE_BLOCK=2;
public static final int SOUND_PLAY_EXPLOSION=3;
public static final int SOUND_PLAY_PLACE_BLOCK=4;
private android.media.MediaPlayer musicPlayer;
private android.media.MediaPlayer soundPlayerRotateBlock;
private android.media.MediaPlayer soundPlayerExplosion;
private android.media.MediaPlayer soundPlayerPlaceBlock;
}


As you can see the run() method calls the appropriate method for playing each sound, depending on the message received. How do we send a message to the thread? By using the following code:


android.os.Message message = android.os.Message.obtain(soundSystem.messageHandler, SoundSystem.SOUND_START_MUSIC);
message.sendToTarget();


Notice that we use a MediaPlayer object for each sound. I don't know how heavyweight the MediaPlayer object is, and if it is suitable for use for playing 10's or even 100's of sounds. So that could be a problem if you use a lot of sounds for your game. Also, we use synchronous playback, and that could be a problem, too, if our sounds are long. But since it is only version 1.0, it will be improved

No comments:

Search the web