blob: 65854d0208e7fb0ccd62bce575c5239e470bf572 [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.replica.replicaisland;
import java.util.Comparator;
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
public class SoundSystem extends BaseObject {
private static final int MAX_STREAMS = 8;
private static final int MAX_SOUNDS = 32;
private static final SoundComparator sSoundComparator = new SoundComparator();
public static final int PRIORITY_LOW = 0;
public static final int PRIORITY_NORMAL = 1;
public static final int PRIORITY_HIGH = 2;
public static final int PRIORITY_MUSIC = 3;
private SoundPool mSoundPool;
private FixedSizeArray<Sound> mSounds;
private Sound mSearchDummy;
private boolean mSoundEnabled;
private int[] mLoopingStreams;
public SoundSystem() {
super();
mSoundPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, 0);
mSounds = new FixedSizeArray<Sound>(MAX_SOUNDS, sSoundComparator);
mSearchDummy = new Sound();
mLoopingStreams = new int[MAX_STREAMS];
for (int x = 0; x < mLoopingStreams.length; x++) {
mLoopingStreams[x] = -1;
}
}
@Override
public void reset() {
mSoundPool.release();
mSounds.clear();
mSoundEnabled = true;
for (int x = 0; x < mLoopingStreams.length; x++) {
mLoopingStreams[x] = -1;
}
}
public Sound load(int resource) {
final int index = findSound(resource);
Sound result = null;
if (index < 0) {
// new sound.
if (sSystemRegistry.contextParameters != null) {
Context context = sSystemRegistry.contextParameters.context;
result = new Sound();
result.resource = resource;
result.soundId = mSoundPool.load(context, resource, 1);
mSounds.add(result);
mSounds.sort(false);
}
} else {
result = mSounds.get(index);
}
return result;
}
synchronized public final int play(Sound sound, boolean loop, int priority) {
int stream = -1;
if (mSoundEnabled) {
stream = mSoundPool.play(sound.soundId, 1.0f, 1.0f, priority, loop ? -1 : 0, 1.0f);
if (loop) {
addLoopingStream(stream);
}
}
return stream;
}
synchronized public final int play(Sound sound, boolean loop, int priority, float volume, float rate) {
int stream = -1;
if (mSoundEnabled) {
stream = mSoundPool.play(sound.soundId, volume, volume, priority, loop ? -1 : 0, rate);
if (loop) {
addLoopingStream(stream);
}
}
return stream;
}
public final void stop(int stream) {
mSoundPool.stop(stream);
removeLoopingStream(stream);
}
public final void pause(int stream) {
mSoundPool.pause(stream);
}
public final void resume(int stream) {
mSoundPool.resume(stream);
}
public final void stopAll() {
final int count = mLoopingStreams.length;
for (int x = count - 1; x >= 0; x--) {
if (mLoopingStreams[x] >= 0) {
stop(mLoopingStreams[x]);
}
}
}
// HACK: There's no way to pause an entire sound pool, but if we
// don't do something when our parent activity is paused, looping
// sounds will continue to play. Rather that reproduce all the bookkeeping
// that SoundPool does internally here, I've opted to just pause looping
// sounds when the Activity is paused.
public void pauseAll() {
final int count = mLoopingStreams.length;
for (int x = 0; x < count; x++) {
if (mLoopingStreams[x] >= 0) {
pause(mLoopingStreams[x]);
}
}
}
private void addLoopingStream(int stream) {
final int count = mLoopingStreams.length;
for (int x = 0; x < count; x++) {
if (mLoopingStreams[x] < 0) {
mLoopingStreams[x] = stream;
break;
}
}
}
private void removeLoopingStream(int stream) {
final int count = mLoopingStreams.length;
for (int x = 0; x < count; x++) {
if (mLoopingStreams[x] == stream) {
mLoopingStreams[x] = -1;
break;
}
}
}
private final int findSound(int resource) {
mSearchDummy.resource = resource;
return mSounds.find(mSearchDummy, false);
}
synchronized public final void setSoundEnabled(boolean soundEnabled) {
mSoundEnabled = soundEnabled;
}
public final boolean getSoundEnabled() {
return mSoundEnabled;
}
public class Sound extends AllocationGuard {
public int resource;
public int soundId;
}
/** Comparator for sounds. */
private final static class SoundComparator implements Comparator<Sound> {
public int compare(final Sound object1, final Sound object2) {
int result = 0;
if (object1 == null && object2 != null) {
result = 1;
} else if (object1 != null && object2 == null) {
result = -1;
} else if (object1 != null && object2 != null) {
result = object1.resource - object2.resource;
}
return result;
}
}
}