Home | History | Annotate | Download | only in replicaisland
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.replica.replicaisland;
     18 
     19 import java.util.Comparator;
     20 
     21 import android.content.Context;
     22 import android.media.AudioManager;
     23 import android.media.SoundPool;
     24 
     25 public class SoundSystem extends BaseObject {
     26     private static final int MAX_STREAMS = 8;
     27     private static final int MAX_SOUNDS = 32;
     28     private static final SoundComparator sSoundComparator = new SoundComparator();
     29 
     30     public static final int PRIORITY_LOW = 0;
     31     public static final int PRIORITY_NORMAL = 1;
     32     public static final int PRIORITY_HIGH = 2;
     33     public static final int PRIORITY_MUSIC = 3;
     34 
     35     private SoundPool mSoundPool;
     36     private FixedSizeArray<Sound> mSounds;
     37     private Sound mSearchDummy;
     38     private boolean mSoundEnabled;
     39     private int[] mLoopingStreams;
     40 
     41     public SoundSystem() {
     42         super();
     43         mSoundPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, 0);
     44         mSounds = new FixedSizeArray<Sound>(MAX_SOUNDS, sSoundComparator);
     45         mSearchDummy = new Sound();
     46         mLoopingStreams = new int[MAX_STREAMS];
     47         for (int x = 0; x < mLoopingStreams.length; x++) {
     48         	mLoopingStreams[x] = -1;
     49         }
     50     }
     51 
     52     @Override
     53     public void reset() {
     54         mSoundPool.release();
     55         mSounds.clear();
     56         mSoundEnabled = true;
     57         for (int x = 0; x < mLoopingStreams.length; x++) {
     58         	mLoopingStreams[x] = -1;
     59         }
     60     }
     61 
     62     public Sound load(int resource) {
     63         final int index = findSound(resource);
     64         Sound result = null;
     65         if (index < 0) {
     66             // new sound.
     67            if (sSystemRegistry.contextParameters != null) {
     68                Context context = sSystemRegistry.contextParameters.context;
     69                result = new Sound();
     70                result.resource = resource;
     71                result.soundId = mSoundPool.load(context, resource, 1);
     72                mSounds.add(result);
     73                mSounds.sort(false);
     74            }
     75         } else {
     76             result = mSounds.get(index);
     77         }
     78 
     79         return result;
     80     }
     81 
     82     synchronized public final int play(Sound sound, boolean loop, int priority) {
     83     	int stream = -1;
     84     	if (mSoundEnabled) {
     85     		stream = mSoundPool.play(sound.soundId, 1.0f, 1.0f, priority, loop ? -1 : 0, 1.0f);
     86     		if (loop) {
     87     			addLoopingStream(stream);
     88     		}
     89     	}
     90 
     91     	return stream;
     92     }
     93 
     94     synchronized public final int play(Sound sound, boolean loop, int priority, float volume, float rate) {
     95     	int stream = -1;
     96     	if (mSoundEnabled) {
     97     		stream = mSoundPool.play(sound.soundId, volume, volume, priority, loop ? -1 : 0, rate);
     98     		if (loop) {
     99     			addLoopingStream(stream);
    100     		}
    101     	}
    102 
    103     	return stream;
    104     }
    105 
    106     public final void stop(int stream) {
    107         mSoundPool.stop(stream);
    108         removeLoopingStream(stream);
    109     }
    110 
    111     public final void pause(int stream) {
    112         mSoundPool.pause(stream);
    113     }
    114 
    115     public final void resume(int stream) {
    116        mSoundPool.resume(stream);
    117     }
    118 
    119     public final void stopAll() {
    120     	final int count = mLoopingStreams.length;
    121     	for (int x = count - 1; x >= 0; x--) {
    122     		if (mLoopingStreams[x] >= 0) {
    123     			stop(mLoopingStreams[x]);
    124     		}
    125     	}
    126     }
    127 
    128     // HACK: There's no way to pause an entire sound pool, but if we
    129     // don't do something when our parent activity is paused, looping
    130     // sounds will continue to play.  Rather that reproduce all the bookkeeping
    131     // that SoundPool does internally here, I've opted to just pause looping
    132     // sounds when the Activity is paused.
    133     public void pauseAll() {
    134     	final int count = mLoopingStreams.length;
    135     	for (int x = 0; x < count; x++) {
    136     		if (mLoopingStreams[x] >= 0) {
    137     			pause(mLoopingStreams[x]);
    138     		}
    139     	}
    140     }
    141 
    142     private void addLoopingStream(int stream) {
    143     	final int count = mLoopingStreams.length;
    144     	for (int x = 0; x < count; x++) {
    145     		if (mLoopingStreams[x] < 0) {
    146     			mLoopingStreams[x] = stream;
    147     			break;
    148     		}
    149     	}
    150     }
    151 
    152     private void removeLoopingStream(int stream) {
    153     	final int count = mLoopingStreams.length;
    154     	for (int x = 0; x < count; x++) {
    155     		if (mLoopingStreams[x] == stream) {
    156     			mLoopingStreams[x] = -1;
    157     			break;
    158     		}
    159     	}
    160     }
    161 
    162     private final int findSound(int resource) {
    163         mSearchDummy.resource = resource;
    164         return mSounds.find(mSearchDummy, false);
    165     }
    166 
    167 	synchronized public final void setSoundEnabled(boolean soundEnabled) {
    168 		mSoundEnabled = soundEnabled;
    169 	}
    170 
    171 	public final boolean getSoundEnabled() {
    172 		return mSoundEnabled;
    173 	}
    174 
    175     public class Sound extends AllocationGuard {
    176         public int resource;
    177         public int soundId;
    178     }
    179 
    180     /** Comparator for sounds. */
    181     private final static class SoundComparator implements Comparator<Sound> {
    182         public int compare(final Sound object1, final Sound object2) {
    183             int result = 0;
    184             if (object1 == null && object2 != null) {
    185                 result = 1;
    186             } else if (object1 != null && object2 == null) {
    187                 result = -1;
    188             } else if (object1 != null && object2 != null) {
    189                 result = object1.resource - object2.resource;
    190             }
    191             return result;
    192         }
    193     }
    194 
    195 
    196 }
    197