AudioManager.java

/*
 * Copyright © 2011 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.battletank.game.audio;

import java.util.Timer;
import java.util.TimerTask;

public class AudioManager {
    private static final SoundEffect[] PLAY_BUFFER;
    static {
        String s = System.getProperty("supports.mixing");
        PLAY_BUFFER = s != null && s.equalsIgnoreCase("true") ? new SoundEffect[3] : new SoundEffect[1];
        // TODO more testing with Symbian devices which might not be able to mix sounds although report that mixing is supported
    }

    public static final int EXPLOSION_LARGE = 0;
    public static final int EXPLOSION_SMALL = 1;
    public static final int CANNON = 2;

    private static final SoundEffect[] EFFECTS = new SoundEffect[3];
    static {
        EFFECTS[EXPLOSION_LARGE] = new SoundEffect("explosion.mp3");
        EFFECTS[EXPLOSION_SMALL] = new SoundEffect("explosion2.mp3");
        EFFECTS[CANNON] = new SoundEffect("firing.mp3");
    }

    private static boolean soundsEnabled = false;
    private static Timer timer = new Timer();

    public static void setSoundEnabled(boolean enable) {
        if(enable) enableSounds();
        else disableSounds();
    }

    public static boolean areSoundsEnabled() {
        return soundsEnabled;
    }

    public static void enableSounds() {
        if(soundsEnabled) return;
        soundsEnabled = true;
        for(int i = 0; i < EFFECTS.length; i++) {
            EFFECTS[i].load();
        }
    }

    public static void disableSounds() {
        if(!soundsEnabled) return;
        soundsEnabled = false;
        for(int i = 0; i < EFFECTS.length; i++) {
            EFFECTS[i].close();
        }
    }

    public static void bufferEffect(int effect, int volume) {
        EFFECTS[effect].volume = Math.max(EFFECTS[effect].volume, volume);
    }

    public static void playEffects() {
        if(!soundsEnabled) return;
        timer.schedule(new TimerTask() {
            public void run() {
                int channels = PLAY_BUFFER.length;
                for(int effect = 0; effect < EFFECTS.length; effect++) {
                    for(int channel = 0; channel < channels; channel++) {
                        int t = (channel + effect) % channels;
                        if(PLAY_BUFFER[t] == null || PLAY_BUFFER[t].volume < EFFECTS[effect].volume) {
                            PLAY_BUFFER[t] = EFFECTS[effect];
                        }
                    }
                }
                for(int effect = 0; effect < EFFECTS.length; effect++) {
                    boolean contains = false;
                    for(int channel = 0; channel < channels; channel++) {
                        contains = PLAY_BUFFER[channel] == EFFECTS[effect];
                        if(contains) break;
                    }
                    if(!contains) EFFECTS[effect].deallocate();
                }
                for(int channel = 0; channel < channels; channel++) {
                    PLAY_BUFFER[channel].play();
                }
            }
        }, 0);
    }
}