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