AudioTrack.java revision 619346f902241736d933657a4fe10f10c50a1ba8
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 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.lang.ref.WeakReference; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.IllegalArgumentException; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.IllegalStateException; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.media.AudioManager; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The AudioTrack class manages and plays a single audio resource for Java applications. 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * It allows to stream PCM audio buffers to the audio hardware for playback. This is 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * achieved by "pushing" the data to the AudioTrack object using one of the 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #write(byte[], int, int)} and {@link #write(short[], int, int)} methods. 35ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * 36ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * <p>An AudioTrack instance can operate under two modes: static or streaming.<br> 37ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * In Streaming mode, the application writes a continuous stream of data to the AudioTrack, using 38ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * one of the write() methods. These are blocking and return when the data has been transferred 39ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * from the Java layer to the native layer and queued for playback. The streaming mode 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is most useful when playing blocks of audio data that for instance are: 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>too big to fit in memory because of the duration of the sound to play,</li> 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>too big to fit in memory because of the characteristics of the audio data 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (high sampling rate, bits per sample ...)</li> 45ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * <li>received or generated while previously queued audio is playing.</li> 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The static mode is to be chosen when dealing with short sounds that fit in memory and 48ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * that need to be played with the smallest latency possible. AudioTrack instances in static mode 49ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * can play the sound without the need to transfer the audio data from Java to native layer 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each time the sound is to be played. The static mode will therefore be preferred for UI and 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * game sounds that are played often, and with the smallest overhead possible. 52ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Upon creation, an AudioTrack object initializes its associated audio buffer. 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The size of this buffer, specified during the construction, determines how long an AudioTrack 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can play before running out of data.<br> 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For an AudioTrack using the static mode, this size is the maximum size of the sound that can 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be played from it.<br> 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For the streaming mode, data will be written to the hardware in chunks of 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sizes inferior to the total buffer size. 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class AudioTrack 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Constants 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Minimum value for a channel volume */ 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float VOLUME_MIN = 0.0f; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Maximum value for a channel volume */ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final float VOLUME_MAX = 1.0f; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 71ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi /** indicates AudioTrack state is stopped */ 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int PLAYSTATE_STOPPED = 1; // matches SL_PLAYSTATE_STOPPED 73ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi /** indicates AudioTrack state is paused */ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int PLAYSTATE_PAUSED = 2; // matches SL_PLAYSTATE_PAUSED 75ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi /** indicates AudioTrack state is playing */ 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int PLAYSTATE_PLAYING = 3; // matches SL_PLAYSTATE_PLAYING 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creation mode where audio data is transferred from Java to the native layer 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * only once before the audio starts playing. 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MODE_STATIC = 0; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creation mode where audio data is streamed from Java to the native layer 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as the audio is playing. 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int MODE_STREAM = 1; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 90ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * State of an AudioTrack that was not successfully initialized upon creation. 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int STATE_UNINITIALIZED = 0; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * State of an AudioTrack that is ready to be used. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int STATE_INITIALIZED = 1; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * State of a successfully initialized AudioTrack that uses static data, 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but that hasn't received that data yet. 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int STATE_NO_STATIC_DATA = 2; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Error codes: 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to keep in sync with frameworks/base/core/jni/android_media_AudioTrack.cpp 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Denotes a successful operation. 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SUCCESS = 0; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Denotes a generic operation failure. 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ERROR = -1; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Denotes a failure due to the use of an invalid value. 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ERROR_BAD_VALUE = -2; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Denotes a failure due to the improper use of a method. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int ERROR_INVALID_OPERATION = -3; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ERROR_NATIVESETUP_AUDIOSYSTEM = -16; 123a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent private static final int ERROR_NATIVESETUP_INVALIDCHANNELMASK = -17; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ERROR_NATIVESETUP_INVALIDFORMAT = -18; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ERROR_NATIVESETUP_INVALIDSTREAMTYPE = -19; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ERROR_NATIVESETUP_NATIVEINITFAILED = -20; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Events: 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to keep in sync with frameworks/base/include/media/AudioTrack.h 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 131ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Event id denotes when playback head has reached a previously set marker. 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int NATIVE_EVENT_MARKER = 3; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 135ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Event id denotes when previously set update period has elapsed during playback. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int NATIVE_EVENT_NEW_POS = 4; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static String TAG = "AudioTrack-Java"; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------------------------------------------------------------- 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Member variables 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 146ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Indicates the state of the AudioTrack instance. 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mState = STATE_UNINITIALIZED; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 150ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Indicates the play state of the AudioTrack instance. 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mPlayState = PLAYSTATE_STOPPED; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Lock to make sure mPlayState updates are reflecting the actual state of the object. 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Object mPlayStateLock = new Object(); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1584df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * The listener the AudioTrack notifies when the playback position reaches a marker 1594df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * or for periodic updates during the progression of the playback head. 1604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @see #setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener) 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1624df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project private OnPlaybackPositionUpdateListener mPositionListener = null; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 164ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Lock to protect event listener updates against event notifications. 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1664df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project private final Object mPositionListenerLock = new Object(); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Size of the native audio buffer. 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mNativeBufferSizeInBytes = 0; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 172ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Handler for marker events coming from the native code. 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1744df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project private NativeEventHandlerDelegate mEventHandlerDelegate = null; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 176ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Looper associated with the thread that creates the AudioTrack instance. 177105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project */ 178105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private Looper mInitializationLooper = null; 179105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project /** 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The audio data sampling rate in Hz. 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSampleRate = 22050; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1843026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent * The number of audio output channels (1 is mono, 2 is stereo). 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mChannelCount = 1; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1883026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent * The audio channel mask. 1893026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent */ 1903026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent private int mChannels = AudioFormat.CHANNEL_OUT_MONO; 1913026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent 1923026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent /** 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The type of the audio stream to play. See 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM}, 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC} and 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioManager#STREAM_ALARM} 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mStreamType = AudioManager.STREAM_MUSIC; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The way audio is consumed by the hardware, streaming or static. 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDataLoadMode = MODE_STREAM; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 204ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * The current audio channel configuration. 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 206a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent private int mChannelConfiguration = AudioFormat.CHANNEL_OUT_MONO; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The encoding of the audio samples. 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see AudioFormat#ENCODING_PCM_8BIT 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see AudioFormat#ENCODING_PCM_16BIT 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT; 213619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent /** 214619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * Audio session ID 215619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent */ 216619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent private int mSessionId = 0; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------------------- 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Used exclusively by native code 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 223ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Accessed by native methods: provides access to C++ AudioTrack object. 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("unused") 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mNativeTrackInJavaObj; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Accessed by native methods: provides access to the JNI data (i.e. resources used by 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the native AudioTrack object, but not stored in it). 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("unused") 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mJniData; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------------------------------------------------------------- 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Constructor, Finalize 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Class constructor. 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param streamType the type of the audio stream. See 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM}, 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC} and 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioManager#STREAM_ALARM} 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sampleRateInHz the sample rate expressed in Hertz. Examples of rates are (but 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not limited to) 44100, 22050 and 11025. 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param channelConfig describes the configuration of the audio channels. 247a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * See {@link AudioFormat#CHANNEL_OUT_MONO} and 248a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * {@link AudioFormat#CHANNEL_OUT_STEREO} 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param audioFormat the format in which the audio data is represented. 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link AudioFormat#ENCODING_PCM_16BIT} and 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioFormat#ENCODING_PCM_8BIT} 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * from for playback. If using the AudioTrack in streaming mode, you can write data into 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this buffer in smaller chunks than this size. If using the AudioTrack in static mode, 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this is the maximum size of the sound that will be played for this instance. 256ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size 257ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * for the successful creation of an AudioTrack instance in streaming mode. Using values 258ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * smaller than getMinBufferSize() will result in an initialization failure. 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM} 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws java.lang.IllegalArgumentException 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int bufferSizeInBytes, int mode) 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IllegalArgumentException { 265619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent this(streamType, sampleRateInHz, channelConfig, audioFormat, 266619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent bufferSizeInBytes, mode, 0); 267619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent } 268619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent 269619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent /** 270619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * Class constructor with audio session. Use this constructor when the AudioTrack must be 271619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * attached to a particular audio session. The primary use of the audio session ID is to 272619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * associate audio effects to a particular instance of AudioTrack: if an audio session ID 273619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * is provided when creating an AudioEffect, this effect will be applied only to audio tracks 274619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * and media players in the same session and not to the output mix. 275619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * When an AudioTrack is created without specifying a session, it will create its own session 276619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * which can be retreived by calling the {@link #getAudioSessionId()} method. 277619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * If a session ID is provided, this AudioTrack will share effects attached to this session 278619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * with all other media players or audio tracks in the same session. 279619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @param streamType the type of the audio stream. See 280619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM}, 281619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC} and 282619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * {@link AudioManager#STREAM_ALARM} 283619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @param sampleRateInHz the sample rate expressed in Hertz. Examples of rates are (but 284619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * not limited to) 44100, 22050 and 11025. 285619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @param channelConfig describes the configuration of the audio channels. 286619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * See {@link AudioFormat#CHANNEL_OUT_MONO} and 287619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * {@link AudioFormat#CHANNEL_OUT_STEREO} 288619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @param audioFormat the format in which the audio data is represented. 289619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * See {@link AudioFormat#ENCODING_PCM_16BIT} and 290619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * {@link AudioFormat#ENCODING_PCM_8BIT} 291619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read 292619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * from for playback. If using the AudioTrack in streaming mode, you can write data into 293619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * this buffer in smaller chunks than this size. If using the AudioTrack in static mode, 294619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * this is the maximum size of the sound that will be played for this instance. 295619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size 296619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * for the successful creation of an AudioTrack instance in streaming mode. Using values 297619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * smaller than getMinBufferSize() will result in an initialization failure. 298619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM} 299619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @param sessionId Id of audio session the AudioTrack must be attached to 300619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @throws java.lang.IllegalArgumentException 301619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent // FIXME: unhide. 302619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @hide 303619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent */ 304619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, 305619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent int bufferSizeInBytes, int mode, int sessionId) 306619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent throws IllegalArgumentException { 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = STATE_UNINITIALIZED; 308105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 309105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // remember which looper is associated with the AudioTrack instanciation 310105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if ((mInitializationLooper = Looper.myLooper()) == null) { 311105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mInitializationLooper = Looper.getMainLooper(); 312105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioParamCheck(streamType, sampleRateInHz, channelConfig, audioFormat, mode); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project audioBuffSizeCheck(bufferSizeInBytes); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 318619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent if (sessionId < 0) { 319619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent throw (new IllegalArgumentException("Invalid audio session ID: "+sessionId)); 320619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent } 321619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent 322619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent int[] session = new int[1]; 323619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent session[0] = sessionId; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // native initialization 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int initResult = native_setup(new WeakReference<AudioTrack>(this), 3263026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent mStreamType, mSampleRate, mChannels, mAudioFormat, 327619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent mNativeBufferSizeInBytes, mDataLoadMode, session); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (initResult != SUCCESS) { 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loge("Error code "+initResult+" when initializing AudioTrack."); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; // with mState == STATE_UNINITIALIZED 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 333619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent mSessionId = session[0]; 334619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataLoadMode == MODE_STATIC) { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = STATE_NO_STATIC_DATA; 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = STATE_INITIALIZED; 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Convenience method for the constructor's parameter checks. 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is where constructor IllegalArgumentException-s are thrown 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // postconditions: 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mStreamType is valid 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mChannelCount is valid 3483026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent // mChannels is valid 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mAudioFormat is valid 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mSampleRate is valid 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mDataLoadMode is valid 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void audioParamCheck(int streamType, int sampleRateInHz, 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int channelConfig, int audioFormat, int mode) { 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------- 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // stream type 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if( (streamType != AudioManager.STREAM_ALARM) && (streamType != AudioManager.STREAM_MUSIC) 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (streamType != AudioManager.STREAM_RING) && (streamType != AudioManager.STREAM_SYSTEM) 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (streamType != AudioManager.STREAM_VOICE_CALL) 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (streamType != AudioManager.STREAM_NOTIFICATION) 361a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent && (streamType != AudioManager.STREAM_BLUETOOTH_SCO) 362a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent && (streamType != AudioManager.STREAM_DTMF)) { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw (new IllegalArgumentException("Invalid stream type.")); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStreamType = streamType; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------- 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // sample rate 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw (new IllegalArgumentException(sampleRateInHz 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "Hz is not a supported sample rate.")); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSampleRate = sampleRateInHz; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------- 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // channel config 3793026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent mChannelConfiguration = channelConfig; 3803026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (channelConfig) { 3823026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent case AudioFormat.CHANNEL_OUT_DEFAULT: //AudioFormat.CHANNEL_CONFIGURATION_DEFAULT 383a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent case AudioFormat.CHANNEL_OUT_MONO: 3843026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent case AudioFormat.CHANNEL_CONFIGURATION_MONO: 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChannelCount = 1; 3863026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent mChannels = AudioFormat.CHANNEL_OUT_MONO; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 388a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent case AudioFormat.CHANNEL_OUT_STEREO: 3893026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent case AudioFormat.CHANNEL_CONFIGURATION_STEREO: 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChannelCount = 2; 3913026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent mChannels = AudioFormat.CHANNEL_OUT_STEREO; 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mChannelCount = 0; 3953026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent mChannels = AudioFormat.CHANNEL_INVALID; 3963026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_INVALID; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw(new IllegalArgumentException("Unsupported channel configuration.")); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------- 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // audio format 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (audioFormat) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AudioFormat.ENCODING_DEFAULT: 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioFormat = AudioFormat.ENCODING_PCM_16BIT; 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AudioFormat.ENCODING_PCM_16BIT: 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case AudioFormat.ENCODING_PCM_8BIT: 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioFormat = audioFormat; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mAudioFormat = AudioFormat.ENCODING_INVALID; 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw(new IllegalArgumentException("Unsupported sample encoding." 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " Should be ENCODING_PCM_8BIT or ENCODING_PCM_16BIT.")); 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------- 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // audio load mode 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( (mode != MODE_STREAM) && (mode != MODE_STATIC) ) { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw(new IllegalArgumentException("Invalid mode.")); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDataLoadMode = mode; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Convenience method for the contructor's audio buffer size check. 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preconditions: 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mChannelCount is valid 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mAudioFormat is valid 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // postcondition: 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mNativeBufferSizeInBytes is valid (multiple of frame size, positive) 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void audioBuffSizeCheck(int audioBufferSize) { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // NB: this section is only valid with PCM data. 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // To update when supporting compressed formats 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int frameSizeInBytes = mChannelCount 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (mAudioFormat == AudioFormat.ENCODING_PCM_8BIT ? 1 : 2); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw (new IllegalArgumentException("Invalid audio buffer size.")); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNativeBufferSizeInBytes = audioBufferSize; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Releases the native AudioTrack resources. 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void release() { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // even though native_release() stops the native AudioTrack, we need to stop 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // AudioTrack subclasses too. 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stop(); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch(IllegalStateException ise) { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't raise an exception, we're releasing the resources. 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_release(); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = STATE_UNINITIALIZED; 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void finalize() { 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_finalize(); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------------------------------------------------------------- 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Getters 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the minimum valid volume value. Volume values set under this one will 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be clamped at this value. 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the minimum volume expressed as a linear attenuation. 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public float getMinVolume() { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AudioTrack.VOLUME_MIN; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the maximum valid volume value. Volume values set above this one will 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be clamped at this value. 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the maximum volume expressed as a linear attenuation. 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public float getMaxVolume() { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AudioTrack.VOLUME_MAX; 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the configured audio data sample rate in Hz 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getSampleRate() { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mSampleRate; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 49488e209dcf8c2ebddda5c272f46d1bd5478bc639cEric Laurent * Returns the current playback rate in Hz. 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPlaybackRate() { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_get_playback_rate(); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_16BIT} 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and {@link AudioFormat#ENCODING_PCM_8BIT}. 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAudioFormat() { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mAudioFormat; 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the type of audio stream this AudioTrack is configured for. 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Compare the result against {@link AudioManager#STREAM_VOICE_CALL}, 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioManager#STREAM_SYSTEM}, {@link AudioManager#STREAM_RING}, 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioManager#STREAM_MUSIC} or {@link AudioManager#STREAM_ALARM} 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStreamType() { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStreamType; 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the configured channel configuration. 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 521a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * See {@link AudioFormat#CHANNEL_OUT_MONO} 522a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * and {@link AudioFormat#CHANNEL_OUT_STEREO}. 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChannelConfiguration() { 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mChannelConfiguration; 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the configured number of channels. 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getChannelCount() { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mChannelCount; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the state of the AudioTrack instance. This is useful after the 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * AudioTrack instance has been created to check if it was initialized 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * properly. This ensures that the appropriate hardware resources have been 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * acquired. 540ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @see #STATE_INITIALIZED 541ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @see #STATE_NO_STATIC_DATA 542ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @see #STATE_UNINITIALIZED 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getState() { 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mState; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the playback state of the AudioTrack instance. 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #PLAYSTATE_STOPPED 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #PLAYSTATE_PAUSED 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #PLAYSTATE_PLAYING 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPlayState() { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPlayState; 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 559ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Returns the native frame count used by the hardware. 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int getNativeFrameCount() { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_get_native_frame_count(); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 566ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Returns marker position expressed in frames. 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getNotificationMarkerPosition() { 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_get_marker_pos(); 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 573ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Returns the notification update period expressed in frames. 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPositionNotificationPeriod() { 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_get_pos_update_period(); 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 580ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Returns the playback head position expressed in frames 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPlaybackHeadPosition() { 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_get_position(); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the hardware output sample rate 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public int getNativeOutputSampleRate(int streamType) { 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_get_output_sample_rate(streamType); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the minimum buffer size required for the successful creation of an AudioTrack 595ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * object to be created in the {@link #MODE_STREAM} mode. Note that this size doesn't 596ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * guarantee a smooth playback under load, and higher values should be chosen according to 597ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * the expected frequency at which the buffer will be refilled with additional data to play. 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sampleRateInHz the sample rate expressed in Hertz. 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param channelConfig describes the configuration of the audio channels. 600a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * See {@link AudioFormat#CHANNEL_OUT_MONO} and 601a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * {@link AudioFormat#CHANNEL_OUT_STEREO} 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param audioFormat the format in which the audio data is represented. 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See {@link AudioFormat#ENCODING_PCM_16BIT} and 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link AudioFormat#ENCODING_PCM_8BIT} 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return {@link #ERROR_BAD_VALUE} if an invalid parameter was passed, 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or {@link #ERROR} if the implementation was unable to query the hardware for its output 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * properties, 608ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * or the minimum buffer size expressed in bytes. 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) { 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int channelCount = 0; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(channelConfig) { 613a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent case AudioFormat.CHANNEL_OUT_MONO: 6143026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent case AudioFormat.CHANNEL_CONFIGURATION_MONO: 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project channelCount = 1; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 617a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent case AudioFormat.CHANNEL_OUT_STEREO: 6183026a023b8979b7ddcb3fe97bbc45531c89fda92Eric Laurent case AudioFormat.CHANNEL_CONFIGURATION_STEREO: 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project channelCount = 2; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loge("getMinBufferSize(): Invalid channel configuration."); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AudioTrack.ERROR_BAD_VALUE; 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((audioFormat != AudioFormat.ENCODING_PCM_16BIT) 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (audioFormat != AudioFormat.ENCODING_PCM_8BIT)) { 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loge("getMinBufferSize(): Invalid audio format."); 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AudioTrack.ERROR_BAD_VALUE; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) { 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loge("getMinBufferSize(): " + sampleRateInHz +"Hz is not a supported sample rate."); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AudioTrack.ERROR_BAD_VALUE; 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((size == -1) || (size == 0)) { 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loge("getMinBufferSize(): error querying hardware"); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return AudioTrack.ERROR; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return size; 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 647619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent /** 648619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * Returns the audio session ID. 649619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * 650619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @return the ID of the audio session this AudioTrack belongs to. 651619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent // FIXME: unhide. 652619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent // FIXME: link to AudioEffect class when public. 653619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent * @hide 654619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent */ 655619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent public int getAudioSessionId() { 656619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent return mSessionId; 657619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------------------------------------------------------------- 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Initialization / configuration 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * Sets the listener the AudioTrack notifies when a previously set marker is reached or 6644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * for each periodic playback head position update. 665ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Notifications will be received in the same thread as the one in which the AudioTrack 666ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * instance was created. 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param listener 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6694df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener) { 6704df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project setPlaybackPositionUpdateListener(listener, null); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6724df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 673ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi /** 674ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Sets the listener the AudioTrack notifies when a previously set marker is reached or 675ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * for each periodic playback head position update. 676ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Use this method to receive AudioTrack events in the Handler associated with another 677ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * thread than the one in which you created the AudioTrack instance. 678ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @param listener 679ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @param handler the Handler that will receive the event notification messages. 680ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi */ 6814df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener, 6824df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project Handler handler) { 6834df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project synchronized (mPositionListenerLock) { 6844df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mPositionListener = listener; 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6864df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (listener != null) { 6874df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mEventHandlerDelegate = new NativeEventHandlerDelegate(this, handler); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6894df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6934df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the specified left/right output volume values on the AudioTrack. Values are clamped 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the ({@link #getMinVolume()}, {@link #getMaxVolume()}) interval if outside this range. 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param leftVolume output attenuation for the left channel. A value of 0.0f is silence, 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a value of 1.0f is no attenuation. 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param rightVolume output attenuation for the right channel 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return error code or success, see {@link #SUCCESS}, 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #ERROR_INVALID_OPERATION} 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int setStereoVolume(float leftVolume, float rightVolume) { 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // clamp the volumes 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (leftVolume < getMinVolume()) { 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftVolume = getMinVolume(); 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (leftVolume > getMaxVolume()) { 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftVolume = getMaxVolume(); 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rightVolume < getMinVolume()) { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rightVolume = getMinVolume(); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rightVolume > getMaxVolume()) { 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rightVolume = getMaxVolume(); 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_setVolume(leftVolume, rightVolume); 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return SUCCESS; 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the playback sample rate for this track. This sets the sampling rate at which 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the audio data will be consumed and played back, not the original sampling rate of the 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * content. Setting it to half the sample rate of the content will cause the playback to 73288e209dcf8c2ebddda5c272f46d1bd5478bc639cEric Laurent * last twice as long, but will also result in a negative pitch shift. 73388e209dcf8c2ebddda5c272f46d1bd5478bc639cEric Laurent * The valid sample rate range if from 1Hz to twice the value returned by 73488e209dcf8c2ebddda5c272f46d1bd5478bc639cEric Laurent * {@link #getNativeOutputSampleRate(int)}. 735ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @param sampleRateInHz the sample rate expressed in Hz 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #ERROR_INVALID_OPERATION} 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int setPlaybackRate(int sampleRateInHz) { 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sampleRateInHz <= 0) { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_BAD_VALUE; 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 74688e209dcf8c2ebddda5c272f46d1bd5478bc639cEric Laurent return native_set_playback_rate(sampleRateInHz); 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 751ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Sets the position of the notification marker. 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param markerInFrames marker in frames 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #ERROR_INVALID_OPERATION} 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int setNotificationMarkerPosition(int markerInFrames) { 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_set_marker_pos(markerInFrames); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 765ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * Sets the period for the periodic notification event. 766ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @param periodInFrames update period expressed in frames 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION} 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int setPositionNotificationPeriod(int periodInFrames) { 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_set_pos_update_period(periodInFrames); 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the playback head position. The track must be stopped for the position to be changed. 779ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @param positionInFrames playback head position expressed in frames 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #ERROR_INVALID_OPERATION} 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int setPlaybackHeadPosition(int positionInFrames) { 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mPlayStateLock) { 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mPlayState == PLAYSTATE_STOPPED) || (mPlayState == PLAYSTATE_PAUSED)) { 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_set_position(positionInFrames); 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the loop points and the loop count. The loop can be infinite. 795ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @param startInFrames loop start marker expressed in frames 796ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @param endInFrames loop end marker expressed in frames 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param loopCount the number of times the loop is looped. 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A value of -1 means infinite looping. 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #ERROR_INVALID_OPERATION} 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int setLoopPoints(int startInFrames, int endInFrames, int loopCount) { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataLoadMode == MODE_STREAM) { 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_set_loop(startInFrames, endInFrames, loopCount); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the initialization state of the instance. To be used in an AudioTrack subclass 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constructor to set a subclass-specific post-initialization state. 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param state the state of the AudioTrack instance 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void setState(int state) { 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = state; 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Transport control methods 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Starts playing an AudioTrack. 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void play() 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IllegalStateException { 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw(new IllegalStateException("play() called on uninitialized AudioTrack.")); 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mPlayStateLock) { 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_start(); 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayState = PLAYSTATE_PLAYING; 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Stops playing the audio data. 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void stop() 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IllegalStateException { 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw(new IllegalStateException("stop() called on uninitialized AudioTrack.")); 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // stop playing 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mPlayStateLock) { 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayState = PLAYSTATE_STOPPED; 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Pauses the playback of the audio data. 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throws IllegalStateException 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void pause() 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws IllegalStateException { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw(new IllegalStateException("pause() called on uninitialized AudioTrack.")); 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //logd("pause()"); 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // pause playback 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mPlayStateLock) { 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_pause(); 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPlayState = PLAYSTATE_PAUSED; 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Audio data supply 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Flushes the audio data currently queued for playback. 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void flush() { 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState == STATE_INITIALIZED) { 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // flush the data in native layer 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_flush(); 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Writes the audio data to the audio hardware for playback. 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param audioData the array that holds the data to play. 893ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @param offsetInBytes the offset expressed in bytes in audioData where the data to play 894ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * starts. 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sizeInBytes the number of bytes to read in audioData after the offset. 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of bytes that were written or {@link #ERROR_INVALID_OPERATION} 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the parameters don't resolve to valid data and indexes. 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int write(byte[] audioData,int offsetInBytes, int sizeInBytes) { 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mDataLoadMode == MODE_STATIC) 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (mState == STATE_NO_STATIC_DATA) 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (sizeInBytes > 0)) { 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = STATE_INITIALIZED; 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( (audioData == null) || (offsetInBytes < 0 ) || (sizeInBytes < 0) 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || (offsetInBytes + sizeInBytes > audioData.length)) { 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_BAD_VALUE; 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat); 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Writes the audio data to the audio hardware for playback. 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param audioData the array that holds the data to play. 924ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * @param offsetInShorts the offset expressed in shorts in audioData where the data to play 925ff14c25339da3f6cd86edd66ef42640e6d0c0787Jean-Michel Trivi * starts. 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param sizeInShorts the number of bytes to read in audioData after the offset. 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the number of shorts that were written or {@link #ERROR_INVALID_OPERATION} 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the parameters don't resolve to valid data and indexes. 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int write(short[] audioData, int offsetInShorts, int sizeInShorts) { 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mDataLoadMode == MODE_STATIC) 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (mState == STATE_NO_STATIC_DATA) 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (sizeInShorts > 0)) { 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mState = STATE_INITIALIZED; 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mState != STATE_INITIALIZED) { 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ( (audioData == null) || (offsetInShorts < 0 ) || (sizeInShorts < 0) 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || (offsetInShorts + sizeInShorts > audioData.length)) { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_BAD_VALUE; 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_write_short(audioData, offsetInShorts, sizeInShorts, mAudioFormat); 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Notifies the native resource to reuse the audio data already loaded in the native 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * layer. This call is only valid with AudioTrack instances that don't use the streaming 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * model. 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #ERROR_INVALID_OPERATION} 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int reloadStaticData() { 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDataLoadMode == MODE_STREAM) { 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ERROR_INVALID_OPERATION; 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_reload_static(); 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Interface definitions 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9714df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * Interface definition for a callback to be invoked when the playback head position of 9724df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * an AudioTrack has reached a notification marker or has increased by a certain period. 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9744df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public interface OnPlaybackPositionUpdateListener { 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called on the listener to notify it that the previously set marker has been reached 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the playback head. 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onMarkerReached(AudioTrack track); 9804df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called on the listener to periodically notify it that the playback head has reached 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a multiple of the notification period. 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onPeriodicNotification(AudioTrack track); 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Inner classes 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9934df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * Helper class to handle the forwarding of native events to the appropriate listener 9944df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * (potentially) handled in a different thread 9954df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project */ 9964df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project private class NativeEventHandlerDelegate { 9974df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project private final AudioTrack mAudioTrack; 9984df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project private final Handler mHandler; 9994df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 10004df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project NativeEventHandlerDelegate(AudioTrack track, Handler handler) { 10014df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mAudioTrack = track; 10024df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // find the looper for our new event handler 10034df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project Looper looper; 10044df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (handler != null) { 10054df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project looper = handler.getLooper(); 10064df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } else { 1007105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // no given handler, use the looper the AudioTrack was created in 1008105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project looper = mInitializationLooper; 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1010105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 10114df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // construct the event handler with this looper 10124df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (looper != null) { 10134df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // implement the event handler delegate 10144df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mHandler = new Handler(looper) { 10154df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project @Override 10164df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public void handleMessage(Message msg) { 10174df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (mAudioTrack == null) { 10184df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return; 10194df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10204df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project OnPlaybackPositionUpdateListener listener = null; 10214df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project synchronized (mPositionListenerLock) { 10224df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project listener = mAudioTrack.mPositionListener; 10234df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10244df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project switch(msg.what) { 10254df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project case NATIVE_EVENT_MARKER: 10264df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (listener != null) { 10274df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project listener.onMarkerReached(mAudioTrack); 10284df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10294df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project break; 10304df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project case NATIVE_EVENT_NEW_POS: 10314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (listener != null) { 10324df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project listener.onPeriodicNotification(mAudioTrack); 10334df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10344df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project break; 10354df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project default: 10364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project Log.e(TAG, "[ android.media.AudioTrack.NativeEventHandler ] " + 10374df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project "Unknown event type: " + msg.what); 10384df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project break; 10394df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10404df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10414df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project }; 10424df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } else { 10434df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mHandler = null; 10444df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10454df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10464df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 10474df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project Handler getHandler() { 10484df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return mHandler; 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Java methods called from the native side 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @SuppressWarnings("unused") 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static void postEventFromNative(Object audiotrack_ref, 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int what, int arg1, int arg2, Object obj) { 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2); 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AudioTrack track = (AudioTrack)((WeakReference)audiotrack_ref).get(); 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (track == null) { 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10654df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (track.mEventHandlerDelegate != null) { 10664df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project Message m = 10674df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project track.mEventHandlerDelegate.getHandler().obtainMessage(what, arg1, arg2, obj); 10684df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project track.mEventHandlerDelegate.getHandler().sendMessage(m); 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Native methods called from the Java side 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //-------------------- 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_setup(Object audiotrack_this, 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int streamType, int sampleRate, int nbChannels, int audioFormat, 1080619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent int buffSizeInBytes, int mode, int[] sessionId); 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_finalize(); 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_release(); 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_start(); 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_stop(); 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_pause(); 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_flush(); 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_write_byte(byte[] audioData, 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offsetInBytes, int sizeInBytes, int format); 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_write_short(short[] audioData, 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offsetInShorts, int sizeInShorts, int format); 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_reload_static(); 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_get_native_frame_count(); 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final void native_setVolume(float leftVolume, float rightVolume); 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 110688e209dcf8c2ebddda5c272f46d1bd5478bc639cEric Laurent private native final int native_set_playback_rate(int sampleRateInHz); 110788e209dcf8c2ebddda5c272f46d1bd5478bc639cEric Laurent private native final int native_get_playback_rate(); 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_set_marker_pos(int marker); 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_get_marker_pos(); 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_set_pos_update_period(int updatePeriod); 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_get_pos_update_period(); 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_set_position(int position); 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_get_position(); 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native final int native_set_loop(int start, int end, int loopCount); 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static private native final int native_get_output_sample_rate(int streamType); 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static private native final int native_get_min_buff_size( 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int sampleRateInHz, int channelConfig, int audioFormat); 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1124619346f902241736d933657a4fe10f10c50a1ba8Eric Laurent private native final int native_get_session_id(); 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //--------------------------------------------------------- 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Utility methods 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //------------------ 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static void logd(String msg) { 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "[ android.media.AudioTrack ] " + msg); 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static void loge(String msg) { 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "[ android.media.AudioTrack ] " + msg); 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1139