/* * 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; } } }