Home | History | Annotate | Download | only in camera
      1 /*
      2  * Copyright (C) 2014 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.android.camera;
     18 
     19 import android.content.Context;
     20 import android.media.AudioManager;
     21 import android.media.SoundPool;
     22 import android.util.SparseIntArray;
     23 
     24 import com.android.camera.util.ApiHelper;
     25 
     26 /**
     27  * Loads a plays custom sounds. For playing system-standard sounds for various
     28  * camera actions, please refer to {@link SoundClips}.
     29  */
     30 public class SoundPlayer {
     31     private final Context mAppContext;
     32     private final SoundPool mSoundPool;
     33     /** Keeps a mapping from sound resource ID to sound ID */
     34     private final SparseIntArray mResourceToSoundId = new SparseIntArray();
     35     private boolean mIsReleased = false;
     36 
     37     /**
     38      * Construct a new sound player.
     39      */
     40     public SoundPlayer(Context appContext) {
     41         mAppContext = appContext;
     42         final int audioType = getAudioTypeForSoundPool();
     43         mSoundPool = new SoundPool(1 /* max streams */, audioType, 0 /* quality */);
     44     }
     45 
     46     /**
     47      * Load the sound from a resource.
     48      */
     49     public void loadSound(int resourceId) {
     50         int soundId = mSoundPool.load(mAppContext, resourceId, 1/* priority */);
     51         mResourceToSoundId.put(resourceId, soundId);
     52     }
     53 
     54     /**
     55      * Play the sound with the given resource. The resource has to be loaded
     56      * before it can be played, otherwise an exception will be thrown.
     57      */
     58     public void play(int resourceId, float volume) {
     59         Integer soundId = mResourceToSoundId.get(resourceId);
     60         if (soundId == null) {
     61             throw new IllegalStateException("Sound not loaded. Must call #loadSound first.");
     62         }
     63         mSoundPool.play(soundId, volume, volume, 0 /* priority */, 0 /* loop */, 1 /* rate */);
     64     }
     65 
     66     /**
     67      * Unload the given sound if it's not needed anymore to release memory.
     68      */
     69     public void unloadSound(int resourceId) {
     70         Integer soundId = mResourceToSoundId.get(resourceId);
     71         if (soundId == null) {
     72             throw new IllegalStateException("Sound not loaded. Must call #loadSound first.");
     73         }
     74         mSoundPool.unload(soundId);
     75     }
     76 
     77     /**
     78      * Call this if you don't need the SoundPlayer anymore. All memory will be
     79      * released and the object cannot be re-used.
     80      */
     81     public void release() {
     82         mIsReleased = true;
     83         mSoundPool.release();
     84     }
     85 
     86     public boolean isReleased() {
     87         return mIsReleased;
     88     }
     89 
     90     private static int getAudioTypeForSoundPool() {
     91         // STREAM_SYSTEM_ENFORCED is hidden API.
     92         return ApiHelper.getIntFieldIfExists(AudioManager.class,
     93                 "STREAM_SYSTEM_ENFORCED", null, AudioManager.STREAM_RING);
     94     }
     95 }
     96