1 /* 2 * Copyright (C) 2011 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.res.AssetFileDescriptor; 20 import android.media.AudioManager; 21 import android.media.MediaPlayer; 22 import android.util.Log; 23 24 import java.io.IOException; 25 26 /** 27 * Plays an AssetFileDescriptor, but does all the hard work on another thread so 28 * that any slowness with preparing or loading doesn't block the calling thread. 29 */ 30 public class SoundPlayer implements Runnable { 31 private static final String TAG = "SoundPlayer"; 32 private Thread mThread; 33 private MediaPlayer mPlayer; 34 private int mPlayCount = 0; 35 private boolean mExit; 36 private AssetFileDescriptor mAfd; 37 private int mAudioStreamType; 38 39 @Override run()40 public void run() { 41 while(true) { 42 try { 43 if (mPlayer == null) { 44 MediaPlayer player = new MediaPlayer(); 45 player.setAudioStreamType(mAudioStreamType); 46 player.setDataSource(mAfd.getFileDescriptor(), mAfd.getStartOffset(), 47 mAfd.getLength()); 48 player.setLooping(false); 49 player.prepare(); 50 mPlayer = player; 51 mAfd.close(); 52 mAfd = null; 53 } 54 synchronized (this) { 55 while(true) { 56 if (mExit) { 57 return; 58 } else if (mPlayCount <= 0) { 59 wait(); 60 } else { 61 mPlayCount--; 62 break; 63 } 64 } 65 } 66 mPlayer.start(); 67 } catch (Exception e) { 68 Log.e(TAG, "Error playing sound", e); 69 } 70 } 71 } 72 SoundPlayer(AssetFileDescriptor afd)73 public SoundPlayer(AssetFileDescriptor afd) { 74 mAfd = afd; 75 mAudioStreamType = AudioManager.STREAM_MUSIC; 76 } 77 SoundPlayer(AssetFileDescriptor afd, boolean enforceAudible)78 public SoundPlayer(AssetFileDescriptor afd, boolean enforceAudible) { 79 mAfd = afd; 80 if (enforceAudible) { 81 mAudioStreamType = 7; // AudioManager.STREAM_SYSTEM_ENFORCED; currently hidden API. 82 } else { 83 mAudioStreamType = AudioManager.STREAM_MUSIC; 84 } 85 } 86 play()87 public void play() { 88 if (mThread == null) { 89 mThread = new Thread(this); 90 mThread.start(); 91 } 92 synchronized (this) { 93 mPlayCount++; 94 notifyAll(); 95 } 96 } 97 release()98 public void release() { 99 if (mThread != null) { 100 synchronized (this) { 101 mExit = true; 102 notifyAll(); 103 } 104 try { 105 mThread.join(); 106 } catch (InterruptedException e) { 107 } 108 mThread = null; 109 } 110 if (mAfd != null) { 111 try { 112 mAfd.close(); 113 } catch(IOException e) { 114 } 115 mAfd = null; 116 } 117 if (mPlayer != null) { 118 mPlayer.release(); 119 mPlayer = null; 120 } 121 } 122 } 123