Here's an example for managing sounds that will be played many times
(like gunshots, explosions, clicks, etc) using a pool and then sounds
that are just one-offs, like an announcer or an intro sound.
public class MediaPlayerPool {
private static final String TAG = "MediaPlayerPool";
private Context context;
private int streamType;
private HashMap<Integer, ArrayList<MediaPlayer>> pools;
public MediaPlayerPool(Context context, int streamType) {
this.context = context;
this.streamType = streamType;
pools = new HashMap<Integer, ArrayList<MediaPlayer>>();
}
public boolean hasMedia(int resourceId) {
return pools.keySet().contains(resourceId);
}
public void addMedia(int resourceId, int poolSize) {
ArrayList<MediaPlayer> pool = pools.get(resourceId);
if (pool == null) {
pool = new ArrayList<MediaPlayer>();
}
for (int i = 0; i < poolSize; i++) {
pool.add(createMediaPlayer(resourceId));
}
pools.put(resourceId, pool);
}
public void playMedia(int resourceId) {
ArrayList<MediaPlayer> pool = pools.get(resourceId);
MediaPlayer player = null;
if (pool.size() > 0) {
player = pool.remove(0);
}
if (player == null) {
Log.e(TAG, "Pool is empty for resource " + resourceId);
} else {
player.start();
}
}
public void release() {
for (Integer key : pools.keySet()) {
ArrayList<MediaPlayer> pool = pools.get(key);
for (MediaPlayer player : pool) {
if (player.isPlaying()) {
player.stop();
}
player.release();
}
pool.clear();
}
pools.clear();
}
private MediaPlayer createMediaPlayer(final int resourceId) {
MediaPlayer mp = MediaPlayer.create(context, resourceId);
mp.setOnCompletionListener(new
MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer player) {
player.seekTo(0);
returnToPool(resourceId, player);
}
});
mp.setAudioStreamType(streamType);
return mp;
}
private void returnToPool(int resourceId, MediaPlayer player) {
ArrayList<MediaPlayer> pool = pools.get(new
Integer(resourceId));
pool.add(player);
}
}
public class MediaPlayerSoundManager {
private static final String TAG = "MediaPlayerSoundManager";
private Context context;
private MediaPlayerPool pool;
private HashMap<Integer, Integer> soundResourceMap;
public MediaPlayerSoundManager(Context context) {
this.context = context;
this.pool = new MediaPlayerPool(context,
AudioManager.STREAM_MUSIC);
this.soundResourceMap = new HashMap<Integer, Integer>();
}
public void init() {
release();
pool.addMedia(R.raw.sound_1, 2);
soundResourceMap.put(SOUND_1, R.raw.sound_1);
}
public void playSound(int soundId) {
int resourceId = getResourceId(soundId);
if (pool.hasMedia(resourceId)) {
pool.playMedia(resourceId);
} else {
playOneShotSound(resourceId);
}
}
private int getResourceId(int soundId) {
Integer resourceId = soundResourceMap.get(soundId);
if (resourceId == null) {
Log.e(TAG, "No resource found for soundId " + soundId);
}
return resourceId;
}
private void playOneShotSound(int resourceId) {
MediaPlayer mp = MediaPlayer.create(context, resourceId);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.start();
mp.setOnCompletionListener(new
MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
arg0.release();
}
});
}
public void release() {
pool.release();
soundResourceMap.clear();
}
}
On Nov 10, 10:04 pm, plusminus <[EMAIL PROTECTED]> wrote:
> Hi all,
>
> any ideas on how to implement a kind of OnCompletionListener ?
> As I want to queue 2 sounds after each other :/
>
> Any help appreciated.
>
> Best Regards,
> plusminus
>
> On 15 Okt., 08:47, Robert Green <[EMAIL PROTECTED]> wrote:
>
> > I just read the whole discussion. All I can say is... What were they
> > thinking?? How is a developer supposed to be able to generate or
> > synthesize audio real time? These are important apps. Just look at
> > the guitar or harmonica app for the iPhone. Those are very popular
> > and do exactly that.
>
> > I'm just dumbfounded that the API developers don't provide such basic
> > functionality as setting a byte stream datasource for a media player.
> > Media players also are not adequate at all for games other than
> > providing the background music. Games often times have small samples
> > that are played very often and need to be layered on each other.
> > Maintaining a media player pool seems very heavy and cumbersome just
> > to achieve this, not to mention you may end up with a 100 media
> > players if you have 30 different samples and estimate that it would be
> > possible to play 3 at a time of each.
>
> > Another problem is that for racing, flying and other games which have
> > an "engine" sound, it's not possible to get the pitch of the engine to
> > match the speed shown on the game without being able to change the
> > sampling rate of the sound. I used SoundPool for that because it
> > supported changing the sampling rate while playing and it does work
> > correctly for me right now. Whoever designed SoundPool definitely
> > knew what they were doing for games because it's the right kind of API
> > for that but we still have the problem of not being able to produce
> > our own stream of audio on the fly and play it which limits what kind
> > of apps we can write and the general quality of the audio in games and
> > other applications.
>
> > Originally I was thinking that I'd go the old school route on the
> > sound in my game and just mix the audio in an update routine and
> > constantly feed the sound buffer but there is no option for this.
>
> > Unbelievable. I find this really discouraging. It's also very
> > frustrating that there is a SoundPool API which DOES WORK given a few
> > bugs and workarounds in the SDK 1.0 and is very suitable for 90% of
> > gaming applications as well as soundboard style apps and I'm sure
> > other things. Why would they get rid of this?!
>
> > blindfold - Where did you find that it's not supported under 1.0 r1?
> > I can't find any documentation on whether it's supported, intended for
> > future or recently added and already deprecated.
>
> > On Oct 15, 3:01 am, blindfold <[EMAIL PROTECTED]> wrote:
>
> > > > it works on both the emulator and a real G1.
>
> > > So you have access to a real G1. Lucky you!!
>
> > > > I'm really surprised that there is no access to the audio buffer.
> > > > How are we supposed to write dynamic audio generation apps?
>
> > > Unfortunately not supported by Android SDK 1.0 r1. See
>
> > >http://code.google.com/p/android/issues/detail?id=739
>
> > > and search this group for discussions on "ByteArrayInputStream".
>
> > > Regards
>
> > > On Oct 15, 12:43 am, Robert Green <[EMAIL PROTECTED]> wrote:
>
> > > > I used it for my game and it works on both the emulator and a real
> > > > G1. Just follow my example.
>
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---