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