SoundManager.java
/*
* Copyright © 2012 Nokia Corporation. All rights reserved.
* Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.
* Oracle and Java are trademarks or registered trademarks of Oracle and/or its
* affiliates. Other product and company names mentioned herein may be trademarks
* or trade names of their respective owners.
* See LICENSE.TXT for license information.
*/
package com.nokia.example.drumkit;
import java.io.InputStream;
import java.util.Vector;
import javax.microedition.media.Manager;
import javax.microedition.media.Player;
public class SoundManager {
public static final int SAMPLE_KICK = 0;
public static final int SAMPLE_SNARE = 1;
public static final int SAMPLE_COWBELL = 2;
public static final int SAMPLE_HIHAT_OPEN = 3;
public static final int SAMPLE_HIHAT_CLOSED = 4;
public static final int SAMPLE_CRASH = 5;
public static final int SAMPLE_SPLASH = 6;
public static final int SAMPLE_RIDE_BELL = 7;
public static final int SAMPLE_RIDE = 8;
public static final int SAMPLE_TOM1 = 9;
public static final int SAMPLE_TOM2 = 10;
public static final int SAMPLE_TOM3 = 11;
private static int maxPrefetchedPlayers = 8;
private static int maxStartedPlayers = supportsMixing() ? 3 : 1;
private static final Vector prefetchedPlayers = new Vector();
private static final Vector startedPlayers = new Vector();
private static final String[] resources = {
"/kick.wav", // 0
"/snare.wav", // 1
"/cowbell.wav", // 2
"/hihat2.wav", // 3
"/hihat1.wav", // 4
"/crash.wav", // 5
"/splash.wav", // 6
"/ride2.wav", // 7
"/ride1.wav", // 8
"/tom1.wav", // 9
"/tom2.wav", // 10
"/tom3.wav" // 11
};
/**
* @return true if mixing is supported
*/
public static boolean supportsMixing() {
String s = System.getProperty("supports.mixing");
return s != null && s.equalsIgnoreCase("true") && !Main.isS60Phone();
}
/**
* Play a sound
* @param sound
*/
public static void playSound(int sound) {
if (restart(sound)) {
return;
}
Player player = null;
InputStream stream = SoundManager.class.getResourceAsStream(resources[sound]);
try {
limitPrefetchedPlayers();
player = Manager.createPlayer(stream, "audio/wav");
player.realize();
player.prefetch();
start(sound, player);
}
catch (Exception e) {
// Either the device is in silent mode...
if (prefetchedPlayers.isEmpty()) {
Main.getInstance().sampleAlert();
}
// ...or does not support having all 8 players prefetched
else if (maxPrefetchedPlayers > 1) {
// Reduce amount of players and try again
maxPrefetchedPlayers--;
playSound(sound);
}
}
}
/**
* Clean up all loaded resources
*/
public static void cleanUp() {
synchronized (prefetchedPlayers) {
while (!prefetchedPlayers.isEmpty()) {
clean((SoundPlayer) prefetchedPlayers.firstElement());
}
}
}
/**
* Deallocate player
* @param sp
*/
private static void clean(SoundPlayer sp) {
synchronized (prefetchedPlayers) {
prefetchedPlayers.removeElement(sp);
stop(sp.player);
try {
sp.player.deallocate();
sp.player.close();
}
catch (Exception e) {
}
}
}
/**
* Restart player, if it's already in prefetched players
* @param sound
* @return
*/
private static boolean restart(int sound) {
synchronized (prefetchedPlayers) {
for (int i = 0; i < prefetchedPlayers.size(); i++) {
SoundPlayer sp = (SoundPlayer) prefetchedPlayers.elementAt(i);
if (sp.sound == sound) {
prefetchedPlayers.removeElement(sp);
prefetchedPlayers.addElement(sp);
stop(sp.player);
try {
sp.player.setMediaTime(0);
}
catch (Exception e) {
}
start(sp.player);
return true;
}
}
return false;
}
}
/**
* Limit the amount of prefetched players
*/
private static void limitPrefetchedPlayers() {
synchronized (prefetchedPlayers) {
try {
while (prefetchedPlayers.size() >= maxPrefetchedPlayers) {
SoundPlayer sp = (SoundPlayer) prefetchedPlayers.firstElement();
clean(sp);
}
}
catch (Exception e) {
}
}
}
/**
* Start a new player
* @param sound
* @param player
*/
private static void start(int sound, Player player) {
synchronized (prefetchedPlayers) {
prefetchedPlayers.addElement(new SoundPlayer(sound, player));
start(player);
}
}
/**
* Start a
* @param player
*/
private static void start(Player player) {
synchronized (startedPlayers) {
try {
while (startedPlayers.size() >= maxStartedPlayers) {
Player p = (Player) startedPlayers.firstElement();
startedPlayers.removeElementAt(0);
stop(p);
}
}
catch (Exception e) {
}
startedPlayers.addElement(player);
try {
player.start();
}
catch (Exception e) {
}
}
}
/**
* Stop a player
* @param player
*/
private static void stop(Player player) {
synchronized (startedPlayers) {
startedPlayers.removeElement(player);
try {
if (player.getState() == Player.STARTED) {
try {
player.stop();
}
catch (Exception e) {
}
}
}
catch (Exception e) {
}
}
}
/**
* Associate a sound to a player
*/
private static class SoundPlayer {
public final int sound;
public final Player player;
public SoundPlayer(int sound, Player player) {
this.sound = sound;
this.player = player;
}
}
}