19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.media; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.ref.WeakReference; 22e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 231af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlockimport android.app.ActivityThread; 241af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlockimport android.app.AppOpsManager; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.AssetFileDescriptor; 27f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparksimport android.os.Handler; 281af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlockimport android.os.IBinder; 29f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparksimport android.os.Looper; 30f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparksimport android.os.Message; 31e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrillimport android.os.ParcelFileDescriptor; 321af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlockimport android.os.Process; 331af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlockimport android.os.RemoteException; 341af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlockimport android.os.ServiceManager; 35e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrillimport android.os.SystemProperties; 36e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrillimport android.util.AndroidRuntimeException; 37e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrillimport android.util.Log; 38e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 391af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlockimport com.android.internal.app.IAppOpsService; 401af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock 41f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks 42cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks/** 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The SoundPool class manages and plays audio resources for applications. 44cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 45cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * <p>A SoundPool is a collection of samples that can be loaded into memory 46cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * from a resource inside the APK or from a file in the file system. The 47cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * SoundPool library uses the MediaPlayer service to decode the audio 48cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * into a raw 16-bit PCM mono or stereo stream. This allows applications 49cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * to ship with compressed streams without having to suffer the CPU load 50cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * and latency of decompressing during playback.</p> 51cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 52cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * <p>In addition to low-latency playback, SoundPool can also manage the number 53cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * of audio streams being rendered at once. When the SoundPool object is 54cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * constructed, the maxStreams parameter sets the maximum number of streams 55cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * that can be played at a time from this single SoundPool. SoundPool tracks 56cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * the number of active streams. If the maximum number of streams is exceeded, 57cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * SoundPool will automatically stop a previously playing stream based first 58cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * on priority and then by age within that priority. Limiting the maximum 59cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * number of streams helps to cap CPU loading and reducing the likelihood that 60cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * audio mixing will impact visuals or UI performance.</p> 61cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 626cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * <p>Sounds can be looped by setting a non-zero loop value. A value of -1 636cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * causes the sound to loop forever. In this case, the application must 646cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * explicitly call the stop() function to stop the sound. Any other non-zero 656cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * value will cause the sound to repeat the specified number of times, e.g. 666cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * a value of 3 causes the sound to play a total of 4 times.</p> 676cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * 686cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * <p>The playback rate can also be changed. A playback rate of 1.0 causes 696cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * the sound to play at its original frequency (resampled, if necessary, 706cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * to the hardware output frequency). A playback rate of 2.0 causes the 716cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * sound to play at twice its original frequency, and a playback rate of 726cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * 0.5 causes it to play at half its original frequency. The playback 736cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * rate range is 0.5 to 2.0.</p> 746cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * 75cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * <p>Priority runs low to high, i.e. higher numbers are higher priority. 76cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * Priority is used when a call to play() would cause the number of active 77cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * streams to exceed the value established by the maxStreams parameter when 78cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * the SoundPool was created. In this case, the stream allocator will stop 79cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * the lowest priority stream. If there are multiple streams with the same 80cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * low priority, it will choose the oldest stream to stop. In the case 81cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * where the priority of the new stream is lower than all the active 82cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * streams, the new sound will not play and the play() function will return 83cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * a streamID of zero.</p> 84cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 85cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * <p>Let's examine a typical use case: A game consists of several levels of 86cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * play. For each level, there is a set of unique sounds that are used only 87cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * by that level. In this case, the game logic should create a new SoundPool 88cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * object when the first level is loaded. The level data itself might contain 89cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * the list of sounds to be used by this level. The loading logic iterates 90cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * through the list of sounds calling the appropriate SoundPool.load() 91cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * function. This should typically be done early in the process to allow time 92cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * for decompressing the audio to raw PCM format before they are needed for 93cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * playback.</p> 94cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 95cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * <p>Once the sounds are loaded and play has started, the application can 96cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * trigger sounds by calling SoundPool.play(). Playing streams can be 97cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * paused or resumed, and the application can also alter the pitch by 98cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * adjusting the playback rate in real-time for doppler or synthesis 99cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * effects.</p> 100cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 1016cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * <p>Note that since streams can be stopped due to resource constraints, the 1026cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * streamID is a reference to a particular instance of a stream. If the stream 1036cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * is stopped to allow a higher priority stream to play, the stream is no 1046cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * longer be valid. However, the application is allowed to call methods on 1056cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * the streamID without error. This may help simplify program logic since 1066cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * the application need not concern itself with the stream lifecycle.</p> 1076cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * 108cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * <p>In our example, when the player has completed the level, the game 109cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * logic should call SoundPool.release() to release all the native resources 110cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * in use and then set the SoundPool reference to null. If the player starts 111cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * another level, a new SoundPool is created, sounds are loaded, and play 112cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * resumes.</p> 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 114e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrillpublic class SoundPool { 115e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private final SoundPoolDelegate mImpl; 116f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks 117cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 118cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * Constructor. Constructs a SoundPool object with the following 119cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * characteristics: 120cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 121cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param maxStreams the maximum number of simultaneous streams for this 122cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * SoundPool object 123cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param streamType the audio stream type as described in AudioManager 124cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * For example, game applications will normally use 125cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * {@link AudioManager#STREAM_MUSIC}. 126cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param srcQuality the sample-rate converter quality. Currently has no 127cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * effect. Use 0 for the default. 128cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @return a SoundPool object, or null if creation failed 129fb52139bd81e8ac53ec923b005f10c5cb7d80e0cJean-Michel Trivi * @deprecated use {@link SoundPool.Builder} instead to create and configure a 130fb52139bd81e8ac53ec923b005f10c5cb7d80e0cJean-Michel Trivi * SoundPool instance 131cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public SoundPool(int maxStreams, int streamType, int srcQuality) { 13355a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi this(maxStreams, 13455a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build()); 13555a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi } 13655a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi 13755a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi private SoundPool(int maxStreams, AudioAttributes attributes) { 138e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if (SystemProperties.getBoolean("config.disable_media", false)) { 139e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl = new SoundPoolStub(); 140e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } else { 14155a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi mImpl = new SoundPoolImpl(this, maxStreams, attributes); 14255a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi } 14355a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi } 14455a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi 14555a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi /** 14655a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi * Builder class for {@link SoundPool} objects. 14755a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi */ 14855a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi public static class Builder { 14955a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi private int mMaxStreams = 1; 15055a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi private AudioAttributes mAudioAttributes; 15155a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi 15255a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi /** 15355a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi * Constructs a new Builder with the defaults format values. 1542d17128f6e9954a818a71513ad6da4180e95356bJean-Michel Trivi * If not provided, the maximum number of streams is 1 (see {@link #setMaxStreams(int)} to 1552d17128f6e9954a818a71513ad6da4180e95356bJean-Michel Trivi * change it), and the audio attributes have a usage value of 1562d17128f6e9954a818a71513ad6da4180e95356bJean-Michel Trivi * {@link AudioAttributes#USAGE_MEDIA} (see {@link #setAudioAttributes(AudioAttributes)} to 1572d17128f6e9954a818a71513ad6da4180e95356bJean-Michel Trivi * change them). 15855a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi */ 15955a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi public Builder() { 16055a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi } 16155a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi 16255a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi /** 16355a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi * Sets the maximum of number of simultaneous streams that can be played simultaneously. 16455a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi * @param maxStreams a value equal to 1 or greater. 16555a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi * @return the same Builder instance 16655a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi * @throws IllegalArgumentException 16755a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi */ 16855a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi public Builder setMaxStreams(int maxStreams) throws IllegalArgumentException { 16955a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi if (maxStreams <= 0) { 17055a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi throw new IllegalArgumentException( 171fb52139bd81e8ac53ec923b005f10c5cb7d80e0cJean-Michel Trivi "Strictly positive value required for the maximum number of streams"); 17255a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi } 17355a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi mMaxStreams = maxStreams; 17455a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi return this; 17555a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi } 17655a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi 17755a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi /** 17855a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi * Sets the {@link AudioAttributes}. For examples, game applications will use attributes 17955a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi * built with usage information set to {@link AudioAttributes#USAGE_GAME}. 18055a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi * @param attributes a non-null 18155a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi * @return 18255a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi */ 18355a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi public Builder setAudioAttributes(AudioAttributes attributes) 18455a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi throws IllegalArgumentException { 18555a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi if (attributes == null) { 18655a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi throw new IllegalArgumentException("Invalid null AudioAttributes"); 18755a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi } 18855a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi mAudioAttributes = attributes; 18955a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi return this; 19055a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi } 19155a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi 19255a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi public SoundPool build() { 19355a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi if (mAudioAttributes == null) { 19455a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi mAudioAttributes = new AudioAttributes.Builder() 19555a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi .setUsage(AudioAttributes.USAGE_MEDIA).build(); 19655a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi } 19755a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi return new SoundPool(mMaxStreams, mAudioAttributes); 198f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 201cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 2026cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Load the sound from the specified path. 2036cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * 204cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param path the path to the audio file 2056cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param priority the priority of the sound. Currently has no effect. Use 2066cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * a value of 1 for future compatibility. 207cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @return a sound ID. This value can be used to play or unload the sound. 208cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 209e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(String path, int priority) { 210e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return mImpl.load(path, priority); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 213cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 2146cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Load the sound from the specified APK resource. 215cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 2166cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Note that the extension is dropped. For example, if you want to load 217cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * a sound from the raw resource file "explosion.mp3", you would specify 218cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * "R.raw.explosion" as the resource ID. Note that this means you cannot 219cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * have both an "explosion.wav" and an "explosion.mp3" in the res/raw 2206cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * directory. 221cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 222cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param context the application context 223cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param resId the resource ID 2246cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param priority the priority of the sound. Currently has no effect. Use 2256cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * a value of 1 for future compatibility. 226cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @return a sound ID. This value can be used to play or unload the sound. 227cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int load(Context context, int resId, int priority) { 229e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return mImpl.load(context, resId, priority); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 232cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 2336cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Load the sound from an asset file descriptor. 234cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 235cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param afd an asset file descriptor 2366cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param priority the priority of the sound. Currently has no effect. Use 2376cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * a value of 1 for future compatibility. 238cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @return a sound ID. This value can be used to play or unload the sound. 239cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int load(AssetFileDescriptor afd, int priority) { 241e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return mImpl.load(afd, priority); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 244cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 2456cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Load the sound from a FileDescriptor. 246cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 2476cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * This version is useful if you store multiple sounds in a single 248cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * binary. The offset specifies the offset from the start of the file 2496cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * and the length specifies the length of the sound within the file. 250cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 251cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param fd a FileDescriptor object 252cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param offset offset to the start of the sound 253cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param length length of the sound 2546cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param priority the priority of the sound. Currently has no effect. Use 2556cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * a value of 1 for future compatibility. 256cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @return a sound ID. This value can be used to play or unload the sound. 257cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int load(FileDescriptor fd, long offset, long length, int priority) { 259e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return mImpl.load(fd, offset, length, priority); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 262cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 2636cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Unload a sound from a sound ID. 264cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 2656cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Unloads the sound specified by the soundID. This is the value 266cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * returned by the load() function. Returns true if the sound is 2676cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * successfully unloaded, false if the sound was already unloaded. 268cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 269cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param soundID a soundID returned by the load() function 270cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @return true if just unloaded, false if previously unloaded 271cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 272e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final boolean unload(int soundID) { 273e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return mImpl.unload(soundID); 274e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 276cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 2776cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Play a sound from a sound ID. 278cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 2796cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Play the sound specified by the soundID. This is the value 280cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * returned by the load() function. Returns a non-zero streamID 281cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * if successful, zero if it fails. The streamID can be used to 282cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * further control playback. Note that calling play() may cause 283cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * another sound to stop playing if the maximum number of active 2846cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * streams is exceeded. A loop value of -1 means loop forever, 2856cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * a value of 0 means don't loop, other values indicate the 2866cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * number of repeats, e.g. a value of 1 plays the audio twice. 2876cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * The playback rate allows the application to vary the playback 2886cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * rate (pitch) of the sound. A value of 1.0 means play back at 2896cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * the original frequency. A value of 2.0 means play back twice 2906cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * as fast, and a value of 0.5 means playback at half speed. 291cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 292cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param soundID a soundID returned by the load() function 2936cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param leftVolume left volume value (range = 0.0 to 1.0) 2946cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param rightVolume right volume value (range = 0.0 to 1.0) 2956cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param priority stream priority (0 = lowest priority) 2966cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param loop loop mode (0 = no loop, -1 = loop forever) 2976cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param rate playback rate (1.0 = normal playback, range 0.5 to 2.0) 298cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @return non-zero streamID if successful, zero if failed 299cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 300e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final int play(int soundID, float leftVolume, float rightVolume, 301e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill int priority, int loop, float rate) { 302e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return mImpl.play( 303e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill soundID, leftVolume, rightVolume, priority, loop, rate); 304e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 306cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 3076cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Pause a playback stream. 308cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 3096cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Pause the stream specified by the streamID. This is the 310cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * value returned by the play() function. If the stream is 311cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * playing, it will be paused. If the stream is not playing 312cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * (e.g. is stopped or was previously paused), calling this 3136cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * function will have no effect. 314cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 315cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param streamID a streamID returned by the play() function 316cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 317e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void pause(int streamID) { 318e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl.pause(streamID); 319e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 321cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 3226cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Resume a playback stream. 323cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 3246cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Resume the stream specified by the streamID. This 325cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * is the value returned by the play() function. If the stream 326cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * is paused, this will resume playback. If the stream was not 3276cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * previously paused, calling this function will have no effect. 328cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 329cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param streamID a streamID returned by the play() function 330cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 331e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void resume(int streamID) { 332e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl.resume(streamID); 333e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 335cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 336f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks * Pause all active streams. 337f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks * 338f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks * Pause all streams that are currently playing. This function 339f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks * iterates through all the active streams and pauses any that 340f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks * are playing. It also sets a flag so that any streams that 341f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks * are playing can be resumed by calling autoResume(). 342f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks */ 343e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void autoPause() { 344e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl.autoPause(); 345e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 346f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks 347f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks /** 348f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks * Resume all previously active streams. 349f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks * 350f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks * Automatically resumes all streams that were paused in previous 351f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks * calls to autoPause(). 352f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks */ 353e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void autoResume() { 354e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl.autoResume(); 355e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 356f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks 357f992cbb9aae593c7787ac9c5f6b475e7bb0a92c5Dave Sparks /** 3586cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Stop a playback stream. 359cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 3606cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Stop the stream specified by the streamID. This 361cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * is the value returned by the play() function. If the stream 362cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * is playing, it will be stopped. It also releases any native 363cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * resources associated with this stream. If the stream is not 3646cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * playing, it will have no effect. 365cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 366cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param streamID a streamID returned by the play() function 367cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 368e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void stop(int streamID) { 369e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl.stop(streamID); 370e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 372cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 3736cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Set stream volume. 374cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 3756cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Sets the volume on the stream specified by the streamID. 376cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * This is the value returned by the play() function. The 377cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * value must be in the range of 0.0 to 1.0. If the stream does 3786cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * not exist, it will have no effect. 379cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 380cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param streamID a streamID returned by the play() function 381cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param leftVolume left volume value (range = 0.0 to 1.0) 382cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param rightVolume right volume value (range = 0.0 to 1.0) 383cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 384e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void setVolume(int streamID, 385e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill float leftVolume, float rightVolume) { 386e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl.setVolume(streamID, leftVolume, rightVolume); 387e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 390068225de0197df07a0247b2877666ea91c22c992Glenn Kasten * Similar, except set volume of all channels to same value. 391068225de0197df07a0247b2877666ea91c22c992Glenn Kasten * @hide 392068225de0197df07a0247b2877666ea91c22c992Glenn Kasten */ 393068225de0197df07a0247b2877666ea91c22c992Glenn Kasten public void setVolume(int streamID, float volume) { 394068225de0197df07a0247b2877666ea91c22c992Glenn Kasten setVolume(streamID, volume, volume); 395068225de0197df07a0247b2877666ea91c22c992Glenn Kasten } 396068225de0197df07a0247b2877666ea91c22c992Glenn Kasten 397068225de0197df07a0247b2877666ea91c22c992Glenn Kasten /** 3986cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Change stream priority. 399cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 4006cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Change the priority of the stream specified by the streamID. 401cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * This is the value returned by the play() function. Affects the 4026cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * order in which streams are re-used to play new sounds. If the 4036cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * stream does not exist, it will have no effect. 404cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 405cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param streamID a streamID returned by the play() function 406cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 407e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void setPriority(int streamID, int priority) { 408e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl.setPriority(streamID, priority); 409e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 411cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks /** 4126cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Set loop mode. 413cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 4146cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Change the loop mode. A loop value of -1 means loop forever, 4156cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * a value of 0 means don't loop, other values indicate the 4166cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * number of repeats, e.g. a value of 1 plays the audio twice. 4176cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * If the stream does not exist, it will have no effect. 418cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * 419cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks * @param streamID a streamID returned by the play() function 4206cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param loop loop mode (0 = no loop, -1 = loop forever) 421cef302d0950a02fdc6920475d0c357d3949e85c3Dave Sparks */ 422e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void setLoop(int streamID, int loop) { 423e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl.setLoop(streamID, loop); 424e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4266cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks /** 4276cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * Change playback rate. 4286cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * 4296cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * The playback rate allows the application to vary the playback 4306cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * rate (pitch) of the sound. A value of 1.0 means playback at 4316cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * the original frequency. A value of 2.0 means playback twice 4326cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * as fast, and a value of 0.5 means playback at half speed. 4336cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * If the stream does not exist, it will have no effect. 4346cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * 4356cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param streamID a streamID returned by the play() function 4366cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks * @param rate playback rate (1.0 = normal playback, range 0.5 to 2.0) 4376cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks */ 438e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void setRate(int streamID, float rate) { 439e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl.setRate(streamID, rate); 440e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 442e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public interface OnLoadCompleteListener { 443f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks /** 444f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks * Called when a sound has completed loading. 445f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks * 446f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks * @param soundPool SoundPool object from the load() method 44736b692d8ef595eee1e28d20b740be548365a5671David Friedman * @param sampleId the sample ID of the sound loaded. 448f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks * @param status the status of the load operation (0 = success) 449f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks */ 450f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks public void onLoadComplete(SoundPool soundPool, int sampleId, int status); 451f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks } 452f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks 453f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks /** 454f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks * Sets the callback hook for the OnLoadCompleteListener. 455f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks */ 456e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void setOnLoadCompleteListener(OnLoadCompleteListener listener) { 457e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl.setOnLoadCompleteListener(listener); 458e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 459e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 460e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill /** 461e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * Release the SoundPool resources. 462e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * 463e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * Release all memory and native resources used by the SoundPool 464e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * object. The SoundPool can no longer be used and the reference 465e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * should be set to null. 466e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill */ 467e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void release() { 468e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mImpl.release(); 469e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 470e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 471e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill /** 472e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * Interface for SoundPool implementations. 473e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * SoundPool is statically referenced and unconditionally called from all 474e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * over the framework, so we can't simply omit the class or make it throw 475e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * runtime exceptions, as doing so would break the framework. Instead we 476e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * now select either a real or no-op impl object based on whether media is 477e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * enabled. 478e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * 479e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * @hide 480e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill */ 481e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill /* package */ interface SoundPoolDelegate { 482e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(String path, int priority); 483e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(Context context, int resId, int priority); 484e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(AssetFileDescriptor afd, int priority); 485e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load( 486e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill FileDescriptor fd, long offset, long length, int priority); 487e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public boolean unload(int soundID); 488e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int play( 489e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill int soundID, float leftVolume, float rightVolume, 490e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill int priority, int loop, float rate); 491e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void pause(int streamID); 492e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void resume(int streamID); 493e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void autoPause(); 494e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void autoResume(); 495e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void stop(int streamID); 496e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void setVolume(int streamID, float leftVolume, float rightVolume); 497e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void setVolume(int streamID, float volume); 498e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void setPriority(int streamID, int priority); 499e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void setLoop(int streamID, int loop); 500e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void setRate(int streamID, float rate); 501e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void setOnLoadCompleteListener(OnLoadCompleteListener listener); 502e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void release(); 503e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 504e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 505e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 506e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill /** 507e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * Real implementation of the delegate interface. This was formerly the 508e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * body of SoundPool itself. 509e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill */ 510e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill /* package */ static class SoundPoolImpl implements SoundPoolDelegate { 511e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill static { System.loadLibrary("soundpool"); } 512e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 513e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private final static String TAG = "SoundPool"; 514e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private final static boolean DEBUG = false; 515e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 516075e9a19ce645752f8282bc19c91b25978a7dc52Ashok Bhat private long mNativeContext; // accessed by native methods 517e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 518e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private EventHandler mEventHandler; 519e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private SoundPool.OnLoadCompleteListener mOnLoadCompleteListener; 520e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private SoundPool mProxy; 521e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 522e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private final Object mLock; 52355a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi private final AudioAttributes mAttributes; 5241af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock private final IAppOpsService mAppOps; 525e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 526e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill // SoundPool messages 527e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill // 528e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill // must match SoundPool.h 529e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private static final int SAMPLE_LOADED = 1; 530e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 53155a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi public SoundPoolImpl(SoundPool proxy, int maxStreams, AudioAttributes attr) { 532e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 533e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill // do native setup 53455a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi if (native_setup(new WeakReference(this), maxStreams, attr) != 0) { 535e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill throw new RuntimeException("Native setup failed"); 536e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 537e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mLock = new Object(); 538e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mProxy = proxy; 53955a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi mAttributes = attr; 5401af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE); 5411af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock mAppOps = IAppOpsService.Stub.asInterface(b); 542e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 543e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 544e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(String path, int priority) 545e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill { 546e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill // pass network streams to player 547e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if (path.startsWith("http:")) 548e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return _load(path, priority); 549e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 550e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill // try local path 551e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill int id = 0; 552e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill try { 553e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill File f = new File(path); 554e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill ParcelFileDescriptor fd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY); 555e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if (fd != null) { 556e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill id = _load(fd.getFileDescriptor(), 0, f.length(), priority); 557e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill fd.close(); 558a60e212d0dda7d2a748180ce77405f2463c9cf53Eric Laurent } 559e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } catch (java.io.IOException e) { 560e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill Log.e(TAG, "error loading " + path); 561e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 562e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return id; 563e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 564e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 565e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(Context context, int resId, int priority) { 566e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId); 567e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill int id = 0; 568e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if (afd != null) { 569e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill id = _load(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(), priority); 570e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill try { 571e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill afd.close(); 572e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } catch (java.io.IOException ex) { 573e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill //Log.d(TAG, "close failed:", ex); 574e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 575e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 576e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return id; 577e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 578e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 579e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(AssetFileDescriptor afd, int priority) { 580e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if (afd != null) { 581e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill long len = afd.getLength(); 582e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if (len < 0) { 583e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill throw new AndroidRuntimeException("no length for fd"); 584e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 585e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return _load(afd.getFileDescriptor(), afd.getStartOffset(), len, priority); 586a60e212d0dda7d2a748180ce77405f2463c9cf53Eric Laurent } else { 587e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return 0; 588a60e212d0dda7d2a748180ce77405f2463c9cf53Eric Laurent } 589f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks } 590f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks 591e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(FileDescriptor fd, long offset, long length, int priority) { 592e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return _load(fd, offset, length, priority); 593e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 594e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 595e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private native final int _load(String uri, int priority); 596e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 597e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private native final int _load(FileDescriptor fd, long offset, long length, int priority); 598e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 599e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public native final boolean unload(int soundID); 600e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 6011af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock public final int play(int soundID, float leftVolume, float rightVolume, 6021af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock int priority, int loop, float rate) { 6031af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock if (isRestricted()) { 6041af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock leftVolume = rightVolume = 0; 6051af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 6061af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock return _play(soundID, leftVolume, rightVolume, priority, loop, rate); 6071af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 6081af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock 6091af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock public native final int _play(int soundID, float leftVolume, float rightVolume, 610e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill int priority, int loop, float rate); 611e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 6121af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock private boolean isRestricted() { 6131af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock try { 6141af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, 61555a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi mAttributes.getUsage(), 61655a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi Process.myUid(), ActivityThread.currentPackageName()); 6171af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock return mode != AppOpsManager.MODE_ALLOWED; 6181af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } catch (RemoteException e) { 6191af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock return false; 6201af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 6211af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 6221af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock 623e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public native final void pause(int streamID); 624e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 625e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public native final void resume(int streamID); 626e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 627e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public native final void autoPause(); 628e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 629e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public native final void autoResume(); 630e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 631e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public native final void stop(int streamID); 632f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks 6331af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock public final void setVolume(int streamID, float leftVolume, float rightVolume) { 6341af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock if (isRestricted()) { 6351af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock return; 6361af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 6371af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock _setVolume(streamID, leftVolume, rightVolume); 6381af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock } 6391af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock 6401af30c7ac480e5d335f267a3ac3b2e6c748ce240John Spurlock private native final void _setVolume(int streamID, float leftVolume, float rightVolume); 641e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 642e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void setVolume(int streamID, float volume) { 643e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill setVolume(streamID, volume, volume); 644f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks } 645f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks 646e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public native final void setPriority(int streamID, int priority); 647e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 648e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public native final void setLoop(int streamID, int loop); 649e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 650e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public native final void setRate(int streamID, float rate); 651e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 652e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener) 653e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill { 654e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill synchronized(mLock) { 655e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if (listener != null) { 656e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill // setup message handler 657e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill Looper looper; 658e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if ((looper = Looper.myLooper()) != null) { 659e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mEventHandler = new EventHandler(mProxy, looper); 660e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } else if ((looper = Looper.getMainLooper()) != null) { 661e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mEventHandler = new EventHandler(mProxy, looper); 662e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } else { 663e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mEventHandler = null; 664f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks } 665e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } else { 666e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mEventHandler = null; 667f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks } 668e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mOnLoadCompleteListener = listener; 669f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks } 670f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks } 671f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks 672e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private class EventHandler extends Handler 673e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill { 674e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private SoundPool mSoundPool; 675e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 676e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public EventHandler(SoundPool soundPool, Looper looper) { 677e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill super(looper); 678e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mSoundPool = soundPool; 679e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 680f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks 681e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill @Override 682e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void handleMessage(Message msg) { 683e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill switch(msg.what) { 684e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill case SAMPLE_LOADED: 685e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if (DEBUG) Log.d(TAG, "Sample " + msg.arg1 + " loaded"); 686e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill synchronized(mLock) { 687e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if (mOnLoadCompleteListener != null) { 688e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill mOnLoadCompleteListener.onLoadComplete(mSoundPool, msg.arg1, msg.arg2); 689e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 690e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 691e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill break; 692e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill default: 693e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill Log.e(TAG, "Unknown message type " + msg.what); 694e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return; 695e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 696e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 697f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks } 698e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 699e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill // post event from native code to message handler 700e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill private static void postEventFromNative(Object weakRef, int msg, int arg1, int arg2, Object obj) 701e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill { 702e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill SoundPoolImpl soundPoolImpl = (SoundPoolImpl)((WeakReference)weakRef).get(); 703e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if (soundPoolImpl == null) 704e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return; 705e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 706e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill if (soundPoolImpl.mEventHandler != null) { 707e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill Message m = soundPoolImpl.mEventHandler.obtainMessage(msg, arg1, arg2, obj); 708e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill soundPoolImpl.mEventHandler.sendMessage(m); 709e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 710e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 711e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 712e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public native final void release(); 713e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 71455a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi private native final int native_setup(Object weakRef, int maxStreams, 71555a30c41b6c47d3afe6b13c25c64e8eec9f45e7cJean-Michel Trivi Object/*AudioAttributes*/ attributes); 716e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 717e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill protected void finalize() { release(); } 718f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks } 719f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks 720f6e43bf29084760b39257b2273e0f04c2815fdc5Dave Sparks /** 721e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * No-op implementation of SoundPool. 722e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * Used when media is disabled by the system. 723e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill * @hide 7246cb9900e6f884adb6c9aa0243f2bf88985f671f8Dave Sparks */ 725e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill /* package */ static class SoundPoolStub implements SoundPoolDelegate { 726e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public SoundPoolStub() { } 727e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 728e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(String path, int priority) { 729e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return 0; 730e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 731e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 732e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(Context context, int resId, int priority) { 733e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return 0; 734e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 735e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 736e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(AssetFileDescriptor afd, int priority) { 737e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return 0; 738e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 739e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 740e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public int load(FileDescriptor fd, long offset, long length, int priority) { 741e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return 0; 742e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 743e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 744e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final boolean unload(int soundID) { 745e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return true; 746e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 747e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 748e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final int play(int soundID, float leftVolume, float rightVolume, 749e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill int priority, int loop, float rate) { 750e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill return 0; 751e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 752e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 753e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void pause(int streamID) { } 754e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 755e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void resume(int streamID) { } 756e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 757e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void autoPause() { } 758e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 759e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void autoResume() { } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 761e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void stop(int streamID) { } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 763e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void setVolume(int streamID, 764e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill float leftVolume, float rightVolume) { } 765e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 766e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void setVolume(int streamID, float volume) { 767e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 768e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 769e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void setPriority(int streamID, int priority) { } 770e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 771e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void setLoop(int streamID, int loop) { } 772e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 773e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void setRate(int streamID, float rate) { } 774e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 775e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener) { 776e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 777e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill 778e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill public final void release() { } 779e4d9a01bfc7451afff1ed399a5801c7aa2af2831Dan Morrill } 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 781