1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.media;
18 
19 import java.lang.annotation.Retention;
20 import java.lang.annotation.RetentionPolicy;
21 import java.lang.ref.WeakReference;
22 import java.lang.Math;
23 import java.nio.ByteBuffer;
24 import java.nio.ByteOrder;
25 import java.nio.NioUtils;
26 import java.util.Collection;
27 
28 import android.annotation.IntDef;
29 import android.annotation.NonNull;
30 import android.app.ActivityThread;
31 import android.app.AppOpsManager;
32 import android.content.Context;
33 import android.os.Handler;
34 import android.os.IBinder;
35 import android.os.Looper;
36 import android.os.Message;
37 import android.os.Process;
38 import android.os.RemoteException;
39 import android.os.ServiceManager;
40 import android.util.ArrayMap;
41 import android.util.Log;
42 
43 import com.android.internal.app.IAppOpsService;
44 
45 
46 /**
47  * The AudioTrack class manages and plays a single audio resource for Java applications.
48  * It allows streaming of PCM audio buffers to the audio sink for playback. This is
49  * achieved by "pushing" the data to the AudioTrack object using one of the
50  *  {@link #write(byte[], int, int)}, {@link #write(short[], int, int)},
51  *  and {@link #write(float[], int, int, int)} methods.
52  *
53  * <p>An AudioTrack instance can operate under two modes: static or streaming.<br>
54  * In Streaming mode, the application writes a continuous stream of data to the AudioTrack, using
55  * one of the {@code write()} methods. These are blocking and return when the data has been
56  * transferred from the Java layer to the native layer and queued for playback. The streaming
57  * mode is most useful when playing blocks of audio data that for instance are:
58  *
59  * <ul>
60  *   <li>too big to fit in memory because of the duration of the sound to play,</li>
61  *   <li>too big to fit in memory because of the characteristics of the audio data
62  *         (high sampling rate, bits per sample ...)</li>
63  *   <li>received or generated while previously queued audio is playing.</li>
64  * </ul>
65  *
66  * The static mode should be chosen when dealing with short sounds that fit in memory and
67  * that need to be played with the smallest latency possible. The static mode will
68  * therefore be preferred for UI and game sounds that are played often, and with the
69  * smallest overhead possible.
70  *
71  * <p>Upon creation, an AudioTrack object initializes its associated audio buffer.
72  * The size of this buffer, specified during the construction, determines how long an AudioTrack
73  * can play before running out of data.<br>
74  * For an AudioTrack using the static mode, this size is the maximum size of the sound that can
75  * be played from it.<br>
76  * For the streaming mode, data will be written to the audio sink in chunks of
77  * sizes less than or equal to the total buffer size.
78  *
79  * AudioTrack is not final and thus permits subclasses, but such use is not recommended.
80  */
81 public class AudioTrack
82 {
83     //---------------------------------------------------------
84     // Constants
85     //--------------------
86     /** Minimum value for a linear gain or auxiliary effect level.
87      *  This value must be exactly equal to 0.0f; do not change it.
88      */
89     private static final float GAIN_MIN = 0.0f;
90     /** Maximum value for a linear gain or auxiliary effect level.
91      *  This value must be greater than or equal to 1.0f.
92      */
93     private static final float GAIN_MAX = 1.0f;
94 
95     /** Minimum value for sample rate */
96     private static final int SAMPLE_RATE_HZ_MIN = 4000;
97     /** Maximum value for sample rate */
98     private static final int SAMPLE_RATE_HZ_MAX = 192000;
99 
100     // FCC_8
101     /** Maximum value for AudioTrack channel count */
102     private static final int CHANNEL_COUNT_MAX = 8;
103 
104     /** indicates AudioTrack state is stopped */
105     public static final int PLAYSTATE_STOPPED = 1;  // matches SL_PLAYSTATE_STOPPED
106     /** indicates AudioTrack state is paused */
107     public static final int PLAYSTATE_PAUSED  = 2;  // matches SL_PLAYSTATE_PAUSED
108     /** indicates AudioTrack state is playing */
109     public static final int PLAYSTATE_PLAYING = 3;  // matches SL_PLAYSTATE_PLAYING
110 
111     // keep these values in sync with android_media_AudioTrack.cpp
112     /**
113      * Creation mode where audio data is transferred from Java to the native layer
114      * only once before the audio starts playing.
115      */
116     public static final int MODE_STATIC = 0;
117     /**
118      * Creation mode where audio data is streamed from Java to the native layer
119      * as the audio is playing.
120      */
121     public static final int MODE_STREAM = 1;
122 
123     /** @hide */
124     @IntDef({
125         MODE_STATIC,
126         MODE_STREAM
127     })
128     @Retention(RetentionPolicy.SOURCE)
129     public @interface TransferMode {}
130 
131     /**
132      * State of an AudioTrack that was not successfully initialized upon creation.
133      */
134     public static final int STATE_UNINITIALIZED = 0;
135     /**
136      * State of an AudioTrack that is ready to be used.
137      */
138     public static final int STATE_INITIALIZED   = 1;
139     /**
140      * State of a successfully initialized AudioTrack that uses static data,
141      * but that hasn't received that data yet.
142      */
143     public static final int STATE_NO_STATIC_DATA = 2;
144 
145     /**
146      * Denotes a successful operation.
147      */
148     public  static final int SUCCESS                               = AudioSystem.SUCCESS;
149     /**
150      * Denotes a generic operation failure.
151      */
152     public  static final int ERROR                                 = AudioSystem.ERROR;
153     /**
154      * Denotes a failure due to the use of an invalid value.
155      */
156     public  static final int ERROR_BAD_VALUE                       = AudioSystem.BAD_VALUE;
157     /**
158      * Denotes a failure due to the improper use of a method.
159      */
160     public  static final int ERROR_INVALID_OPERATION               = AudioSystem.INVALID_OPERATION;
161     /**
162      * An error code indicating that the object reporting it is no longer valid and needs to
163      * be recreated.
164      * @hide
165      */
166     public  static final int ERROR_DEAD_OBJECT                     = AudioSystem.DEAD_OBJECT;
167     /**
168      * {@link #getTimestampWithStatus(AudioTimestamp)} is called in STOPPED or FLUSHED state,
169      * or immediately after start/ACTIVE.
170      * @hide
171      */
172     public  static final int ERROR_WOULD_BLOCK                     = AudioSystem.WOULD_BLOCK;
173 
174     // Error codes:
175     // to keep in sync with frameworks/base/core/jni/android_media_AudioTrack.cpp
176     private static final int ERROR_NATIVESETUP_AUDIOSYSTEM         = -16;
177     private static final int ERROR_NATIVESETUP_INVALIDCHANNELMASK  = -17;
178     private static final int ERROR_NATIVESETUP_INVALIDFORMAT       = -18;
179     private static final int ERROR_NATIVESETUP_INVALIDSTREAMTYPE   = -19;
180     private static final int ERROR_NATIVESETUP_NATIVEINITFAILED    = -20;
181 
182     // Events:
183     // to keep in sync with frameworks/av/include/media/AudioTrack.h
184     /**
185      * Event id denotes when playback head has reached a previously set marker.
186      */
187     private static final int NATIVE_EVENT_MARKER  = 3;
188     /**
189      * Event id denotes when previously set update period has elapsed during playback.
190      */
191     private static final int NATIVE_EVENT_NEW_POS = 4;
192 
193     private final static String TAG = "android.media.AudioTrack";
194 
195 
196     /** @hide */
197     @IntDef({
198         WRITE_BLOCKING,
199         WRITE_NON_BLOCKING
200     })
201     @Retention(RetentionPolicy.SOURCE)
202     public @interface WriteMode {}
203 
204     /**
205      * The write mode indicating the write operation will block until all data has been written,
206      * to be used as the actual value of the writeMode parameter in
207      * {@link #write(byte[], int, int, int)}, {@link #write(short[], int, int, int)},
208      * {@link #write(float[], int, int, int)}, {@link #write(ByteBuffer, int, int)}, and
209      * {@link #write(ByteBuffer, int, int, long)}.
210      */
211     public final static int WRITE_BLOCKING = 0;
212 
213     /**
214      * The write mode indicating the write operation will return immediately after
215      * queuing as much audio data for playback as possible without blocking,
216      * to be used as the actual value of the writeMode parameter in
217      * {@link #write(ByteBuffer, int, int)}, {@link #write(short[], int, int, int)},
218      * {@link #write(float[], int, int, int)}, {@link #write(ByteBuffer, int, int)}, and
219      * {@link #write(ByteBuffer, int, int, long)}.
220      */
221     public final static int WRITE_NON_BLOCKING = 1;
222 
223     //--------------------------------------------------------------------------
224     // Member variables
225     //--------------------
226     /**
227      * Indicates the state of the AudioTrack instance.
228      * One of STATE_UNINITIALIZED, STATE_INITIALIZED, or STATE_NO_STATIC_DATA.
229      */
230     private int mState = STATE_UNINITIALIZED;
231     /**
232      * Indicates the play state of the AudioTrack instance.
233      * One of PLAYSTATE_STOPPED, PLAYSTATE_PAUSED, or PLAYSTATE_PLAYING.
234      */
235     private int mPlayState = PLAYSTATE_STOPPED;
236     /**
237      * Lock to ensure mPlayState updates reflect the actual state of the object.
238      */
239     private final Object mPlayStateLock = new Object();
240     /**
241      * Sizes of the native audio buffer.
242      * These values are set during construction and can be stale.
243      * To obtain the current native audio buffer frame count use {@link #getBufferSizeInFrames()}.
244      */
245     private int mNativeBufferSizeInBytes = 0;
246     private int mNativeBufferSizeInFrames = 0;
247     /**
248      * Handler for events coming from the native code.
249      */
250     private NativePositionEventHandlerDelegate mEventHandlerDelegate;
251     /**
252      * Looper associated with the thread that creates the AudioTrack instance.
253      */
254     private final Looper mInitializationLooper;
255     /**
256      * The audio data source sampling rate in Hz.
257      */
258     private int mSampleRate; // initialized by all constructors via audioParamCheck()
259     /**
260      * The number of audio output channels (1 is mono, 2 is stereo, etc.).
261      */
262     private int mChannelCount = 1;
263     /**
264      * The audio channel mask used for calling native AudioTrack
265      */
266     private int mChannelMask = AudioFormat.CHANNEL_OUT_MONO;
267 
268     /**
269      * The type of the audio stream to play. See
270      *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
271      *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
272      *   {@link AudioManager#STREAM_ALARM}, {@link AudioManager#STREAM_NOTIFICATION}, and
273      *   {@link AudioManager#STREAM_DTMF}.
274      */
275     private int mStreamType = AudioManager.STREAM_MUSIC;
276 
277     private final AudioAttributes mAttributes;
278     /**
279      * The way audio is consumed by the audio sink, one of MODE_STATIC or MODE_STREAM.
280      */
281     private int mDataLoadMode = MODE_STREAM;
282     /**
283      * The current channel position mask, as specified on AudioTrack creation.
284      * Can be set simultaneously with channel index mask {@link #mChannelIndexMask}.
285      * May be set to {@link AudioFormat#CHANNEL_INVALID} if a channel index mask is specified.
286      */
287     private int mChannelConfiguration = AudioFormat.CHANNEL_OUT_MONO;
288     /**
289      * The channel index mask if specified, otherwise 0.
290      */
291     private int mChannelIndexMask = 0;
292     /**
293      * The encoding of the audio samples.
294      * @see AudioFormat#ENCODING_PCM_8BIT
295      * @see AudioFormat#ENCODING_PCM_16BIT
296      * @see AudioFormat#ENCODING_PCM_FLOAT
297      */
298     private int mAudioFormat;   // initialized by all constructors via audioParamCheck()
299     /**
300      * Audio session ID
301      */
302     private int mSessionId = AudioSystem.AUDIO_SESSION_ALLOCATE;
303     /**
304      * Reference to the app-ops service.
305      */
306     private final IAppOpsService mAppOps;
307     /**
308      * HW_AV_SYNC track AV Sync Header
309      */
310     private ByteBuffer mAvSyncHeader = null;
311     /**
312      * HW_AV_SYNC track audio data bytes remaining to write after current AV sync header
313      */
314     private int mAvSyncBytesRemaining = 0;
315 
316     //--------------------------------
317     // Used exclusively by native code
318     //--------------------
319     /**
320      * Accessed by native methods: provides access to C++ AudioTrack object.
321      */
322     @SuppressWarnings("unused")
323     private long mNativeTrackInJavaObj;
324     /**
325      * Accessed by native methods: provides access to the JNI data (i.e. resources used by
326      * the native AudioTrack object, but not stored in it).
327      */
328     @SuppressWarnings("unused")
329     private long mJniData;
330 
331 
332     //--------------------------------------------------------------------------
333     // Constructor, Finalize
334     //--------------------
335     /**
336      * Class constructor.
337      * @param streamType the type of the audio stream. See
338      *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
339      *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
340      *   {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
341      * @param sampleRateInHz the initial source sample rate expressed in Hz.
342      * @param channelConfig describes the configuration of the audio channels.
343      *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
344      *   {@link AudioFormat#CHANNEL_OUT_STEREO}
345      * @param audioFormat the format in which the audio data is represented.
346      *   See {@link AudioFormat#ENCODING_PCM_16BIT},
347      *   {@link AudioFormat#ENCODING_PCM_8BIT},
348      *   and {@link AudioFormat#ENCODING_PCM_FLOAT}.
349      * @param bufferSizeInBytes the total size (in bytes) of the internal buffer where audio data is
350      *   read from for playback. This should be a multiple of the frame size in bytes.
351      *   <p> If the track's creation mode is {@link #MODE_STATIC},
352      *   this is the maximum length sample, or audio clip, that can be played by this instance.
353      *   <p> If the track's creation mode is {@link #MODE_STREAM},
354      *   this should be the desired buffer size
355      *   for the <code>AudioTrack</code> to satisfy the application's
356      *   natural latency requirements.
357      *   If <code>bufferSizeInBytes</code> is less than the
358      *   minimum buffer size for the output sink, it is automatically increased to the minimum
359      *   buffer size.
360      *   The method {@link #getBufferSizeInFrames()} returns the
361      *   actual size in frames of the native buffer created, which
362      *   determines the frequency to write
363      *   to the streaming <code>AudioTrack</code> to avoid underrun.
364      * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
365      * @throws java.lang.IllegalArgumentException
366      */
AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode)367     public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
368             int bufferSizeInBytes, int mode)
369     throws IllegalArgumentException {
370         this(streamType, sampleRateInHz, channelConfig, audioFormat,
371                 bufferSizeInBytes, mode, AudioSystem.AUDIO_SESSION_ALLOCATE);
372     }
373 
374     /**
375      * Class constructor with audio session. Use this constructor when the AudioTrack must be
376      * attached to a particular audio session. The primary use of the audio session ID is to
377      * associate audio effects to a particular instance of AudioTrack: if an audio session ID
378      * is provided when creating an AudioEffect, this effect will be applied only to audio tracks
379      * and media players in the same session and not to the output mix.
380      * When an AudioTrack is created without specifying a session, it will create its own session
381      * which can be retrieved by calling the {@link #getAudioSessionId()} method.
382      * If a non-zero session ID is provided, this AudioTrack will share effects attached to this
383      * session
384      * with all other media players or audio tracks in the same session, otherwise a new session
385      * will be created for this track if none is supplied.
386      * @param streamType the type of the audio stream. See
387      *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
388      *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
389      *   {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
390      * @param sampleRateInHz the initial source sample rate expressed in Hz.
391      * @param channelConfig describes the configuration of the audio channels.
392      *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
393      *   {@link AudioFormat#CHANNEL_OUT_STEREO}
394      * @param audioFormat the format in which the audio data is represented.
395      *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
396      *   {@link AudioFormat#ENCODING_PCM_8BIT},
397      *   and {@link AudioFormat#ENCODING_PCM_FLOAT}.
398      * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read
399      *   from for playback. If using the AudioTrack in streaming mode, you can write data into
400      *   this buffer in smaller chunks than this size. If using the AudioTrack in static mode,
401      *   this is the maximum size of the sound that will be played for this instance.
402      *   See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size
403      *   for the successful creation of an AudioTrack instance in streaming mode. Using values
404      *   smaller than getMinBufferSize() will result in an initialization failure.
405      * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
406      * @param sessionId Id of audio session the AudioTrack must be attached to
407      * @throws java.lang.IllegalArgumentException
408      */
AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode, int sessionId)409     public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
410             int bufferSizeInBytes, int mode, int sessionId)
411     throws IllegalArgumentException {
412         // mState already == STATE_UNINITIALIZED
413         this((new AudioAttributes.Builder())
414                     .setLegacyStreamType(streamType)
415                     .build(),
416                 (new AudioFormat.Builder())
417                     .setChannelMask(channelConfig)
418                     .setEncoding(audioFormat)
419                     .setSampleRate(sampleRateInHz)
420                     .build(),
421                 bufferSizeInBytes,
422                 mode, sessionId);
423     }
424 
425     /**
426      * Class constructor with {@link AudioAttributes} and {@link AudioFormat}.
427      * @param attributes a non-null {@link AudioAttributes} instance.
428      * @param format a non-null {@link AudioFormat} instance describing the format of the data
429      *     that will be played through this AudioTrack. See {@link AudioFormat.Builder} for
430      *     configuring the audio format parameters such as encoding, channel mask and sample rate.
431      * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read
432      *   from for playback. If using the AudioTrack in streaming mode, you can write data into
433      *   this buffer in smaller chunks than this size. If using the AudioTrack in static mode,
434      *   this is the maximum size of the sound that will be played for this instance.
435      *   See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size
436      *   for the successful creation of an AudioTrack instance in streaming mode. Using values
437      *   smaller than getMinBufferSize() will result in an initialization failure.
438      * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}.
439      * @param sessionId ID of audio session the AudioTrack must be attached to, or
440      *   {@link AudioManager#AUDIO_SESSION_ID_GENERATE} if the session isn't known at construction
441      *   time. See also {@link AudioManager#generateAudioSessionId()} to obtain a session ID before
442      *   construction.
443      * @throws IllegalArgumentException
444      */
AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes, int mode, int sessionId)445     public AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
446             int mode, int sessionId)
447                     throws IllegalArgumentException {
448         // mState already == STATE_UNINITIALIZED
449 
450         if (attributes == null) {
451             throw new IllegalArgumentException("Illegal null AudioAttributes");
452         }
453         if (format == null) {
454             throw new IllegalArgumentException("Illegal null AudioFormat");
455         }
456 
457         // remember which looper is associated with the AudioTrack instantiation
458         Looper looper;
459         if ((looper = Looper.myLooper()) == null) {
460             looper = Looper.getMainLooper();
461         }
462 
463         int rate = 0;
464         if ((format.getPropertySetMask() & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) != 0)
465         {
466             rate = format.getSampleRate();
467         } else {
468             rate = AudioSystem.getPrimaryOutputSamplingRate();
469             if (rate <= 0) {
470                 rate = 44100;
471             }
472         }
473         int channelIndexMask = 0;
474         if ((format.getPropertySetMask()
475                 & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK) != 0) {
476             channelIndexMask = format.getChannelIndexMask();
477         }
478         int channelMask = 0;
479         if ((format.getPropertySetMask()
480                 & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) != 0) {
481             channelMask = format.getChannelMask();
482         } else if (channelIndexMask == 0) { // if no masks at all, use stereo
483             channelMask = AudioFormat.CHANNEL_OUT_FRONT_LEFT
484                     | AudioFormat.CHANNEL_OUT_FRONT_RIGHT;
485         }
486         int encoding = AudioFormat.ENCODING_DEFAULT;
487         if ((format.getPropertySetMask() & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_ENCODING) != 0) {
488             encoding = format.getEncoding();
489         }
490         audioParamCheck(rate, channelMask, channelIndexMask, encoding, mode);
491         mStreamType = AudioSystem.STREAM_DEFAULT;
492 
493         audioBuffSizeCheck(bufferSizeInBytes);
494 
495         mInitializationLooper = looper;
496         IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
497         mAppOps = IAppOpsService.Stub.asInterface(b);
498 
499         mAttributes = new AudioAttributes.Builder(attributes).build();
500 
501         if (sessionId < 0) {
502             throw new IllegalArgumentException("Invalid audio session ID: "+sessionId);
503         }
504 
505         int[] session = new int[1];
506         session[0] = sessionId;
507         // native initialization
508         int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes,
509                 mSampleRate, mChannelMask, mChannelIndexMask, mAudioFormat,
510                 mNativeBufferSizeInBytes, mDataLoadMode, session);
511         if (initResult != SUCCESS) {
512             loge("Error code "+initResult+" when initializing AudioTrack.");
513             return; // with mState == STATE_UNINITIALIZED
514         }
515 
516         mSessionId = session[0];
517 
518         if (mDataLoadMode == MODE_STATIC) {
519             mState = STATE_NO_STATIC_DATA;
520         } else {
521             mState = STATE_INITIALIZED;
522         }
523     }
524 
525     /**
526      * Builder class for {@link AudioTrack} objects.
527      * Use this class to configure and create an <code>AudioTrack</code> instance. By setting audio
528      * attributes and audio format parameters, you indicate which of those vary from the default
529      * behavior on the device.
530      * <p> Here is an example where <code>Builder</code> is used to specify all {@link AudioFormat}
531      * parameters, to be used by a new <code>AudioTrack</code> instance:
532      *
533      * <pre class="prettyprint">
534      * AudioTrack player = new AudioTrack.Builder()
535      *         .setAudioAttributes(new AudioAttributes.Builder()
536      *                  .setUsage(AudioAttributes.USAGE_ALARM)
537      *                  .setContentType(CONTENT_TYPE_MUSIC)
538      *                  .build())
539      *         .setAudioFormat(new AudioFormat.Builder()
540      *                 .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
541      *                 .setSampleRate(441000)
542      *                 .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
543      *                 .build())
544      *         .setBufferSize(minBuffSize)
545      *         .build();
546      * </pre>
547      * <p>
548      * If the audio attributes are not set with {@link #setAudioAttributes(AudioAttributes)},
549      * attributes comprising {@link AudioAttributes#USAGE_MEDIA} will be used.
550      * <br>If the audio format is not specified or is incomplete, its sample rate will be the
551      * default output sample rate of the device (see
552      * {@link AudioManager#PROPERTY_OUTPUT_SAMPLE_RATE}), its channel configuration will be
553      * {@link AudioFormat#CHANNEL_OUT_STEREO} and the encoding will be
554      * {@link AudioFormat#ENCODING_PCM_16BIT}.
555      * <br>If the buffer size is not specified with {@link #setBufferSizeInBytes(int)},
556      * and the mode is {@link AudioTrack#MODE_STREAM}, the minimum buffer size is used.
557      * <br>If the transfer mode is not specified with {@link #setTransferMode(int)},
558      * <code>MODE_STREAM</code> will be used.
559      * <br>If the session ID is not specified with {@link #setSessionId(int)}, a new one will
560      * be generated.
561      */
562     public static class Builder {
563         private AudioAttributes mAttributes;
564         private AudioFormat mFormat;
565         private int mBufferSizeInBytes;
566         private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
567         private int mMode = MODE_STREAM;
568 
569         /**
570          * Constructs a new Builder with the default values as described above.
571          */
Builder()572         public Builder() {
573         }
574 
575         /**
576          * Sets the {@link AudioAttributes}.
577          * @param attributes a non-null {@link AudioAttributes} instance that describes the audio
578          *     data to be played.
579          * @return the same Builder instance.
580          * @throws IllegalArgumentException
581          */
setAudioAttributes(@onNull AudioAttributes attributes)582         public @NonNull Builder setAudioAttributes(@NonNull AudioAttributes attributes)
583                 throws IllegalArgumentException {
584             if (attributes == null) {
585                 throw new IllegalArgumentException("Illegal null AudioAttributes argument");
586             }
587             // keep reference, we only copy the data when building
588             mAttributes = attributes;
589             return this;
590         }
591 
592         /**
593          * Sets the format of the audio data to be played by the {@link AudioTrack}.
594          * See {@link AudioFormat.Builder} for configuring the audio format parameters such
595          * as encoding, channel mask and sample rate.
596          * @param format a non-null {@link AudioFormat} instance.
597          * @return the same Builder instance.
598          * @throws IllegalArgumentException
599          */
setAudioFormat(@onNull AudioFormat format)600         public @NonNull Builder setAudioFormat(@NonNull AudioFormat format)
601                 throws IllegalArgumentException {
602             if (format == null) {
603                 throw new IllegalArgumentException("Illegal null AudioFormat argument");
604             }
605             // keep reference, we only copy the data when building
606             mFormat = format;
607             return this;
608         }
609 
610         /**
611          * Sets the total size (in bytes) of the buffer where audio data is read from for playback.
612          * If using the {@link AudioTrack} in streaming mode
613          * (see {@link AudioTrack#MODE_STREAM}, you can write data into this buffer in smaller
614          * chunks than this size. See {@link #getMinBufferSize(int, int, int)} to determine
615          * the minimum required buffer size for the successful creation of an AudioTrack instance
616          * in streaming mode. Using values smaller than <code>getMinBufferSize()</code> will result
617          * in an exception when trying to build the <code>AudioTrack</code>.
618          * <br>If using the <code>AudioTrack</code> in static mode (see
619          * {@link AudioTrack#MODE_STATIC}), this is the maximum size of the sound that will be
620          * played by this instance.
621          * @param bufferSizeInBytes
622          * @return the same Builder instance.
623          * @throws IllegalArgumentException
624          */
setBufferSizeInBytes(int bufferSizeInBytes)625         public @NonNull Builder setBufferSizeInBytes(int bufferSizeInBytes)
626                 throws IllegalArgumentException {
627             if (bufferSizeInBytes <= 0) {
628                 throw new IllegalArgumentException("Invalid buffer size " + bufferSizeInBytes);
629             }
630             mBufferSizeInBytes = bufferSizeInBytes;
631             return this;
632         }
633 
634         /**
635          * Sets the mode under which buffers of audio data are transferred from the
636          * {@link AudioTrack} to the framework.
637          * @param mode one of {@link AudioTrack#MODE_STREAM}, {@link AudioTrack#MODE_STATIC}.
638          * @return the same Builder instance.
639          * @throws IllegalArgumentException
640          */
setTransferMode(@ransferMode int mode)641         public @NonNull Builder setTransferMode(@TransferMode int mode)
642                 throws IllegalArgumentException {
643             switch(mode) {
644                 case MODE_STREAM:
645                 case MODE_STATIC:
646                     mMode = mode;
647                     break;
648                 default:
649                     throw new IllegalArgumentException("Invalid transfer mode " + mode);
650             }
651             return this;
652         }
653 
654         /**
655          * Sets the session ID the {@link AudioTrack} will be attached to.
656          * @param sessionId a strictly positive ID number retrieved from another
657          *     <code>AudioTrack</code> via {@link AudioTrack#getAudioSessionId()} or allocated by
658          *     {@link AudioManager} via {@link AudioManager#generateAudioSessionId()}, or
659          *     {@link AudioManager#AUDIO_SESSION_ID_GENERATE}.
660          * @return the same Builder instance.
661          * @throws IllegalArgumentException
662          */
setSessionId(int sessionId)663         public @NonNull Builder setSessionId(int sessionId)
664                 throws IllegalArgumentException {
665             if ((sessionId != AudioManager.AUDIO_SESSION_ID_GENERATE) && (sessionId < 1)) {
666                 throw new IllegalArgumentException("Invalid audio session ID " + sessionId);
667             }
668             mSessionId = sessionId;
669             return this;
670         }
671 
672         /**
673          * Builds an {@link AudioTrack} instance initialized with all the parameters set
674          * on this <code>Builder</code>.
675          * @return a new successfully initialized {@link AudioTrack} instance.
676          * @throws UnsupportedOperationException if the parameters set on the <code>Builder</code>
677          *     were incompatible, or if they are not supported by the device,
678          *     or if the device was not available.
679          */
build()680         public @NonNull AudioTrack build() throws UnsupportedOperationException {
681             if (mAttributes == null) {
682                 mAttributes = new AudioAttributes.Builder()
683                         .setUsage(AudioAttributes.USAGE_MEDIA)
684                         .build();
685             }
686             if (mFormat == null) {
687                 mFormat = new AudioFormat.Builder()
688                         .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
689                         .setSampleRate(AudioSystem.getPrimaryOutputSamplingRate())
690                         .setEncoding(AudioFormat.ENCODING_DEFAULT)
691                         .build();
692             }
693             try {
694                 // If the buffer size is not specified in streaming mode,
695                 // use a single frame for the buffer size and let the
696                 // native code figure out the minimum buffer size.
697                 if (mMode == MODE_STREAM && mBufferSizeInBytes == 0) {
698                     mBufferSizeInBytes = mFormat.getChannelCount()
699                             * mFormat.getBytesPerSample(mFormat.getEncoding());
700                 }
701                 final AudioTrack track = new AudioTrack(
702                         mAttributes, mFormat, mBufferSizeInBytes, mMode, mSessionId);
703                 if (track.getState() == STATE_UNINITIALIZED) {
704                     // release is not necessary
705                     throw new UnsupportedOperationException("Cannot create AudioTrack");
706                 }
707                 return track;
708             } catch (IllegalArgumentException e) {
709                 throw new UnsupportedOperationException(e.getMessage());
710             }
711         }
712     }
713 
714     // mask of all the positional channels supported, however the allowed combinations
715     // are further restricted by the matching left/right rule and CHANNEL_COUNT_MAX
716     private static final int SUPPORTED_OUT_CHANNELS =
717             AudioFormat.CHANNEL_OUT_FRONT_LEFT |
718             AudioFormat.CHANNEL_OUT_FRONT_RIGHT |
719             AudioFormat.CHANNEL_OUT_FRONT_CENTER |
720             AudioFormat.CHANNEL_OUT_LOW_FREQUENCY |
721             AudioFormat.CHANNEL_OUT_BACK_LEFT |
722             AudioFormat.CHANNEL_OUT_BACK_RIGHT |
723             AudioFormat.CHANNEL_OUT_BACK_CENTER |
724             AudioFormat.CHANNEL_OUT_SIDE_LEFT |
725             AudioFormat.CHANNEL_OUT_SIDE_RIGHT;
726 
727     // Convenience method for the constructor's parameter checks.
728     // This is where constructor IllegalArgumentException-s are thrown
729     // postconditions:
730     //    mChannelCount is valid
731     //    mChannelMask is valid
732     //    mAudioFormat is valid
733     //    mSampleRate is valid
734     //    mDataLoadMode is valid
audioParamCheck(int sampleRateInHz, int channelConfig, int channelIndexMask, int audioFormat, int mode)735     private void audioParamCheck(int sampleRateInHz, int channelConfig, int channelIndexMask,
736                                  int audioFormat, int mode) {
737         //--------------
738         // sample rate, note these values are subject to change
739         if (sampleRateInHz < SAMPLE_RATE_HZ_MIN || sampleRateInHz > SAMPLE_RATE_HZ_MAX) {
740             throw new IllegalArgumentException(sampleRateInHz
741                     + "Hz is not a supported sample rate.");
742         }
743         mSampleRate = sampleRateInHz;
744 
745         //--------------
746         // channel config
747         mChannelConfiguration = channelConfig;
748 
749         switch (channelConfig) {
750         case AudioFormat.CHANNEL_OUT_DEFAULT: //AudioFormat.CHANNEL_CONFIGURATION_DEFAULT
751         case AudioFormat.CHANNEL_OUT_MONO:
752         case AudioFormat.CHANNEL_CONFIGURATION_MONO:
753             mChannelCount = 1;
754             mChannelMask = AudioFormat.CHANNEL_OUT_MONO;
755             break;
756         case AudioFormat.CHANNEL_OUT_STEREO:
757         case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
758             mChannelCount = 2;
759             mChannelMask = AudioFormat.CHANNEL_OUT_STEREO;
760             break;
761         default:
762             if (channelConfig == AudioFormat.CHANNEL_INVALID && channelIndexMask != 0) {
763                 mChannelCount = 0;
764                 break; // channel index configuration only
765             }
766             if (!isMultichannelConfigSupported(channelConfig)) {
767                 // input channel configuration features unsupported channels
768                 throw new IllegalArgumentException("Unsupported channel configuration.");
769             }
770             mChannelMask = channelConfig;
771             mChannelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
772         }
773         // check the channel index configuration (if present)
774         mChannelIndexMask = channelIndexMask;
775         if (mChannelIndexMask != 0) {
776             // restrictive: indexMask could allow up to AUDIO_CHANNEL_BITS_LOG2
777             final int indexMask = (1 << CHANNEL_COUNT_MAX) - 1;
778             if ((channelIndexMask & ~indexMask) != 0) {
779                 throw new IllegalArgumentException("Unsupported channel index configuration "
780                         + channelIndexMask);
781             }
782             int channelIndexCount = Integer.bitCount(channelIndexMask);
783             if (mChannelCount == 0) {
784                  mChannelCount = channelIndexCount;
785             } else if (mChannelCount != channelIndexCount) {
786                 throw new IllegalArgumentException("Channel count must match");
787             }
788         }
789 
790         //--------------
791         // audio format
792         if (audioFormat == AudioFormat.ENCODING_DEFAULT) {
793             audioFormat = AudioFormat.ENCODING_PCM_16BIT;
794         }
795 
796         if (!AudioFormat.isPublicEncoding(audioFormat)) {
797             throw new IllegalArgumentException("Unsupported audio encoding.");
798         }
799         mAudioFormat = audioFormat;
800 
801         //--------------
802         // audio load mode
803         if (((mode != MODE_STREAM) && (mode != MODE_STATIC)) ||
804                 ((mode != MODE_STREAM) && !AudioFormat.isEncodingLinearPcm(mAudioFormat))) {
805             throw new IllegalArgumentException("Invalid mode.");
806         }
807         mDataLoadMode = mode;
808     }
809 
810     /**
811      * Convenience method to check that the channel configuration (a.k.a channel mask) is supported
812      * @param channelConfig the mask to validate
813      * @return false if the AudioTrack can't be used with such a mask
814      */
isMultichannelConfigSupported(int channelConfig)815     private static boolean isMultichannelConfigSupported(int channelConfig) {
816         // check for unsupported channels
817         if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) {
818             loge("Channel configuration features unsupported channels");
819             return false;
820         }
821         final int channelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
822         if (channelCount > CHANNEL_COUNT_MAX) {
823             loge("Channel configuration contains too many channels " +
824                     channelCount + ">" + CHANNEL_COUNT_MAX);
825             return false;
826         }
827         // check for unsupported multichannel combinations:
828         // - FL/FR must be present
829         // - L/R channels must be paired (e.g. no single L channel)
830         final int frontPair =
831                 AudioFormat.CHANNEL_OUT_FRONT_LEFT | AudioFormat.CHANNEL_OUT_FRONT_RIGHT;
832         if ((channelConfig & frontPair) != frontPair) {
833                 loge("Front channels must be present in multichannel configurations");
834                 return false;
835         }
836         final int backPair =
837                 AudioFormat.CHANNEL_OUT_BACK_LEFT | AudioFormat.CHANNEL_OUT_BACK_RIGHT;
838         if ((channelConfig & backPair) != 0) {
839             if ((channelConfig & backPair) != backPair) {
840                 loge("Rear channels can't be used independently");
841                 return false;
842             }
843         }
844         final int sidePair =
845                 AudioFormat.CHANNEL_OUT_SIDE_LEFT | AudioFormat.CHANNEL_OUT_SIDE_RIGHT;
846         if ((channelConfig & sidePair) != 0
847                 && (channelConfig & sidePair) != sidePair) {
848             loge("Side channels can't be used independently");
849             return false;
850         }
851         return true;
852     }
853 
854 
855     // Convenience method for the constructor's audio buffer size check.
856     // preconditions:
857     //    mChannelCount is valid
858     //    mAudioFormat is valid
859     // postcondition:
860     //    mNativeBufferSizeInBytes is valid (multiple of frame size, positive)
audioBuffSizeCheck(int audioBufferSize)861     private void audioBuffSizeCheck(int audioBufferSize) {
862         // NB: this section is only valid with PCM data.
863         //     To update when supporting compressed formats
864         int frameSizeInBytes;
865         if (AudioFormat.isEncodingLinearPcm(mAudioFormat)) {
866             frameSizeInBytes = mChannelCount * AudioFormat.getBytesPerSample(mAudioFormat);
867         } else {
868             frameSizeInBytes = 1;
869         }
870         if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
871             throw new IllegalArgumentException("Invalid audio buffer size.");
872         }
873 
874         mNativeBufferSizeInBytes = audioBufferSize;
875         mNativeBufferSizeInFrames = audioBufferSize / frameSizeInBytes;
876     }
877 
878 
879     /**
880      * Releases the native AudioTrack resources.
881      */
release()882     public void release() {
883         // even though native_release() stops the native AudioTrack, we need to stop
884         // AudioTrack subclasses too.
885         try {
886             stop();
887         } catch(IllegalStateException ise) {
888             // don't raise an exception, we're releasing the resources.
889         }
890         native_release();
891         mState = STATE_UNINITIALIZED;
892     }
893 
894     @Override
finalize()895     protected void finalize() {
896         native_finalize();
897     }
898 
899     //--------------------------------------------------------------------------
900     // Getters
901     //--------------------
902     /**
903      * Returns the minimum gain value, which is the constant 0.0.
904      * Gain values less than 0.0 will be clamped to 0.0.
905      * <p>The word "volume" in the API name is historical; this is actually a linear gain.
906      * @return the minimum value, which is the constant 0.0.
907      */
getMinVolume()908     static public float getMinVolume() {
909         return GAIN_MIN;
910     }
911 
912     /**
913      * Returns the maximum gain value, which is greater than or equal to 1.0.
914      * Gain values greater than the maximum will be clamped to the maximum.
915      * <p>The word "volume" in the API name is historical; this is actually a gain.
916      * expressed as a linear multiplier on sample values, where a maximum value of 1.0
917      * corresponds to a gain of 0 dB (sample values left unmodified).
918      * @return the maximum value, which is greater than or equal to 1.0.
919      */
getMaxVolume()920     static public float getMaxVolume() {
921         return GAIN_MAX;
922     }
923 
924     /**
925      * Returns the configured audio data sample rate in Hz
926      */
getSampleRate()927     public int getSampleRate() {
928         return mSampleRate;
929     }
930 
931     /**
932      * Returns the current playback sample rate rate in Hz.
933      */
getPlaybackRate()934     public int getPlaybackRate() {
935         return native_get_playback_rate();
936     }
937 
938     /**
939      * Returns the current playback parameters.
940      * See {@link #setPlaybackParams(PlaybackParams)} to set playback parameters
941      * @return current {@link PlaybackParams}.
942      * @throws IllegalStateException if track is not initialized.
943      */
getPlaybackParams()944     public @NonNull PlaybackParams getPlaybackParams() {
945         return native_get_playback_params();
946     }
947 
948     /**
949      * Returns the configured audio data encoding. See {@link AudioFormat#ENCODING_PCM_8BIT},
950      * {@link AudioFormat#ENCODING_PCM_16BIT}, and {@link AudioFormat#ENCODING_PCM_FLOAT}.
951      */
getAudioFormat()952     public int getAudioFormat() {
953         return mAudioFormat;
954     }
955 
956     /**
957      * Returns the type of audio stream this AudioTrack is configured for.
958      * Compare the result against {@link AudioManager#STREAM_VOICE_CALL},
959      * {@link AudioManager#STREAM_SYSTEM}, {@link AudioManager#STREAM_RING},
960      * {@link AudioManager#STREAM_MUSIC}, {@link AudioManager#STREAM_ALARM},
961      * {@link AudioManager#STREAM_NOTIFICATION}, or {@link AudioManager#STREAM_DTMF}.
962      */
getStreamType()963     public int getStreamType() {
964         return mStreamType;
965     }
966 
967     /**
968      * Returns the configured channel position mask.
969      * <p> For example, refer to {@link AudioFormat#CHANNEL_OUT_MONO},
970      * {@link AudioFormat#CHANNEL_OUT_STEREO}, {@link AudioFormat#CHANNEL_OUT_5POINT1}.
971      * This method may return {@link AudioFormat#CHANNEL_INVALID} if
972      * a channel index mask was used. Consider
973      * {@link #getFormat()} instead, to obtain an {@link AudioFormat},
974      * which contains both the channel position mask and the channel index mask.
975      */
getChannelConfiguration()976     public int getChannelConfiguration() {
977         return mChannelConfiguration;
978     }
979 
980     /**
981      * Returns the configured <code>AudioTrack</code> format.
982      * @return an {@link AudioFormat} containing the
983      * <code>AudioTrack</code> parameters at the time of configuration.
984      */
getFormat()985     public @NonNull AudioFormat getFormat() {
986         AudioFormat.Builder builder = new AudioFormat.Builder()
987             .setSampleRate(mSampleRate)
988             .setEncoding(mAudioFormat);
989         if (mChannelConfiguration != AudioFormat.CHANNEL_INVALID) {
990             builder.setChannelMask(mChannelConfiguration);
991         }
992         if (mChannelIndexMask != AudioFormat.CHANNEL_INVALID /* 0 */) {
993             builder.setChannelIndexMask(mChannelIndexMask);
994         }
995         return builder.build();
996     }
997 
998     /**
999      * Returns the configured number of channels.
1000      */
getChannelCount()1001     public int getChannelCount() {
1002         return mChannelCount;
1003     }
1004 
1005     /**
1006      * Returns the state of the AudioTrack instance. This is useful after the
1007      * AudioTrack instance has been created to check if it was initialized
1008      * properly. This ensures that the appropriate resources have been acquired.
1009      * @see #STATE_UNINITIALIZED
1010      * @see #STATE_INITIALIZED
1011      * @see #STATE_NO_STATIC_DATA
1012      */
getState()1013     public int getState() {
1014         return mState;
1015     }
1016 
1017     /**
1018      * Returns the playback state of the AudioTrack instance.
1019      * @see #PLAYSTATE_STOPPED
1020      * @see #PLAYSTATE_PAUSED
1021      * @see #PLAYSTATE_PLAYING
1022      */
getPlayState()1023     public int getPlayState() {
1024         synchronized (mPlayStateLock) {
1025             return mPlayState;
1026         }
1027     }
1028 
1029     /**
1030      *  Returns the frame count of the native <code>AudioTrack</code> buffer.
1031      *  <p> If the track's creation mode is {@link #MODE_STATIC},
1032      *  it is equal to the specified bufferSizeInBytes on construction, converted to frame units.
1033      *  A static track's native frame count will not change.
1034      *  <p> If the track's creation mode is {@link #MODE_STREAM},
1035      *  it is greater than or equal to the specified bufferSizeInBytes converted to frame units.
1036      *  For streaming tracks, this value may be rounded up to a larger value if needed by
1037      *  the target output sink, and
1038      *  if the track is subsequently routed to a different output sink, the native
1039      *  frame count may enlarge to accommodate.
1040      *  <p> If the <code>AudioTrack</code> encoding indicates compressed data,
1041      *  e.g. {@link AudioFormat#ENCODING_AC3}, then the frame count returned is
1042      *  the size of the native <code>AudioTrack</code> buffer in bytes.
1043      *  <p> See also {@link AudioManager#getProperty(String)} for key
1044      *  {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
1045      *  @return current size in frames of the <code>AudioTrack</code> buffer.
1046      *  @throws IllegalStateException
1047      */
getBufferSizeInFrames()1048     public int getBufferSizeInFrames() {
1049         return native_get_native_frame_count();
1050     }
1051 
1052     /**
1053      *  Returns the frame count of the native <code>AudioTrack</code> buffer.
1054      *  @return current size in frames of the <code>AudioTrack</code> buffer.
1055      *  @throws IllegalStateException
1056      *  @deprecated Use the identical public method {@link #getBufferSizeInFrames()} instead.
1057      */
1058     @Deprecated
getNativeFrameCount()1059     protected int getNativeFrameCount() {
1060         return native_get_native_frame_count();
1061     }
1062 
1063     /**
1064      * Returns marker position expressed in frames.
1065      * @return marker position in wrapping frame units similar to {@link #getPlaybackHeadPosition},
1066      * or zero if marker is disabled.
1067      */
getNotificationMarkerPosition()1068     public int getNotificationMarkerPosition() {
1069         return native_get_marker_pos();
1070     }
1071 
1072     /**
1073      * Returns the notification update period expressed in frames.
1074      * Zero means that no position update notifications are being delivered.
1075      */
getPositionNotificationPeriod()1076     public int getPositionNotificationPeriod() {
1077         return native_get_pos_update_period();
1078     }
1079 
1080     /**
1081      * Returns the playback head position expressed in frames.
1082      * Though the "int" type is signed 32-bits, the value should be reinterpreted as if it is
1083      * unsigned 32-bits.  That is, the next position after 0x7FFFFFFF is (int) 0x80000000.
1084      * This is a continuously advancing counter.  It will wrap (overflow) periodically,
1085      * for example approximately once every 27:03:11 hours:minutes:seconds at 44.1 kHz.
1086      * It is reset to zero by {@link #flush()}, {@link #reloadStaticData()}, and {@link #stop()}.
1087      * If the track's creation mode is {@link #MODE_STATIC}, the return value indicates
1088      * the total number of frames played since reset,
1089      * <i>not</i> the current offset within the buffer.
1090      */
getPlaybackHeadPosition()1091     public int getPlaybackHeadPosition() {
1092         return native_get_position();
1093     }
1094 
1095     /**
1096      * Returns this track's estimated latency in milliseconds. This includes the latency due
1097      * to AudioTrack buffer size, AudioMixer (if any) and audio hardware driver.
1098      *
1099      * DO NOT UNHIDE. The existing approach for doing A/V sync has too many problems. We need
1100      * a better solution.
1101      * @hide
1102      */
getLatency()1103     public int getLatency() {
1104         return native_get_latency();
1105     }
1106 
1107     /**
1108      *  Returns the output sample rate in Hz for the specified stream type.
1109      */
getNativeOutputSampleRate(int streamType)1110     static public int getNativeOutputSampleRate(int streamType) {
1111         return native_get_output_sample_rate(streamType);
1112     }
1113 
1114     /**
1115      * Returns the minimum buffer size required for the successful creation of an AudioTrack
1116      * object to be created in the {@link #MODE_STREAM} mode. Note that this size doesn't
1117      * guarantee a smooth playback under load, and higher values should be chosen according to
1118      * the expected frequency at which the buffer will be refilled with additional data to play.
1119      * For example, if you intend to dynamically set the source sample rate of an AudioTrack
1120      * to a higher value than the initial source sample rate, be sure to configure the buffer size
1121      * based on the highest planned sample rate.
1122      * @param sampleRateInHz the source sample rate expressed in Hz.
1123      * @param channelConfig describes the configuration of the audio channels.
1124      *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
1125      *   {@link AudioFormat#CHANNEL_OUT_STEREO}
1126      * @param audioFormat the format in which the audio data is represented.
1127      *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
1128      *   {@link AudioFormat#ENCODING_PCM_8BIT},
1129      *   and {@link AudioFormat#ENCODING_PCM_FLOAT}.
1130      * @return {@link #ERROR_BAD_VALUE} if an invalid parameter was passed,
1131      *   or {@link #ERROR} if unable to query for output properties,
1132      *   or the minimum buffer size expressed in bytes.
1133      */
getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat)1134     static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
1135         int channelCount = 0;
1136         switch(channelConfig) {
1137         case AudioFormat.CHANNEL_OUT_MONO:
1138         case AudioFormat.CHANNEL_CONFIGURATION_MONO:
1139             channelCount = 1;
1140             break;
1141         case AudioFormat.CHANNEL_OUT_STEREO:
1142         case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
1143             channelCount = 2;
1144             break;
1145         default:
1146             if (!isMultichannelConfigSupported(channelConfig)) {
1147                 loge("getMinBufferSize(): Invalid channel configuration.");
1148                 return ERROR_BAD_VALUE;
1149             } else {
1150                 channelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
1151             }
1152         }
1153 
1154         if (!AudioFormat.isPublicEncoding(audioFormat)) {
1155             loge("getMinBufferSize(): Invalid audio format.");
1156             return ERROR_BAD_VALUE;
1157         }
1158 
1159         // sample rate, note these values are subject to change
1160         if ( (sampleRateInHz < SAMPLE_RATE_HZ_MIN) || (sampleRateInHz > SAMPLE_RATE_HZ_MAX) ) {
1161             loge("getMinBufferSize(): " + sampleRateInHz + " Hz is not a supported sample rate.");
1162             return ERROR_BAD_VALUE;
1163         }
1164 
1165         int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
1166         if (size <= 0) {
1167             loge("getMinBufferSize(): error querying hardware");
1168             return ERROR;
1169         }
1170         else {
1171             return size;
1172         }
1173     }
1174 
1175     /**
1176      * Returns the audio session ID.
1177      *
1178      * @return the ID of the audio session this AudioTrack belongs to.
1179      */
getAudioSessionId()1180     public int getAudioSessionId() {
1181         return mSessionId;
1182     }
1183 
1184    /**
1185     * Poll for a timestamp on demand.
1186     * <p>
1187     * If you need to track timestamps during initial warmup or after a routing or mode change,
1188     * you should request a new timestamp periodically until the reported timestamps
1189     * show that the frame position is advancing, or until it becomes clear that
1190     * timestamps are unavailable for this route.
1191     * <p>
1192     * After the clock is advancing at a stable rate,
1193     * query for a new timestamp approximately once every 10 seconds to once per minute.
1194     * Calling this method more often is inefficient.
1195     * It is also counter-productive to call this method more often than recommended,
1196     * because the short-term differences between successive timestamp reports are not meaningful.
1197     * If you need a high-resolution mapping between frame position and presentation time,
1198     * consider implementing that at application level, based on low-resolution timestamps.
1199     * <p>
1200     * The audio data at the returned position may either already have been
1201     * presented, or may have not yet been presented but is committed to be presented.
1202     * It is not possible to request the time corresponding to a particular position,
1203     * or to request the (fractional) position corresponding to a particular time.
1204     * If you need such features, consider implementing them at application level.
1205     *
1206     * @param timestamp a reference to a non-null AudioTimestamp instance allocated
1207     *        and owned by caller.
1208     * @return true if a timestamp is available, or false if no timestamp is available.
1209     *         If a timestamp if available,
1210     *         the AudioTimestamp instance is filled in with a position in frame units, together
1211     *         with the estimated time when that frame was presented or is committed to
1212     *         be presented.
1213     *         In the case that no timestamp is available, any supplied instance is left unaltered.
1214     *         A timestamp may be temporarily unavailable while the audio clock is stabilizing,
1215     *         or during and immediately after a route change.
1216     *         A timestamp is permanently unavailable for a given route if the route does not support
1217     *         timestamps.  In this case, the approximate frame position can be obtained
1218     *         using {@link #getPlaybackHeadPosition}.
1219     *         However, it may be useful to continue to query for
1220     *         timestamps occasionally, to recover after a route change.
1221     */
1222     // Add this text when the "on new timestamp" API is added:
1223     //   Use if you need to get the most recent timestamp outside of the event callback handler.
getTimestamp(AudioTimestamp timestamp)1224     public boolean getTimestamp(AudioTimestamp timestamp)
1225     {
1226         if (timestamp == null) {
1227             throw new IllegalArgumentException();
1228         }
1229         // It's unfortunate, but we have to either create garbage every time or use synchronized
1230         long[] longArray = new long[2];
1231         int ret = native_get_timestamp(longArray);
1232         if (ret != SUCCESS) {
1233             return false;
1234         }
1235         timestamp.framePosition = longArray[0];
1236         timestamp.nanoTime = longArray[1];
1237         return true;
1238     }
1239 
1240     /**
1241      * Poll for a timestamp on demand.
1242      * <p>
1243      * Same as {@link #getTimestamp(AudioTimestamp)} but with a more useful return code.
1244      *
1245      * @param timestamp a reference to a non-null AudioTimestamp instance allocated
1246      *        and owned by caller.
1247      * @return {@link #SUCCESS} if a timestamp is available
1248      *         {@link #ERROR_WOULD_BLOCK} if called in STOPPED or FLUSHED state, or if called
1249      *         immediately after start/ACTIVE, when the number of frames consumed is less than the
1250      *         overall hardware latency to physical output. In WOULD_BLOCK cases, one might poll
1251      *         again, or use {@link #getPlaybackHeadPosition}, or use 0 position and current time
1252      *         for the timestamp.
1253      *         {@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
1254      *         needs to be recreated.
1255      *         {@link #ERROR_INVALID_OPERATION} if current route does not support
1256      *         timestamps. In this case, the approximate frame position can be obtained
1257      *         using {@link #getPlaybackHeadPosition}.
1258      *
1259      *         The AudioTimestamp instance is filled in with a position in frame units, together
1260      *         with the estimated time when that frame was presented or is committed to
1261      *         be presented.
1262      * @hide
1263      */
1264      // Add this text when the "on new timestamp" API is added:
1265      //   Use if you need to get the most recent timestamp outside of the event callback handler.
getTimestampWithStatus(AudioTimestamp timestamp)1266      public int getTimestampWithStatus(AudioTimestamp timestamp)
1267      {
1268          if (timestamp == null) {
1269              throw new IllegalArgumentException();
1270          }
1271          // It's unfortunate, but we have to either create garbage every time or use synchronized
1272          long[] longArray = new long[2];
1273          int ret = native_get_timestamp(longArray);
1274          timestamp.framePosition = longArray[0];
1275          timestamp.nanoTime = longArray[1];
1276          return ret;
1277      }
1278 
1279     //--------------------------------------------------------------------------
1280     // Initialization / configuration
1281     //--------------------
1282     /**
1283      * Sets the listener the AudioTrack notifies when a previously set marker is reached or
1284      * for each periodic playback head position update.
1285      * Notifications will be received in the same thread as the one in which the AudioTrack
1286      * instance was created.
1287      * @param listener
1288      */
setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener)1289     public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener) {
1290         setPlaybackPositionUpdateListener(listener, null);
1291     }
1292 
1293     /**
1294      * Sets the listener the AudioTrack notifies when a previously set marker is reached or
1295      * for each periodic playback head position update.
1296      * Use this method to receive AudioTrack events in the Handler associated with another
1297      * thread than the one in which you created the AudioTrack instance.
1298      * @param listener
1299      * @param handler the Handler that will receive the event notification messages.
1300      */
setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener, Handler handler)1301     public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener,
1302                                                     Handler handler) {
1303         if (listener != null) {
1304             mEventHandlerDelegate = new NativePositionEventHandlerDelegate(this, listener, handler);
1305         } else {
1306             mEventHandlerDelegate = null;
1307         }
1308     }
1309 
1310 
clampGainOrLevel(float gainOrLevel)1311     private static float clampGainOrLevel(float gainOrLevel) {
1312         if (Float.isNaN(gainOrLevel)) {
1313             throw new IllegalArgumentException();
1314         }
1315         if (gainOrLevel < GAIN_MIN) {
1316             gainOrLevel = GAIN_MIN;
1317         } else if (gainOrLevel > GAIN_MAX) {
1318             gainOrLevel = GAIN_MAX;
1319         }
1320         return gainOrLevel;
1321     }
1322 
1323 
1324      /**
1325      * Sets the specified left and right output gain values on the AudioTrack.
1326      * <p>Gain values are clamped to the closed interval [0.0, max] where
1327      * max is the value of {@link #getMaxVolume}.
1328      * A value of 0.0 results in zero gain (silence), and
1329      * a value of 1.0 means unity gain (signal unchanged).
1330      * The default value is 1.0 meaning unity gain.
1331      * <p>The word "volume" in the API name is historical; this is actually a linear gain.
1332      * @param leftGain output gain for the left channel.
1333      * @param rightGain output gain for the right channel
1334      * @return error code or success, see {@link #SUCCESS},
1335      *    {@link #ERROR_INVALID_OPERATION}
1336      * @deprecated Applications should use {@link #setVolume} instead, as it
1337      * more gracefully scales down to mono, and up to multi-channel content beyond stereo.
1338      */
setStereoVolume(float leftGain, float rightGain)1339     public int setStereoVolume(float leftGain, float rightGain) {
1340         if (isRestricted()) {
1341             return SUCCESS;
1342         }
1343         if (mState == STATE_UNINITIALIZED) {
1344             return ERROR_INVALID_OPERATION;
1345         }
1346 
1347         leftGain = clampGainOrLevel(leftGain);
1348         rightGain = clampGainOrLevel(rightGain);
1349 
1350         native_setVolume(leftGain, rightGain);
1351 
1352         return SUCCESS;
1353     }
1354 
1355 
1356     /**
1357      * Sets the specified output gain value on all channels of this track.
1358      * <p>Gain values are clamped to the closed interval [0.0, max] where
1359      * max is the value of {@link #getMaxVolume}.
1360      * A value of 0.0 results in zero gain (silence), and
1361      * a value of 1.0 means unity gain (signal unchanged).
1362      * The default value is 1.0 meaning unity gain.
1363      * <p>This API is preferred over {@link #setStereoVolume}, as it
1364      * more gracefully scales down to mono, and up to multi-channel content beyond stereo.
1365      * <p>The word "volume" in the API name is historical; this is actually a linear gain.
1366      * @param gain output gain for all channels.
1367      * @return error code or success, see {@link #SUCCESS},
1368      *    {@link #ERROR_INVALID_OPERATION}
1369      */
setVolume(float gain)1370     public int setVolume(float gain) {
1371         return setStereoVolume(gain, gain);
1372     }
1373 
1374 
1375     /**
1376      * Sets the playback sample rate for this track. This sets the sampling rate at which
1377      * the audio data will be consumed and played back
1378      * (as set by the sampleRateInHz parameter in the
1379      * {@link #AudioTrack(int, int, int, int, int, int)} constructor),
1380      * not the original sampling rate of the
1381      * content. For example, setting it to half the sample rate of the content will cause the
1382      * playback to last twice as long, but will also result in a pitch shift down by one octave.
1383      * The valid sample rate range is from 1 Hz to twice the value returned by
1384      * {@link #getNativeOutputSampleRate(int)}.
1385      * Use {@link #setPlaybackParams(PlaybackParams)} for speed control.
1386      * <p> This method may also be used to repurpose an existing <code>AudioTrack</code>
1387      * for playback of content of differing sample rate,
1388      * but with identical encoding and channel mask.
1389      * @param sampleRateInHz the sample rate expressed in Hz
1390      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
1391      *    {@link #ERROR_INVALID_OPERATION}
1392      */
setPlaybackRate(int sampleRateInHz)1393     public int setPlaybackRate(int sampleRateInHz) {
1394         if (mState != STATE_INITIALIZED) {
1395             return ERROR_INVALID_OPERATION;
1396         }
1397         if (sampleRateInHz <= 0) {
1398             return ERROR_BAD_VALUE;
1399         }
1400         return native_set_playback_rate(sampleRateInHz);
1401     }
1402 
1403 
1404     /**
1405      * Sets the playback parameters.
1406      * This method returns failure if it cannot apply the playback parameters.
1407      * One possible cause is that the parameters for speed or pitch are out of range.
1408      * Another possible cause is that the <code>AudioTrack</code> is streaming
1409      * (see {@link #MODE_STREAM}) and the
1410      * buffer size is too small. For speeds greater than 1.0f, the <code>AudioTrack</code> buffer
1411      * on configuration must be larger than the speed multiplied by the minimum size
1412      * {@link #getMinBufferSize(int, int, int)}) to allow proper playback.
1413      * @param params see {@link PlaybackParams}. In particular,
1414      * speed, pitch, and audio mode should be set.
1415      * @throws IllegalArgumentException if the parameters are invalid or not accepted.
1416      * @throws IllegalStateException if track is not initialized.
1417      */
setPlaybackParams(@onNull PlaybackParams params)1418     public void setPlaybackParams(@NonNull PlaybackParams params) {
1419         if (params == null) {
1420             throw new IllegalArgumentException("params is null");
1421         }
1422         native_set_playback_params(params);
1423     }
1424 
1425 
1426     /**
1427      * Sets the position of the notification marker.  At most one marker can be active.
1428      * @param markerInFrames marker position in wrapping frame units similar to
1429      * {@link #getPlaybackHeadPosition}, or zero to disable the marker.
1430      * To set a marker at a position which would appear as zero due to wraparound,
1431      * a workaround is to use a non-zero position near zero, such as -1 or 1.
1432      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
1433      *  {@link #ERROR_INVALID_OPERATION}
1434      */
setNotificationMarkerPosition(int markerInFrames)1435     public int setNotificationMarkerPosition(int markerInFrames) {
1436         if (mState == STATE_UNINITIALIZED) {
1437             return ERROR_INVALID_OPERATION;
1438         }
1439         return native_set_marker_pos(markerInFrames);
1440     }
1441 
1442 
1443     /**
1444      * Sets the period for the periodic notification event.
1445      * @param periodInFrames update period expressed in frames.
1446      * Zero period means no position updates.  A negative period is not allowed.
1447      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION}
1448      */
setPositionNotificationPeriod(int periodInFrames)1449     public int setPositionNotificationPeriod(int periodInFrames) {
1450         if (mState == STATE_UNINITIALIZED) {
1451             return ERROR_INVALID_OPERATION;
1452         }
1453         return native_set_pos_update_period(periodInFrames);
1454     }
1455 
1456 
1457     /**
1458      * Sets the playback head position within the static buffer.
1459      * The track must be stopped or paused for the position to be changed,
1460      * and must use the {@link #MODE_STATIC} mode.
1461      * @param positionInFrames playback head position within buffer, expressed in frames.
1462      * Zero corresponds to start of buffer.
1463      * The position must not be greater than the buffer size in frames, or negative.
1464      * Though this method and {@link #getPlaybackHeadPosition()} have similar names,
1465      * the position values have different meanings.
1466      * <br>
1467      * If looping is currently enabled and the new position is greater than or equal to the
1468      * loop end marker, the behavior varies by API level:
1469      * as of {@link android.os.Build.VERSION_CODES#M},
1470      * the looping is first disabled and then the position is set.
1471      * For earlier API levels, the behavior is unspecified.
1472      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
1473      *    {@link #ERROR_INVALID_OPERATION}
1474      */
setPlaybackHeadPosition(int positionInFrames)1475     public int setPlaybackHeadPosition(int positionInFrames) {
1476         if (mDataLoadMode == MODE_STREAM || mState == STATE_UNINITIALIZED ||
1477                 getPlayState() == PLAYSTATE_PLAYING) {
1478             return ERROR_INVALID_OPERATION;
1479         }
1480         if (!(0 <= positionInFrames && positionInFrames <= mNativeBufferSizeInFrames)) {
1481             return ERROR_BAD_VALUE;
1482         }
1483         return native_set_position(positionInFrames);
1484     }
1485 
1486     /**
1487      * Sets the loop points and the loop count. The loop can be infinite.
1488      * Similarly to setPlaybackHeadPosition,
1489      * the track must be stopped or paused for the loop points to be changed,
1490      * and must use the {@link #MODE_STATIC} mode.
1491      * @param startInFrames loop start marker expressed in frames.
1492      * Zero corresponds to start of buffer.
1493      * The start marker must not be greater than or equal to the buffer size in frames, or negative.
1494      * @param endInFrames loop end marker expressed in frames.
1495      * The total buffer size in frames corresponds to end of buffer.
1496      * The end marker must not be greater than the buffer size in frames.
1497      * For looping, the end marker must not be less than or equal to the start marker,
1498      * but to disable looping
1499      * it is permitted for start marker, end marker, and loop count to all be 0.
1500      * If any input parameters are out of range, this method returns {@link #ERROR_BAD_VALUE}.
1501      * If the loop period (endInFrames - startInFrames) is too small for the implementation to
1502      * support,
1503      * {@link #ERROR_BAD_VALUE} is returned.
1504      * The loop range is the interval [startInFrames, endInFrames).
1505      * <br>
1506      * As of {@link android.os.Build.VERSION_CODES#M}, the position is left unchanged,
1507      * unless it is greater than or equal to the loop end marker, in which case
1508      * it is forced to the loop start marker.
1509      * For earlier API levels, the effect on position is unspecified.
1510      * @param loopCount the number of times the loop is looped; must be greater than or equal to -1.
1511      *    A value of -1 means infinite looping, and 0 disables looping.
1512      *    A value of positive N means to "loop" (go back) N times.  For example,
1513      *    a value of one means to play the region two times in total.
1514      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
1515      *    {@link #ERROR_INVALID_OPERATION}
1516      */
setLoopPoints(int startInFrames, int endInFrames, int loopCount)1517     public int setLoopPoints(int startInFrames, int endInFrames, int loopCount) {
1518         if (mDataLoadMode == MODE_STREAM || mState == STATE_UNINITIALIZED ||
1519                 getPlayState() == PLAYSTATE_PLAYING) {
1520             return ERROR_INVALID_OPERATION;
1521         }
1522         if (loopCount == 0) {
1523             ;   // explicitly allowed as an exception to the loop region range check
1524         } else if (!(0 <= startInFrames && startInFrames < mNativeBufferSizeInFrames &&
1525                 startInFrames < endInFrames && endInFrames <= mNativeBufferSizeInFrames)) {
1526             return ERROR_BAD_VALUE;
1527         }
1528         return native_set_loop(startInFrames, endInFrames, loopCount);
1529     }
1530 
1531     /**
1532      * Sets the initialization state of the instance. This method was originally intended to be used
1533      * in an AudioTrack subclass constructor to set a subclass-specific post-initialization state.
1534      * However, subclasses of AudioTrack are no longer recommended, so this method is obsolete.
1535      * @param state the state of the AudioTrack instance
1536      * @deprecated Only accessible by subclasses, which are not recommended for AudioTrack.
1537      */
1538     @Deprecated
setState(int state)1539     protected void setState(int state) {
1540         mState = state;
1541     }
1542 
1543 
1544     //---------------------------------------------------------
1545     // Transport control methods
1546     //--------------------
1547     /**
1548      * Starts playing an AudioTrack.
1549      * <p>
1550      * If track's creation mode is {@link #MODE_STATIC}, you must have called one of
1551      * the write methods ({@link #write(byte[], int, int)}, {@link #write(byte[], int, int, int)},
1552      * {@link #write(short[], int, int)}, {@link #write(short[], int, int, int)},
1553      * {@link #write(float[], int, int, int)}, or {@link #write(ByteBuffer, int, int)}) prior to
1554      * play().
1555      * <p>
1556      * If the mode is {@link #MODE_STREAM}, you can optionally prime the data path prior to
1557      * calling play(), by writing up to <code>bufferSizeInBytes</code> (from constructor).
1558      * If you don't call write() first, or if you call write() but with an insufficient amount of
1559      * data, then the track will be in underrun state at play().  In this case,
1560      * playback will not actually start playing until the data path is filled to a
1561      * device-specific minimum level.  This requirement for the path to be filled
1562      * to a minimum level is also true when resuming audio playback after calling stop().
1563      * Similarly the buffer will need to be filled up again after
1564      * the track underruns due to failure to call write() in a timely manner with sufficient data.
1565      * For portability, an application should prime the data path to the maximum allowed
1566      * by writing data until the write() method returns a short transfer count.
1567      * This allows play() to start immediately, and reduces the chance of underrun.
1568      *
1569      * @throws IllegalStateException if the track isn't properly initialized
1570      */
play()1571     public void play()
1572     throws IllegalStateException {
1573         if (mState != STATE_INITIALIZED) {
1574             throw new IllegalStateException("play() called on uninitialized AudioTrack.");
1575         }
1576         if (isRestricted()) {
1577             setVolume(0);
1578         }
1579         synchronized(mPlayStateLock) {
1580             native_start();
1581             mPlayState = PLAYSTATE_PLAYING;
1582         }
1583     }
1584 
isRestricted()1585     private boolean isRestricted() {
1586         if ((mAttributes.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) {
1587             return false;
1588         }
1589         try {
1590             final int usage = AudioAttributes.usageForLegacyStreamType(mStreamType);
1591             final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, usage,
1592                     Process.myUid(), ActivityThread.currentPackageName());
1593             return mode != AppOpsManager.MODE_ALLOWED;
1594         } catch (RemoteException e) {
1595             return false;
1596         }
1597     }
1598 
1599     /**
1600      * Stops playing the audio data.
1601      * When used on an instance created in {@link #MODE_STREAM} mode, audio will stop playing
1602      * after the last buffer that was written has been played. For an immediate stop, use
1603      * {@link #pause()}, followed by {@link #flush()} to discard audio data that hasn't been played
1604      * back yet.
1605      * @throws IllegalStateException
1606      */
stop()1607     public void stop()
1608     throws IllegalStateException {
1609         if (mState != STATE_INITIALIZED) {
1610             throw new IllegalStateException("stop() called on uninitialized AudioTrack.");
1611         }
1612 
1613         // stop playing
1614         synchronized(mPlayStateLock) {
1615             native_stop();
1616             mPlayState = PLAYSTATE_STOPPED;
1617             mAvSyncHeader = null;
1618             mAvSyncBytesRemaining = 0;
1619         }
1620     }
1621 
1622     /**
1623      * Pauses the playback of the audio data. Data that has not been played
1624      * back will not be discarded. Subsequent calls to {@link #play} will play
1625      * this data back. See {@link #flush()} to discard this data.
1626      *
1627      * @throws IllegalStateException
1628      */
pause()1629     public void pause()
1630     throws IllegalStateException {
1631         if (mState != STATE_INITIALIZED) {
1632             throw new IllegalStateException("pause() called on uninitialized AudioTrack.");
1633         }
1634         //logd("pause()");
1635 
1636         // pause playback
1637         synchronized(mPlayStateLock) {
1638             native_pause();
1639             mPlayState = PLAYSTATE_PAUSED;
1640         }
1641     }
1642 
1643 
1644     //---------------------------------------------------------
1645     // Audio data supply
1646     //--------------------
1647 
1648     /**
1649      * Flushes the audio data currently queued for playback. Any data that has
1650      * been written but not yet presented will be discarded.  No-op if not stopped or paused,
1651      * or if the track's creation mode is not {@link #MODE_STREAM}.
1652      * <BR> Note that although data written but not yet presented is discarded, there is no
1653      * guarantee that all of the buffer space formerly used by that data
1654      * is available for a subsequent write.
1655      * For example, a call to {@link #write(byte[], int, int)} with <code>sizeInBytes</code>
1656      * less than or equal to the total buffer size
1657      * may return a short actual transfer count.
1658      */
flush()1659     public void flush() {
1660         if (mState == STATE_INITIALIZED) {
1661             // flush the data in native layer
1662             native_flush();
1663             mAvSyncHeader = null;
1664             mAvSyncBytesRemaining = 0;
1665         }
1666 
1667     }
1668 
1669     /**
1670      * Writes the audio data to the audio sink for playback (streaming mode),
1671      * or copies audio data for later playback (static buffer mode).
1672      * The format specified in the AudioTrack constructor should be
1673      * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array.
1674      * <p>
1675      * In streaming mode, the write will normally block until all the data has been enqueued for
1676      * playback, and will return a full transfer count.  However, if the track is stopped or paused
1677      * on entry, or another thread interrupts the write by calling stop or pause, or an I/O error
1678      * occurs during the write, then the write may return a short transfer count.
1679      * <p>
1680      * In static buffer mode, copies the data to the buffer starting at offset 0.
1681      * Note that the actual playback of this data might occur after this function returns.
1682      *
1683      * @param audioData the array that holds the data to play.
1684      * @param offsetInBytes the offset expressed in bytes in audioData where the data to play
1685      *    starts.
1686      * @param sizeInBytes the number of bytes to read in audioData after the offset.
1687      * @return zero or the positive number of bytes that were written, or
1688      *    {@link #ERROR_INVALID_OPERATION}
1689      *    if the track isn't properly initialized, or {@link #ERROR_BAD_VALUE} if
1690      *    the parameters don't resolve to valid data and indexes, or
1691      *    {@link AudioManager#ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
1692      *    needs to be recreated.
1693      *    The dead object error code is not returned if some data was successfully transferred.
1694      *    In this case, the error is returned at the next write().
1695      *
1696      * This is equivalent to {@link #write(byte[], int, int, int)} with <code>writeMode</code>
1697      * set to  {@link #WRITE_BLOCKING}.
1698      */
write(@onNull byte[] audioData, int offsetInBytes, int sizeInBytes)1699     public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) {
1700         return write(audioData, offsetInBytes, sizeInBytes, WRITE_BLOCKING);
1701     }
1702 
1703     /**
1704      * Writes the audio data to the audio sink for playback (streaming mode),
1705      * or copies audio data for later playback (static buffer mode).
1706      * The format specified in the AudioTrack constructor should be
1707      * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array.
1708      * <p>
1709      * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
1710      * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
1711      * for playback, and will return a full transfer count.  However, if the write mode is
1712      * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
1713      * interrupts the write by calling stop or pause, or an I/O error
1714      * occurs during the write, then the write may return a short transfer count.
1715      * <p>
1716      * In static buffer mode, copies the data to the buffer starting at offset 0,
1717      * and the write mode is ignored.
1718      * Note that the actual playback of this data might occur after this function returns.
1719      *
1720      * @param audioData the array that holds the data to play.
1721      * @param offsetInBytes the offset expressed in bytes in audioData where the data to play
1722      *    starts.
1723      * @param sizeInBytes the number of bytes to read in audioData after the offset.
1724      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
1725      *     effect in static mode.
1726      *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
1727      *         to the audio sink.
1728      *     <br>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
1729      *     queuing as much audio data for playback as possible without blocking.
1730      * @return zero or the positive number of bytes that were written, or
1731      *    {@link #ERROR_INVALID_OPERATION}
1732      *    if the track isn't properly initialized, or {@link #ERROR_BAD_VALUE} if
1733      *    the parameters don't resolve to valid data and indexes, or
1734      *    {@link AudioManager#ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
1735      *    needs to be recreated.
1736      *    The dead object error code is not returned if some data was successfully transferred.
1737      *    In this case, the error is returned at the next write().
1738      */
write(@onNull byte[] audioData, int offsetInBytes, int sizeInBytes, @WriteMode int writeMode)1739     public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
1740             @WriteMode int writeMode) {
1741 
1742         if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
1743             return ERROR_INVALID_OPERATION;
1744         }
1745 
1746         if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
1747             Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
1748             return ERROR_BAD_VALUE;
1749         }
1750 
1751         if ( (audioData == null) || (offsetInBytes < 0 ) || (sizeInBytes < 0)
1752                 || (offsetInBytes + sizeInBytes < 0)    // detect integer overflow
1753                 || (offsetInBytes + sizeInBytes > audioData.length)) {
1754             return ERROR_BAD_VALUE;
1755         }
1756 
1757         int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat,
1758                 writeMode == WRITE_BLOCKING);
1759 
1760         if ((mDataLoadMode == MODE_STATIC)
1761                 && (mState == STATE_NO_STATIC_DATA)
1762                 && (ret > 0)) {
1763             // benign race with respect to other APIs that read mState
1764             mState = STATE_INITIALIZED;
1765         }
1766 
1767         return ret;
1768     }
1769 
1770     /**
1771      * Writes the audio data to the audio sink for playback (streaming mode),
1772      * or copies audio data for later playback (static buffer mode).
1773      * The format specified in the AudioTrack constructor should be
1774      * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array.
1775      * <p>
1776      * In streaming mode, the write will normally block until all the data has been enqueued for
1777      * playback, and will return a full transfer count.  However, if the track is stopped or paused
1778      * on entry, or another thread interrupts the write by calling stop or pause, or an I/O error
1779      * occurs during the write, then the write may return a short transfer count.
1780      * <p>
1781      * In static buffer mode, copies the data to the buffer starting at offset 0.
1782      * Note that the actual playback of this data might occur after this function returns.
1783      *
1784      * @param audioData the array that holds the data to play.
1785      * @param offsetInShorts the offset expressed in shorts in audioData where the data to play
1786      *     starts.
1787      * @param sizeInShorts the number of shorts to read in audioData after the offset.
1788      * @return zero or the positive number of shorts that were written, or
1789      *    {@link #ERROR_INVALID_OPERATION}
1790      *    if the track isn't properly initialized, or {@link #ERROR_BAD_VALUE} if
1791      *    the parameters don't resolve to valid data and indexes, or
1792      *    {@link AudioManager#ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
1793      *    needs to be recreated.
1794      *    The dead object error code is not returned if some data was successfully transferred.
1795      *    In this case, the error is returned at the next write().
1796      *
1797      * This is equivalent to {@link #write(short[], int, int, int)} with <code>writeMode</code>
1798      * set to  {@link #WRITE_BLOCKING}.
1799      */
write(@onNull short[] audioData, int offsetInShorts, int sizeInShorts)1800     public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts) {
1801         return write(audioData, offsetInShorts, sizeInShorts, WRITE_BLOCKING);
1802     }
1803 
1804     /**
1805      * Writes the audio data to the audio sink for playback (streaming mode),
1806      * or copies audio data for later playback (static buffer mode).
1807      * The format specified in the AudioTrack constructor should be
1808      * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array.
1809      * <p>
1810      * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
1811      * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
1812      * for playback, and will return a full transfer count.  However, if the write mode is
1813      * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
1814      * interrupts the write by calling stop or pause, or an I/O error
1815      * occurs during the write, then the write may return a short transfer count.
1816      * <p>
1817      * In static buffer mode, copies the data to the buffer starting at offset 0.
1818      * Note that the actual playback of this data might occur after this function returns.
1819      *
1820      * @param audioData the array that holds the data to play.
1821      * @param offsetInShorts the offset expressed in shorts in audioData where the data to play
1822      *     starts.
1823      * @param sizeInShorts the number of shorts to read in audioData after the offset.
1824      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
1825      *     effect in static mode.
1826      *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
1827      *         to the audio sink.
1828      *     <br>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
1829      *     queuing as much audio data for playback as possible without blocking.
1830      * @return zero or the positive number of shorts that were written, or
1831      *    {@link #ERROR_INVALID_OPERATION}
1832      *    if the track isn't properly initialized, or {@link #ERROR_BAD_VALUE} if
1833      *    the parameters don't resolve to valid data and indexes, or
1834      *    {@link AudioManager#ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
1835      *    needs to be recreated.
1836      *    The dead object error code is not returned if some data was successfully transferred.
1837      *    In this case, the error is returned at the next write().
1838      */
write(@onNull short[] audioData, int offsetInShorts, int sizeInShorts, @WriteMode int writeMode)1839     public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
1840             @WriteMode int writeMode) {
1841 
1842         if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
1843             return ERROR_INVALID_OPERATION;
1844         }
1845 
1846         if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
1847             Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
1848             return ERROR_BAD_VALUE;
1849         }
1850 
1851         if ( (audioData == null) || (offsetInShorts < 0 ) || (sizeInShorts < 0)
1852                 || (offsetInShorts + sizeInShorts < 0)  // detect integer overflow
1853                 || (offsetInShorts + sizeInShorts > audioData.length)) {
1854             return ERROR_BAD_VALUE;
1855         }
1856 
1857         int ret = native_write_short(audioData, offsetInShorts, sizeInShorts, mAudioFormat,
1858                 writeMode == WRITE_BLOCKING);
1859 
1860         if ((mDataLoadMode == MODE_STATIC)
1861                 && (mState == STATE_NO_STATIC_DATA)
1862                 && (ret > 0)) {
1863             // benign race with respect to other APIs that read mState
1864             mState = STATE_INITIALIZED;
1865         }
1866 
1867         return ret;
1868     }
1869 
1870     /**
1871      * Writes the audio data to the audio sink for playback (streaming mode),
1872      * or copies audio data for later playback (static buffer mode).
1873      * The format specified in the AudioTrack constructor should be
1874      * {@link AudioFormat#ENCODING_PCM_FLOAT} to correspond to the data in the array.
1875      * <p>
1876      * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
1877      * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
1878      * for playback, and will return a full transfer count.  However, if the write mode is
1879      * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
1880      * interrupts the write by calling stop or pause, or an I/O error
1881      * occurs during the write, then the write may return a short transfer count.
1882      * <p>
1883      * In static buffer mode, copies the data to the buffer starting at offset 0,
1884      * and the write mode is ignored.
1885      * Note that the actual playback of this data might occur after this function returns.
1886      *
1887      * @param audioData the array that holds the data to play.
1888      *     The implementation does not clip for sample values within the nominal range
1889      *     [-1.0f, 1.0f], provided that all gains in the audio pipeline are
1890      *     less than or equal to unity (1.0f), and in the absence of post-processing effects
1891      *     that could add energy, such as reverb.  For the convenience of applications
1892      *     that compute samples using filters with non-unity gain,
1893      *     sample values +3 dB beyond the nominal range are permitted.
1894      *     However such values may eventually be limited or clipped, depending on various gains
1895      *     and later processing in the audio path.  Therefore applications are encouraged
1896      *     to provide samples values within the nominal range.
1897      * @param offsetInFloats the offset, expressed as a number of floats,
1898      *     in audioData where the data to play starts.
1899      * @param sizeInFloats the number of floats to read in audioData after the offset.
1900      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
1901      *     effect in static mode.
1902      *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
1903      *         to the audio sink.
1904      *     <br>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
1905      *     queuing as much audio data for playback as possible without blocking.
1906      * @return zero or the positive number of floats that were written, or
1907      *    {@link #ERROR_INVALID_OPERATION}
1908      *    if the track isn't properly initialized, or {@link #ERROR_BAD_VALUE} if
1909      *    the parameters don't resolve to valid data and indexes, or
1910      *    {@link AudioManager#ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
1911      *    needs to be recreated.
1912      *    The dead object error code is not returned if some data was successfully transferred.
1913      *    In this case, the error is returned at the next write().
1914      */
write(@onNull float[] audioData, int offsetInFloats, int sizeInFloats, @WriteMode int writeMode)1915     public int write(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats,
1916             @WriteMode int writeMode) {
1917 
1918         if (mState == STATE_UNINITIALIZED) {
1919             Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED");
1920             return ERROR_INVALID_OPERATION;
1921         }
1922 
1923         if (mAudioFormat != AudioFormat.ENCODING_PCM_FLOAT) {
1924             Log.e(TAG, "AudioTrack.write(float[] ...) requires format ENCODING_PCM_FLOAT");
1925             return ERROR_INVALID_OPERATION;
1926         }
1927 
1928         if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
1929             Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
1930             return ERROR_BAD_VALUE;
1931         }
1932 
1933         if ( (audioData == null) || (offsetInFloats < 0 ) || (sizeInFloats < 0)
1934                 || (offsetInFloats + sizeInFloats < 0)  // detect integer overflow
1935                 || (offsetInFloats + sizeInFloats > audioData.length)) {
1936             Log.e(TAG, "AudioTrack.write() called with invalid array, offset, or size");
1937             return ERROR_BAD_VALUE;
1938         }
1939 
1940         int ret = native_write_float(audioData, offsetInFloats, sizeInFloats, mAudioFormat,
1941                 writeMode == WRITE_BLOCKING);
1942 
1943         if ((mDataLoadMode == MODE_STATIC)
1944                 && (mState == STATE_NO_STATIC_DATA)
1945                 && (ret > 0)) {
1946             // benign race with respect to other APIs that read mState
1947             mState = STATE_INITIALIZED;
1948         }
1949 
1950         return ret;
1951     }
1952 
1953 
1954     /**
1955      * Writes the audio data to the audio sink for playback (streaming mode),
1956      * or copies audio data for later playback (static buffer mode).
1957      * The audioData in ByteBuffer should match the format specified in the AudioTrack constructor.
1958      * <p>
1959      * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
1960      * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
1961      * for playback, and will return a full transfer count.  However, if the write mode is
1962      * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
1963      * interrupts the write by calling stop or pause, or an I/O error
1964      * occurs during the write, then the write may return a short transfer count.
1965      * <p>
1966      * In static buffer mode, copies the data to the buffer starting at offset 0,
1967      * and the write mode is ignored.
1968      * Note that the actual playback of this data might occur after this function returns.
1969      *
1970      * @param audioData the buffer that holds the data to play, starting at the position reported
1971      *     by <code>audioData.position()</code>.
1972      *     <BR>Note that upon return, the buffer position (<code>audioData.position()</code>) will
1973      *     have been advanced to reflect the amount of data that was successfully written to
1974      *     the AudioTrack.
1975      * @param sizeInBytes number of bytes to write.
1976      *     <BR>Note this may differ from <code>audioData.remaining()</code>, but cannot exceed it.
1977      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
1978      *     effect in static mode.
1979      *     <BR>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
1980      *         to the audio sink.
1981      *     <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
1982      *     queuing as much audio data for playback as possible without blocking.
1983      * @return zero or the positive number of bytes that were written, or
1984      *     {@link #ERROR_BAD_VALUE}, {@link #ERROR_INVALID_OPERATION}, or
1985      *     {@link AudioManager#ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
1986      *     needs to be recreated.
1987      *     The dead object error code is not returned if some data was successfully transferred.
1988      *     In this case, the error is returned at the next write().
1989      */
write(@onNull ByteBuffer audioData, int sizeInBytes, @WriteMode int writeMode)1990     public int write(@NonNull ByteBuffer audioData, int sizeInBytes,
1991             @WriteMode int writeMode) {
1992 
1993         if (mState == STATE_UNINITIALIZED) {
1994             Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED");
1995             return ERROR_INVALID_OPERATION;
1996         }
1997 
1998         if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
1999             Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
2000             return ERROR_BAD_VALUE;
2001         }
2002 
2003         if ( (audioData == null) || (sizeInBytes < 0) || (sizeInBytes > audioData.remaining())) {
2004             Log.e(TAG, "AudioTrack.write() called with invalid size (" + sizeInBytes + ") value");
2005             return ERROR_BAD_VALUE;
2006         }
2007 
2008         int ret = 0;
2009         if (audioData.isDirect()) {
2010             ret = native_write_native_bytes(audioData,
2011                     audioData.position(), sizeInBytes, mAudioFormat,
2012                     writeMode == WRITE_BLOCKING);
2013         } else {
2014             ret = native_write_byte(NioUtils.unsafeArray(audioData),
2015                     NioUtils.unsafeArrayOffset(audioData) + audioData.position(),
2016                     sizeInBytes, mAudioFormat,
2017                     writeMode == WRITE_BLOCKING);
2018         }
2019 
2020         if ((mDataLoadMode == MODE_STATIC)
2021                 && (mState == STATE_NO_STATIC_DATA)
2022                 && (ret > 0)) {
2023             // benign race with respect to other APIs that read mState
2024             mState = STATE_INITIALIZED;
2025         }
2026 
2027         if (ret > 0) {
2028             audioData.position(audioData.position() + ret);
2029         }
2030 
2031         return ret;
2032     }
2033 
2034     /**
2035      * Writes the audio data to the audio sink for playback in streaming mode on a HW_AV_SYNC track.
2036      * The blocking behavior will depend on the write mode.
2037      * @param audioData the buffer that holds the data to play, starting at the position reported
2038      *     by <code>audioData.position()</code>.
2039      *     <BR>Note that upon return, the buffer position (<code>audioData.position()</code>) will
2040      *     have been advanced to reflect the amount of data that was successfully written to
2041      *     the AudioTrack.
2042      * @param sizeInBytes number of bytes to write.
2043      *     <BR>Note this may differ from <code>audioData.remaining()</code>, but cannot exceed it.
2044      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}.
2045      *     <BR>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
2046      *         to the audio sink.
2047      *     <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
2048      *     queuing as much audio data for playback as possible without blocking.
2049      * @param timestamp The timestamp of the first decodable audio frame in the provided audioData.
2050      * @return zero or a positive number of bytes that were written, or
2051      *     {@link #ERROR_BAD_VALUE}, {@link #ERROR_INVALID_OPERATION}, or
2052      *     {@link AudioManager#ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
2053      *     needs to be recreated.
2054      *     The dead object error code is not returned if some data was successfully transferred.
2055      *     In this case, the error is returned at the next write().
2056      */
write(@onNull ByteBuffer audioData, int sizeInBytes, @WriteMode int writeMode, long timestamp)2057     public int write(@NonNull ByteBuffer audioData, int sizeInBytes,
2058             @WriteMode int writeMode, long timestamp) {
2059 
2060         if (mState == STATE_UNINITIALIZED) {
2061             Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED");
2062             return ERROR_INVALID_OPERATION;
2063         }
2064 
2065         if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
2066             Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
2067             return ERROR_BAD_VALUE;
2068         }
2069 
2070         if (mDataLoadMode != MODE_STREAM) {
2071             Log.e(TAG, "AudioTrack.write() with timestamp called for non-streaming mode track");
2072             return ERROR_INVALID_OPERATION;
2073         }
2074 
2075         if ((mAttributes.getFlags() & AudioAttributes.FLAG_HW_AV_SYNC) == 0) {
2076             Log.d(TAG, "AudioTrack.write() called on a regular AudioTrack. Ignoring pts...");
2077             return write(audioData, sizeInBytes, writeMode);
2078         }
2079 
2080         if ((audioData == null) || (sizeInBytes < 0) || (sizeInBytes > audioData.remaining())) {
2081             Log.e(TAG, "AudioTrack.write() called with invalid size (" + sizeInBytes + ") value");
2082             return ERROR_BAD_VALUE;
2083         }
2084 
2085         // create timestamp header if none exists
2086         if (mAvSyncHeader == null) {
2087             mAvSyncHeader = ByteBuffer.allocate(16);
2088             mAvSyncHeader.order(ByteOrder.BIG_ENDIAN);
2089             mAvSyncHeader.putInt(0x55550001);
2090             mAvSyncHeader.putInt(sizeInBytes);
2091             mAvSyncHeader.putLong(timestamp);
2092             mAvSyncHeader.position(0);
2093             mAvSyncBytesRemaining = sizeInBytes;
2094         }
2095 
2096         // write timestamp header if not completely written already
2097         int ret = 0;
2098         if (mAvSyncHeader.remaining() != 0) {
2099             ret = write(mAvSyncHeader, mAvSyncHeader.remaining(), writeMode);
2100             if (ret < 0) {
2101                 Log.e(TAG, "AudioTrack.write() could not write timestamp header!");
2102                 mAvSyncHeader = null;
2103                 mAvSyncBytesRemaining = 0;
2104                 return ret;
2105             }
2106             if (mAvSyncHeader.remaining() > 0) {
2107                 Log.v(TAG, "AudioTrack.write() partial timestamp header written.");
2108                 return 0;
2109             }
2110         }
2111 
2112         // write audio data
2113         int sizeToWrite = Math.min(mAvSyncBytesRemaining, sizeInBytes);
2114         ret = write(audioData, sizeToWrite, writeMode);
2115         if (ret < 0) {
2116             Log.e(TAG, "AudioTrack.write() could not write audio data!");
2117             mAvSyncHeader = null;
2118             mAvSyncBytesRemaining = 0;
2119             return ret;
2120         }
2121 
2122         mAvSyncBytesRemaining -= ret;
2123         if (mAvSyncBytesRemaining == 0) {
2124             mAvSyncHeader = null;
2125         }
2126 
2127         return ret;
2128     }
2129 
2130 
2131     /**
2132      * Sets the playback head position within the static buffer to zero,
2133      * that is it rewinds to start of static buffer.
2134      * The track must be stopped or paused, and
2135      * the track's creation mode must be {@link #MODE_STATIC}.
2136      * <p>
2137      * As of {@link android.os.Build.VERSION_CODES#M}, also resets the value returned by
2138      * {@link #getPlaybackHeadPosition()} to zero.
2139      * For earlier API levels, the reset behavior is unspecified.
2140      * <p>
2141      * Use {@link #setPlaybackHeadPosition(int)} with a zero position
2142      * if the reset of <code>getPlaybackHeadPosition()</code> is not needed.
2143      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
2144      *  {@link #ERROR_INVALID_OPERATION}
2145      */
reloadStaticData()2146     public int reloadStaticData() {
2147         if (mDataLoadMode == MODE_STREAM || mState != STATE_INITIALIZED) {
2148             return ERROR_INVALID_OPERATION;
2149         }
2150         return native_reload_static();
2151     }
2152 
2153     //--------------------------------------------------------------------------
2154     // Audio effects management
2155     //--------------------
2156 
2157     /**
2158      * Attaches an auxiliary effect to the audio track. A typical auxiliary
2159      * effect is a reverberation effect which can be applied on any sound source
2160      * that directs a certain amount of its energy to this effect. This amount
2161      * is defined by setAuxEffectSendLevel().
2162      * {@see #setAuxEffectSendLevel(float)}.
2163      * <p>After creating an auxiliary effect (e.g.
2164      * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with
2165      * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling
2166      * this method to attach the audio track to the effect.
2167      * <p>To detach the effect from the audio track, call this method with a
2168      * null effect id.
2169      *
2170      * @param effectId system wide unique id of the effect to attach
2171      * @return error code or success, see {@link #SUCCESS},
2172      *    {@link #ERROR_INVALID_OPERATION}, {@link #ERROR_BAD_VALUE}
2173      */
attachAuxEffect(int effectId)2174     public int attachAuxEffect(int effectId) {
2175         if (mState == STATE_UNINITIALIZED) {
2176             return ERROR_INVALID_OPERATION;
2177         }
2178         return native_attachAuxEffect(effectId);
2179     }
2180 
2181     /**
2182      * Sets the send level of the audio track to the attached auxiliary effect
2183      * {@link #attachAuxEffect(int)}.  Effect levels
2184      * are clamped to the closed interval [0.0, max] where
2185      * max is the value of {@link #getMaxVolume}.
2186      * A value of 0.0 results in no effect, and a value of 1.0 is full send.
2187      * <p>By default the send level is 0.0f, so even if an effect is attached to the player
2188      * this method must be called for the effect to be applied.
2189      * <p>Note that the passed level value is a linear scalar. UI controls should be scaled
2190      * logarithmically: the gain applied by audio framework ranges from -72dB to at least 0dB,
2191      * so an appropriate conversion from linear UI input x to level is:
2192      * x == 0 -&gt; level = 0
2193      * 0 &lt; x &lt;= R -&gt; level = 10^(72*(x-R)/20/R)
2194      *
2195      * @param level linear send level
2196      * @return error code or success, see {@link #SUCCESS},
2197      *    {@link #ERROR_INVALID_OPERATION}, {@link #ERROR}
2198      */
setAuxEffectSendLevel(float level)2199     public int setAuxEffectSendLevel(float level) {
2200         if (isRestricted()) {
2201             return SUCCESS;
2202         }
2203         if (mState == STATE_UNINITIALIZED) {
2204             return ERROR_INVALID_OPERATION;
2205         }
2206         level = clampGainOrLevel(level);
2207         int err = native_setAuxEffectSendLevel(level);
2208         return err == 0 ? SUCCESS : ERROR;
2209     }
2210 
2211     //--------------------------------------------------------------------------
2212     // Explicit Routing
2213     //--------------------
2214     private AudioDeviceInfo mPreferredDevice = null;
2215 
2216     /**
2217      * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
2218      * the output from this AudioTrack.
2219      * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio sink.
2220      *  If deviceInfo is null, default routing is restored.
2221      * @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
2222      * does not correspond to a valid audio output device.
2223      */
setPreferredDevice(AudioDeviceInfo deviceInfo)2224     public boolean setPreferredDevice(AudioDeviceInfo deviceInfo) {
2225         // Do some validation....
2226         if (deviceInfo != null && !deviceInfo.isSink()) {
2227             return false;
2228         }
2229         int preferredDeviceId = deviceInfo != null ? deviceInfo.getId() : 0;
2230         boolean status = native_setOutputDevice(preferredDeviceId);
2231         if (status == true) {
2232             synchronized (this) {
2233                 mPreferredDevice = deviceInfo;
2234             }
2235         }
2236         return status;
2237     }
2238 
2239     /**
2240      * Returns the selected output specified by {@link #setPreferredDevice}. Note that this
2241      * is not guaranteed to correspond to the actual device being used for playback.
2242      */
getPreferredDevice()2243     public AudioDeviceInfo getPreferredDevice() {
2244         synchronized (this) {
2245             return mPreferredDevice;
2246         }
2247     }
2248 
2249     //--------------------------------------------------------------------------
2250     // (Re)Routing Info
2251     //--------------------
2252     /**
2253      * Defines the interface by which applications can receive notifications of routing
2254      * changes for the associated {@link AudioTrack}.
2255      */
2256     public interface OnRoutingChangedListener {
2257         /**
2258          * Called when the routing of an AudioTrack changes from either and explicit or
2259          * policy rerouting.  Use {@link #getRoutedDevice()} to retrieve the newly routed-to
2260          * device.
2261          */
onRoutingChanged(AudioTrack audioTrack)2262         public void onRoutingChanged(AudioTrack audioTrack);
2263     }
2264 
2265     /**
2266      * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioTrack.
2267      * Note: The query is only valid if the AudioTrack is currently playing. If it is not,
2268      * <code>getRoutedDevice()</code> will return null.
2269      */
getRoutedDevice()2270     public AudioDeviceInfo getRoutedDevice() {
2271         int deviceId = native_getRoutedDeviceId();
2272         if (deviceId == 0) {
2273             return null;
2274         }
2275         AudioDeviceInfo[] devices =
2276                 AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_OUTPUTS);
2277         for (int i = 0; i < devices.length; i++) {
2278             if (devices[i].getId() == deviceId) {
2279                 return devices[i];
2280             }
2281         }
2282         return null;
2283     }
2284 
2285     /**
2286      * The list of AudioTrack.OnRoutingChangedListener interfaces added (with
2287      * {@link AudioTrack#addOnRoutingChangedListener(OnRoutingChangedListener, android.os.Handler)}
2288      * by an app to receive (re)routing notifications.
2289      */
2290     private ArrayMap<OnRoutingChangedListener, NativeRoutingEventHandlerDelegate>
2291         mRoutingChangeListeners =
2292             new ArrayMap<OnRoutingChangedListener, NativeRoutingEventHandlerDelegate>();
2293 
2294     /**
2295      * Adds an {@link OnRoutingChangedListener} to receive notifications of routing changes
2296      * on this AudioTrack.
2297      * @param listener The {@link OnRoutingChangedListener} interface to receive notifications
2298      * of rerouting events.
2299      * @param handler  Specifies the {@link Handler} object for the thread on which to execute
2300      * the callback. If <code>null</code>, the {@link Handler} associated with the main
2301      * {@link Looper} will be used.
2302      */
addOnRoutingChangedListener(OnRoutingChangedListener listener, android.os.Handler handler)2303     public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
2304             android.os.Handler handler) {
2305         if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
2306             synchronized (mRoutingChangeListeners) {
2307                 if (mRoutingChangeListeners.size() == 0) {
2308                     native_enableDeviceCallback();
2309                 }
2310                 mRoutingChangeListeners.put(
2311                     listener, new NativeRoutingEventHandlerDelegate(this, listener,
2312                             handler != null ? handler : new Handler(mInitializationLooper)));
2313             }
2314         }
2315     }
2316 
2317     /**
2318      * Removes an {@link OnRoutingChangedListener} which has been previously added
2319      * to receive rerouting notifications.
2320      * @param listener The previously added {@link OnRoutingChangedListener} interface to remove.
2321      */
removeOnRoutingChangedListener(OnRoutingChangedListener listener)2322     public void removeOnRoutingChangedListener(OnRoutingChangedListener listener) {
2323         synchronized (mRoutingChangeListeners) {
2324             if (mRoutingChangeListeners.containsKey(listener)) {
2325                 mRoutingChangeListeners.remove(listener);
2326             }
2327             if (mRoutingChangeListeners.size() == 0) {
2328                 native_disableDeviceCallback();
2329             }
2330         }
2331     }
2332 
2333     /**
2334      * Sends device list change notification to all listeners.
2335      */
broadcastRoutingChange()2336     private void broadcastRoutingChange() {
2337         Collection<NativeRoutingEventHandlerDelegate> values;
2338         synchronized (mRoutingChangeListeners) {
2339             values = mRoutingChangeListeners.values();
2340         }
2341         AudioManager.resetAudioPortGeneration();
2342         for(NativeRoutingEventHandlerDelegate delegate : values) {
2343             Handler handler = delegate.getHandler();
2344             if (handler != null) {
2345                 handler.sendEmptyMessage(AudioSystem.NATIVE_EVENT_ROUTING_CHANGE);
2346             }
2347         }
2348     }
2349 
2350     //---------------------------------------------------------
2351     // Interface definitions
2352     //--------------------
2353     /**
2354      * Interface definition for a callback to be invoked when the playback head position of
2355      * an AudioTrack has reached a notification marker or has increased by a certain period.
2356      */
2357     public interface OnPlaybackPositionUpdateListener  {
2358         /**
2359          * Called on the listener to notify it that the previously set marker has been reached
2360          * by the playback head.
2361          */
onMarkerReached(AudioTrack track)2362         void onMarkerReached(AudioTrack track);
2363 
2364         /**
2365          * Called on the listener to periodically notify it that the playback head has reached
2366          * a multiple of the notification period.
2367          */
onPeriodicNotification(AudioTrack track)2368         void onPeriodicNotification(AudioTrack track);
2369     }
2370 
2371     //---------------------------------------------------------
2372     // Inner classes
2373     //--------------------
2374     /**
2375      * Helper class to handle the forwarding of native events to the appropriate listener
2376      * (potentially) handled in a different thread
2377      */
2378     private class NativePositionEventHandlerDelegate {
2379         private final Handler mHandler;
2380 
NativePositionEventHandlerDelegate(final AudioTrack track, final OnPlaybackPositionUpdateListener listener, Handler handler)2381         NativePositionEventHandlerDelegate(final AudioTrack track,
2382                                    final OnPlaybackPositionUpdateListener listener,
2383                                    Handler handler) {
2384             // find the looper for our new event handler
2385             Looper looper;
2386             if (handler != null) {
2387                 looper = handler.getLooper();
2388             } else {
2389                 // no given handler, use the looper the AudioTrack was created in
2390                 looper = mInitializationLooper;
2391             }
2392 
2393             // construct the event handler with this looper
2394             if (looper != null) {
2395                 // implement the event handler delegate
2396                 mHandler = new Handler(looper) {
2397                     @Override
2398                     public void handleMessage(Message msg) {
2399                         if (track == null) {
2400                             return;
2401                         }
2402                         switch(msg.what) {
2403                         case NATIVE_EVENT_MARKER:
2404                             if (listener != null) {
2405                                 listener.onMarkerReached(track);
2406                             }
2407                             break;
2408                         case NATIVE_EVENT_NEW_POS:
2409                             if (listener != null) {
2410                                 listener.onPeriodicNotification(track);
2411                             }
2412                             break;
2413                         default:
2414                             loge("Unknown native event type: " + msg.what);
2415                             break;
2416                         }
2417                     }
2418                 };
2419             } else {
2420                 mHandler = null;
2421             }
2422         }
2423 
getHandler()2424         Handler getHandler() {
2425             return mHandler;
2426         }
2427     }
2428 
2429     /**
2430      * Helper class to handle the forwarding of native events to the appropriate listener
2431      * (potentially) handled in a different thread
2432      */
2433     private class NativeRoutingEventHandlerDelegate {
2434         private final Handler mHandler;
2435 
NativeRoutingEventHandlerDelegate(final AudioTrack track, final OnRoutingChangedListener listener, Handler handler)2436         NativeRoutingEventHandlerDelegate(final AudioTrack track,
2437                                    final OnRoutingChangedListener listener,
2438                                    Handler handler) {
2439             // find the looper for our new event handler
2440             Looper looper;
2441             if (handler != null) {
2442                 looper = handler.getLooper();
2443             } else {
2444                 // no given handler, use the looper the AudioTrack was created in
2445                 looper = mInitializationLooper;
2446             }
2447 
2448             // construct the event handler with this looper
2449             if (looper != null) {
2450                 // implement the event handler delegate
2451                 mHandler = new Handler(looper) {
2452                     @Override
2453                     public void handleMessage(Message msg) {
2454                         if (track == null) {
2455                             return;
2456                         }
2457                         switch(msg.what) {
2458                         case AudioSystem.NATIVE_EVENT_ROUTING_CHANGE:
2459                             if (listener != null) {
2460                                 listener.onRoutingChanged(track);
2461                             }
2462                             break;
2463                         default:
2464                             loge("Unknown native event type: " + msg.what);
2465                             break;
2466                         }
2467                     }
2468                 };
2469             } else {
2470                 mHandler = null;
2471             }
2472         }
2473 
getHandler()2474         Handler getHandler() {
2475             return mHandler;
2476         }
2477     }
2478 
2479     //---------------------------------------------------------
2480     // Java methods called from the native side
2481     //--------------------
2482     @SuppressWarnings("unused")
postEventFromNative(Object audiotrack_ref, int what, int arg1, int arg2, Object obj)2483     private static void postEventFromNative(Object audiotrack_ref,
2484             int what, int arg1, int arg2, Object obj) {
2485         //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2);
2486         AudioTrack track = (AudioTrack)((WeakReference)audiotrack_ref).get();
2487         if (track == null) {
2488             return;
2489         }
2490 
2491         if (what == AudioSystem.NATIVE_EVENT_ROUTING_CHANGE) {
2492             track.broadcastRoutingChange();
2493             return;
2494         }
2495         NativePositionEventHandlerDelegate delegate = track.mEventHandlerDelegate;
2496         if (delegate != null) {
2497             Handler handler = delegate.getHandler();
2498             if (handler != null) {
2499                 Message m = handler.obtainMessage(what, arg1, arg2, obj);
2500                 handler.sendMessage(m);
2501             }
2502         }
2503     }
2504 
2505 
2506     //---------------------------------------------------------
2507     // Native methods called from the Java side
2508     //--------------------
2509 
2510     // post-condition: mStreamType is overwritten with a value
2511     //     that reflects the audio attributes (e.g. an AudioAttributes object with a usage of
2512     //     AudioAttributes.USAGE_MEDIA will map to AudioManager.STREAM_MUSIC
native_setup(Object audiotrack_this, Object attributes, int sampleRate, int channelMask, int channelIndexMask, int audioFormat, int buffSizeInBytes, int mode, int[] sessionId)2513     private native final int native_setup(Object /*WeakReference<AudioTrack>*/ audiotrack_this,
2514             Object /*AudioAttributes*/ attributes,
2515             int sampleRate, int channelMask, int channelIndexMask, int audioFormat,
2516             int buffSizeInBytes, int mode, int[] sessionId);
2517 
native_finalize()2518     private native final void native_finalize();
2519 
native_release()2520     private native final void native_release();
2521 
native_start()2522     private native final void native_start();
2523 
native_stop()2524     private native final void native_stop();
2525 
native_pause()2526     private native final void native_pause();
2527 
native_flush()2528     private native final void native_flush();
2529 
native_write_byte(byte[] audioData, int offsetInBytes, int sizeInBytes, int format, boolean isBlocking)2530     private native final int native_write_byte(byte[] audioData,
2531                                                int offsetInBytes, int sizeInBytes, int format,
2532                                                boolean isBlocking);
2533 
native_write_short(short[] audioData, int offsetInShorts, int sizeInShorts, int format, boolean isBlocking)2534     private native final int native_write_short(short[] audioData,
2535                                                 int offsetInShorts, int sizeInShorts, int format,
2536                                                 boolean isBlocking);
2537 
native_write_float(float[] audioData, int offsetInFloats, int sizeInFloats, int format, boolean isBlocking)2538     private native final int native_write_float(float[] audioData,
2539                                                 int offsetInFloats, int sizeInFloats, int format,
2540                                                 boolean isBlocking);
2541 
native_write_native_bytes(Object audioData, int positionInBytes, int sizeInBytes, int format, boolean blocking)2542     private native final int native_write_native_bytes(Object audioData,
2543             int positionInBytes, int sizeInBytes, int format, boolean blocking);
2544 
native_reload_static()2545     private native final int native_reload_static();
2546 
native_get_native_frame_count()2547     private native final int native_get_native_frame_count();
2548 
native_setVolume(float leftVolume, float rightVolume)2549     private native final void native_setVolume(float leftVolume, float rightVolume);
2550 
native_set_playback_rate(int sampleRateInHz)2551     private native final int native_set_playback_rate(int sampleRateInHz);
native_get_playback_rate()2552     private native final int native_get_playback_rate();
2553 
native_set_playback_params(@onNull PlaybackParams params)2554     private native final void native_set_playback_params(@NonNull PlaybackParams params);
native_get_playback_params()2555     private native final @NonNull PlaybackParams native_get_playback_params();
2556 
native_set_marker_pos(int marker)2557     private native final int native_set_marker_pos(int marker);
native_get_marker_pos()2558     private native final int native_get_marker_pos();
2559 
native_set_pos_update_period(int updatePeriod)2560     private native final int native_set_pos_update_period(int updatePeriod);
native_get_pos_update_period()2561     private native final int native_get_pos_update_period();
2562 
native_set_position(int position)2563     private native final int native_set_position(int position);
native_get_position()2564     private native final int native_get_position();
2565 
native_get_latency()2566     private native final int native_get_latency();
2567 
2568     // longArray must be a non-null array of length >= 2
2569     // [0] is assigned the frame position
2570     // [1] is assigned the time in CLOCK_MONOTONIC nanoseconds
native_get_timestamp(long[] longArray)2571     private native final int native_get_timestamp(long[] longArray);
2572 
native_set_loop(int start, int end, int loopCount)2573     private native final int native_set_loop(int start, int end, int loopCount);
2574 
native_get_output_sample_rate(int streamType)2575     static private native final int native_get_output_sample_rate(int streamType);
native_get_min_buff_size( int sampleRateInHz, int channelConfig, int audioFormat)2576     static private native final int native_get_min_buff_size(
2577             int sampleRateInHz, int channelConfig, int audioFormat);
2578 
native_attachAuxEffect(int effectId)2579     private native final int native_attachAuxEffect(int effectId);
native_setAuxEffectSendLevel(float level)2580     private native final int native_setAuxEffectSendLevel(float level);
2581 
native_setOutputDevice(int deviceId)2582     private native final boolean native_setOutputDevice(int deviceId);
native_getRoutedDeviceId()2583     private native final int native_getRoutedDeviceId();
native_enableDeviceCallback()2584     private native final void native_enableDeviceCallback();
native_disableDeviceCallback()2585     private native final void native_disableDeviceCallback();
2586 
2587     //---------------------------------------------------------
2588     // Utility methods
2589     //------------------
2590 
logd(String msg)2591     private static void logd(String msg) {
2592         Log.d(TAG, msg);
2593     }
2594 
loge(String msg)2595     private static void loge(String msg) {
2596         Log.e(TAG, msg);
2597     }
2598 }
2599