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 import java.util.concurrent.Executor;
28 
29 import android.annotation.CallbackExecutor;
30 import android.annotation.IntDef;
31 import android.annotation.NonNull;
32 import android.annotation.Nullable;
33 import android.app.ActivityThread;
34 import android.content.Context;
35 import android.os.Handler;
36 import android.os.IBinder;
37 import android.os.Looper;
38 import android.os.Message;
39 import android.os.PersistableBundle;
40 import android.os.Process;
41 import android.os.RemoteException;
42 import android.os.ServiceManager;
43 import android.util.ArrayMap;
44 import android.util.Log;
45 
46 import com.android.internal.annotations.GuardedBy;
47 
48 /**
49  * The AudioTrack class manages and plays a single audio resource for Java applications.
50  * It allows streaming of PCM audio buffers to the audio sink for playback. This is
51  * achieved by "pushing" the data to the AudioTrack object using one of the
52  *  {@link #write(byte[], int, int)}, {@link #write(short[], int, int)},
53  *  and {@link #write(float[], int, int, int)} methods.
54  *
55  * <p>An AudioTrack instance can operate under two modes: static or streaming.<br>
56  * In Streaming mode, the application writes a continuous stream of data to the AudioTrack, using
57  * one of the {@code write()} methods. These are blocking and return when the data has been
58  * transferred from the Java layer to the native layer and queued for playback. The streaming
59  * mode is most useful when playing blocks of audio data that for instance are:
60  *
61  * <ul>
62  *   <li>too big to fit in memory because of the duration of the sound to play,</li>
63  *   <li>too big to fit in memory because of the characteristics of the audio data
64  *         (high sampling rate, bits per sample ...)</li>
65  *   <li>received or generated while previously queued audio is playing.</li>
66  * </ul>
67  *
68  * The static mode should be chosen when dealing with short sounds that fit in memory and
69  * that need to be played with the smallest latency possible. The static mode will
70  * therefore be preferred for UI and game sounds that are played often, and with the
71  * smallest overhead possible.
72  *
73  * <p>Upon creation, an AudioTrack object initializes its associated audio buffer.
74  * The size of this buffer, specified during the construction, determines how long an AudioTrack
75  * can play before running out of data.<br>
76  * For an AudioTrack using the static mode, this size is the maximum size of the sound that can
77  * be played from it.<br>
78  * For the streaming mode, data will be written to the audio sink in chunks of
79  * sizes less than or equal to the total buffer size.
80  *
81  * AudioTrack is not final and thus permits subclasses, but such use is not recommended.
82  */
83 public class AudioTrack extends PlayerBase
84                         implements AudioRouting
85                                  , VolumeAutomation
86 {
87     //---------------------------------------------------------
88     // Constants
89     //--------------------
90     /** Minimum value for a linear gain or auxiliary effect level.
91      *  This value must be exactly equal to 0.0f; do not change it.
92      */
93     private static final float GAIN_MIN = 0.0f;
94     /** Maximum value for a linear gain or auxiliary effect level.
95      *  This value must be greater than or equal to 1.0f.
96      */
97     private static final float GAIN_MAX = 1.0f;
98 
99     /** Maximum value for AudioTrack channel count
100      * @hide public for MediaCode only, do not un-hide or change to a numeric literal
101      */
102     public static final int CHANNEL_COUNT_MAX = native_get_FCC_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      */
165     public  static final int ERROR_DEAD_OBJECT                     = AudioSystem.DEAD_OBJECT;
166     /**
167      * {@link #getTimestampWithStatus(AudioTimestamp)} is called in STOPPED or FLUSHED state,
168      * or immediately after start/ACTIVE.
169      * @hide
170      */
171     public  static final int ERROR_WOULD_BLOCK                     = AudioSystem.WOULD_BLOCK;
172 
173     // Error codes:
174     // to keep in sync with frameworks/base/core/jni/android_media_AudioTrack.cpp
175     private static final int ERROR_NATIVESETUP_AUDIOSYSTEM         = -16;
176     private static final int ERROR_NATIVESETUP_INVALIDCHANNELMASK  = -17;
177     private static final int ERROR_NATIVESETUP_INVALIDFORMAT       = -18;
178     private static final int ERROR_NATIVESETUP_INVALIDSTREAMTYPE   = -19;
179     private static final int ERROR_NATIVESETUP_NATIVEINITFAILED    = -20;
180 
181     // Events:
182     // to keep in sync with frameworks/av/include/media/AudioTrack.h
183     /**
184      * Event id denotes when playback head has reached a previously set marker.
185      */
186     private static final int NATIVE_EVENT_MARKER  = 3;
187     /**
188      * Event id denotes when previously set update period has elapsed during playback.
189      */
190     private static final int NATIVE_EVENT_NEW_POS = 4;
191     /**
192      * Callback for more data
193      * TODO only for offload
194      */
195     private static final int NATIVE_EVENT_MORE_DATA = 0;
196     /**
197      * IAudioTrack tear down for offloaded tracks
198      * TODO: when received, java AudioTrack must be released
199      */
200     private static final int NATIVE_EVENT_NEW_IAUDIOTRACK = 6;
201     /**
202      * Event id denotes when all the buffers queued in AF and HW are played
203      * back (after stop is called) for an offloaded track.
204      * TODO: not just for offload
205      */
206     private static final int NATIVE_EVENT_STREAM_END = 7;
207 
208     private final static String TAG = "android.media.AudioTrack";
209 
210 
211     /** @hide */
212     @IntDef({
213         WRITE_BLOCKING,
214         WRITE_NON_BLOCKING
215     })
216     @Retention(RetentionPolicy.SOURCE)
217     public @interface WriteMode {}
218 
219     /**
220      * The write mode indicating the write operation will block until all data has been written,
221      * to be used as the actual value of the writeMode parameter in
222      * {@link #write(byte[], int, int, int)}, {@link #write(short[], int, int, int)},
223      * {@link #write(float[], int, int, int)}, {@link #write(ByteBuffer, int, int)}, and
224      * {@link #write(ByteBuffer, int, int, long)}.
225      */
226     public final static int WRITE_BLOCKING = 0;
227 
228     /**
229      * The write mode indicating the write operation will return immediately after
230      * queuing as much audio data for playback as possible without blocking,
231      * to be used as the actual value of the writeMode parameter in
232      * {@link #write(ByteBuffer, int, int)}, {@link #write(short[], int, int, int)},
233      * {@link #write(float[], int, int, int)}, {@link #write(ByteBuffer, int, int)}, and
234      * {@link #write(ByteBuffer, int, int, long)}.
235      */
236     public final static int WRITE_NON_BLOCKING = 1;
237 
238     /** @hide */
239     @IntDef({
240         PERFORMANCE_MODE_NONE,
241         PERFORMANCE_MODE_LOW_LATENCY,
242         PERFORMANCE_MODE_POWER_SAVING
243     })
244     @Retention(RetentionPolicy.SOURCE)
245     public @interface PerformanceMode {}
246 
247     /**
248      * Default performance mode for an {@link AudioTrack}.
249      */
250     public static final int PERFORMANCE_MODE_NONE = 0;
251 
252     /**
253      * Low latency performance mode for an {@link AudioTrack}.
254      * If the device supports it, this mode
255      * enables a lower latency path through to the audio output sink.
256      * Effects may no longer work with such an {@code AudioTrack} and
257      * the sample rate must match that of the output sink.
258      * <p>
259      * Applications should be aware that low latency requires careful
260      * buffer management, with smaller chunks of audio data written by each
261      * {@code write()} call.
262      * <p>
263      * If this flag is used without specifying a {@code bufferSizeInBytes} then the
264      * {@code AudioTrack}'s actual buffer size may be too small.
265      * It is recommended that a fairly
266      * large buffer should be specified when the {@code AudioTrack} is created.
267      * Then the actual size can be reduced by calling
268      * {@link #setBufferSizeInFrames(int)}. The buffer size can be optimized
269      * by lowering it after each {@code write()} call until the audio glitches,
270      * which is detected by calling
271      * {@link #getUnderrunCount()}. Then the buffer size can be increased
272      * until there are no glitches.
273      * This tuning step should be done while playing silence.
274      * This technique provides a compromise between latency and glitch rate.
275      */
276     public static final int PERFORMANCE_MODE_LOW_LATENCY = 1;
277 
278     /**
279      * Power saving performance mode for an {@link AudioTrack}.
280      * If the device supports it, this
281      * mode will enable a lower power path to the audio output sink.
282      * In addition, this lower power path typically will have
283      * deeper internal buffers and better underrun resistance,
284      * with a tradeoff of higher latency.
285      * <p>
286      * In this mode, applications should attempt to use a larger buffer size
287      * and deliver larger chunks of audio data per {@code write()} call.
288      * Use {@link #getBufferSizeInFrames()} to determine
289      * the actual buffer size of the {@code AudioTrack} as it may have increased
290      * to accommodate a deeper buffer.
291      */
292     public static final int PERFORMANCE_MODE_POWER_SAVING = 2;
293 
294     // keep in sync with system/media/audio/include/system/audio-base.h
295     private static final int AUDIO_OUTPUT_FLAG_FAST = 0x4;
296     private static final int AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8;
297 
298     // Size of HW_AV_SYNC track AV header.
299     private static final float HEADER_V2_SIZE_BYTES = 20.0f;
300 
301     //--------------------------------------------------------------------------
302     // Member variables
303     //--------------------
304     /**
305      * Indicates the state of the AudioTrack instance.
306      * One of STATE_UNINITIALIZED, STATE_INITIALIZED, or STATE_NO_STATIC_DATA.
307      */
308     private int mState = STATE_UNINITIALIZED;
309     /**
310      * Indicates the play state of the AudioTrack instance.
311      * One of PLAYSTATE_STOPPED, PLAYSTATE_PAUSED, or PLAYSTATE_PLAYING.
312      */
313     private int mPlayState = PLAYSTATE_STOPPED;
314     /**
315      * Lock to ensure mPlayState updates reflect the actual state of the object.
316      */
317     private final Object mPlayStateLock = new Object();
318     /**
319      * Sizes of the audio buffer.
320      * These values are set during construction and can be stale.
321      * To obtain the current audio buffer frame count use {@link #getBufferSizeInFrames()}.
322      */
323     private int mNativeBufferSizeInBytes = 0;
324     private int mNativeBufferSizeInFrames = 0;
325     /**
326      * Handler for events coming from the native code.
327      */
328     private NativePositionEventHandlerDelegate mEventHandlerDelegate;
329     /**
330      * Looper associated with the thread that creates the AudioTrack instance.
331      */
332     private final Looper mInitializationLooper;
333     /**
334      * The audio data source sampling rate in Hz.
335      * Never {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED}.
336      */
337     private int mSampleRate; // initialized by all constructors via audioParamCheck()
338     /**
339      * The number of audio output channels (1 is mono, 2 is stereo, etc.).
340      */
341     private int mChannelCount = 1;
342     /**
343      * The audio channel mask used for calling native AudioTrack
344      */
345     private int mChannelMask = AudioFormat.CHANNEL_OUT_MONO;
346 
347     /**
348      * The type of the audio stream to play. See
349      *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
350      *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
351      *   {@link AudioManager#STREAM_ALARM}, {@link AudioManager#STREAM_NOTIFICATION}, and
352      *   {@link AudioManager#STREAM_DTMF}.
353      */
354     private int mStreamType = AudioManager.STREAM_MUSIC;
355 
356     /**
357      * The way audio is consumed by the audio sink, one of MODE_STATIC or MODE_STREAM.
358      */
359     private int mDataLoadMode = MODE_STREAM;
360     /**
361      * The current channel position mask, as specified on AudioTrack creation.
362      * Can be set simultaneously with channel index mask {@link #mChannelIndexMask}.
363      * May be set to {@link AudioFormat#CHANNEL_INVALID} if a channel index mask is specified.
364      */
365     private int mChannelConfiguration = AudioFormat.CHANNEL_OUT_MONO;
366     /**
367      * The channel index mask if specified, otherwise 0.
368      */
369     private int mChannelIndexMask = 0;
370     /**
371      * The encoding of the audio samples.
372      * @see AudioFormat#ENCODING_PCM_8BIT
373      * @see AudioFormat#ENCODING_PCM_16BIT
374      * @see AudioFormat#ENCODING_PCM_FLOAT
375      */
376     private int mAudioFormat;   // initialized by all constructors via audioParamCheck()
377     /**
378      * Audio session ID
379      */
380     private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
381     /**
382      * HW_AV_SYNC track AV Sync Header
383      */
384     private ByteBuffer mAvSyncHeader = null;
385     /**
386      * HW_AV_SYNC track audio data bytes remaining to write after current AV sync header
387      */
388     private int mAvSyncBytesRemaining = 0;
389     /**
390      * Offset of the first sample of the audio in byte from start of HW_AV_SYNC track AV header.
391      */
392     private int mOffset = 0;
393 
394     //--------------------------------
395     // Used exclusively by native code
396     //--------------------
397     /**
398      * @hide
399      * Accessed by native methods: provides access to C++ AudioTrack object.
400      */
401     @SuppressWarnings("unused")
402     protected long mNativeTrackInJavaObj;
403     /**
404      * Accessed by native methods: provides access to the JNI data (i.e. resources used by
405      * the native AudioTrack object, but not stored in it).
406      */
407     @SuppressWarnings("unused")
408     private long mJniData;
409 
410 
411     //--------------------------------------------------------------------------
412     // Constructor, Finalize
413     //--------------------
414     /**
415      * Class constructor.
416      * @param streamType the type of the audio stream. See
417      *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
418      *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
419      *   {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
420      * @param sampleRateInHz the initial source sample rate expressed in Hz.
421      *   {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} means to use a route-dependent value
422      *   which is usually the sample rate of the sink.
423      *   {@link #getSampleRate()} can be used to retrieve the actual sample rate chosen.
424      * @param channelConfig describes the configuration of the audio channels.
425      *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
426      *   {@link AudioFormat#CHANNEL_OUT_STEREO}
427      * @param audioFormat the format in which the audio data is represented.
428      *   See {@link AudioFormat#ENCODING_PCM_16BIT},
429      *   {@link AudioFormat#ENCODING_PCM_8BIT},
430      *   and {@link AudioFormat#ENCODING_PCM_FLOAT}.
431      * @param bufferSizeInBytes the total size (in bytes) of the internal buffer where audio data is
432      *   read from for playback. This should be a nonzero multiple of the frame size in bytes.
433      *   <p> If the track's creation mode is {@link #MODE_STATIC},
434      *   this is the maximum length sample, or audio clip, that can be played by this instance.
435      *   <p> If the track's creation mode is {@link #MODE_STREAM},
436      *   this should be the desired buffer size
437      *   for the <code>AudioTrack</code> to satisfy the application's
438      *   latency requirements.
439      *   If <code>bufferSizeInBytes</code> is less than the
440      *   minimum buffer size for the output sink, it is increased to the minimum
441      *   buffer size.
442      *   The method {@link #getBufferSizeInFrames()} returns the
443      *   actual size in frames of the buffer created, which
444      *   determines the minimum frequency to write
445      *   to the streaming <code>AudioTrack</code> to avoid underrun.
446      *   See {@link #getMinBufferSize(int, int, int)} to determine the estimated minimum buffer size
447      *   for an AudioTrack instance in streaming mode.
448      * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
449      * @throws java.lang.IllegalArgumentException
450      * @deprecated use {@link Builder} or
451      *   {@link #AudioTrack(AudioAttributes, AudioFormat, int, int, int)} to specify the
452      *   {@link AudioAttributes} instead of the stream type which is only for volume control.
453      */
AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode)454     public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
455             int bufferSizeInBytes, int mode)
456     throws IllegalArgumentException {
457         this(streamType, sampleRateInHz, channelConfig, audioFormat,
458                 bufferSizeInBytes, mode, AudioManager.AUDIO_SESSION_ID_GENERATE);
459     }
460 
461     /**
462      * Class constructor with audio session. Use this constructor when the AudioTrack must be
463      * attached to a particular audio session. The primary use of the audio session ID is to
464      * associate audio effects to a particular instance of AudioTrack: if an audio session ID
465      * is provided when creating an AudioEffect, this effect will be applied only to audio tracks
466      * and media players in the same session and not to the output mix.
467      * When an AudioTrack is created without specifying a session, it will create its own session
468      * which can be retrieved by calling the {@link #getAudioSessionId()} method.
469      * If a non-zero session ID is provided, this AudioTrack will share effects attached to this
470      * session
471      * with all other media players or audio tracks in the same session, otherwise a new session
472      * will be created for this track if none is supplied.
473      * @param streamType the type of the audio stream. See
474      *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
475      *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
476      *   {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
477      * @param sampleRateInHz the initial source sample rate expressed in Hz.
478      *   {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} means to use a route-dependent value
479      *   which is usually the sample rate of the sink.
480      * @param channelConfig describes the configuration of the audio channels.
481      *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
482      *   {@link AudioFormat#CHANNEL_OUT_STEREO}
483      * @param audioFormat the format in which the audio data is represented.
484      *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
485      *   {@link AudioFormat#ENCODING_PCM_8BIT},
486      *   and {@link AudioFormat#ENCODING_PCM_FLOAT}.
487      * @param bufferSizeInBytes the total size (in bytes) of the internal buffer where audio data is
488      *   read from for playback. This should be a nonzero multiple of the frame size in bytes.
489      *   <p> If the track's creation mode is {@link #MODE_STATIC},
490      *   this is the maximum length sample, or audio clip, that can be played by this instance.
491      *   <p> If the track's creation mode is {@link #MODE_STREAM},
492      *   this should be the desired buffer size
493      *   for the <code>AudioTrack</code> to satisfy the application's
494      *   latency requirements.
495      *   If <code>bufferSizeInBytes</code> is less than the
496      *   minimum buffer size for the output sink, it is increased to the minimum
497      *   buffer size.
498      *   The method {@link #getBufferSizeInFrames()} returns the
499      *   actual size in frames of the buffer created, which
500      *   determines the minimum frequency to write
501      *   to the streaming <code>AudioTrack</code> to avoid underrun.
502      *   You can write data into this buffer in smaller chunks than this size.
503      *   See {@link #getMinBufferSize(int, int, int)} to determine the estimated minimum buffer size
504      *   for an AudioTrack instance in streaming mode.
505      * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
506      * @param sessionId Id of audio session the AudioTrack must be attached to
507      * @throws java.lang.IllegalArgumentException
508      * @deprecated use {@link Builder} or
509      *   {@link #AudioTrack(AudioAttributes, AudioFormat, int, int, int)} to specify the
510      *   {@link AudioAttributes} instead of the stream type which is only for volume control.
511      */
AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode, int sessionId)512     public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
513             int bufferSizeInBytes, int mode, int sessionId)
514     throws IllegalArgumentException {
515         // mState already == STATE_UNINITIALIZED
516         this((new AudioAttributes.Builder())
517                     .setLegacyStreamType(streamType)
518                     .build(),
519                 (new AudioFormat.Builder())
520                     .setChannelMask(channelConfig)
521                     .setEncoding(audioFormat)
522                     .setSampleRate(sampleRateInHz)
523                     .build(),
524                 bufferSizeInBytes,
525                 mode, sessionId);
526         deprecateStreamTypeForPlayback(streamType, "AudioTrack", "AudioTrack()");
527     }
528 
529     /**
530      * Class constructor with {@link AudioAttributes} and {@link AudioFormat}.
531      * @param attributes a non-null {@link AudioAttributes} instance.
532      * @param format a non-null {@link AudioFormat} instance describing the format of the data
533      *     that will be played through this AudioTrack. See {@link AudioFormat.Builder} for
534      *     configuring the audio format parameters such as encoding, channel mask and sample rate.
535      * @param bufferSizeInBytes the total size (in bytes) of the internal buffer where audio data is
536      *   read from for playback. This should be a nonzero multiple of the frame size in bytes.
537      *   <p> If the track's creation mode is {@link #MODE_STATIC},
538      *   this is the maximum length sample, or audio clip, that can be played by this instance.
539      *   <p> If the track's creation mode is {@link #MODE_STREAM},
540      *   this should be the desired buffer size
541      *   for the <code>AudioTrack</code> to satisfy the application's
542      *   latency requirements.
543      *   If <code>bufferSizeInBytes</code> is less than the
544      *   minimum buffer size for the output sink, it is increased to the minimum
545      *   buffer size.
546      *   The method {@link #getBufferSizeInFrames()} returns the
547      *   actual size in frames of the buffer created, which
548      *   determines the minimum frequency to write
549      *   to the streaming <code>AudioTrack</code> to avoid underrun.
550      *   See {@link #getMinBufferSize(int, int, int)} to determine the estimated minimum buffer size
551      *   for an AudioTrack instance in streaming mode.
552      * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}.
553      * @param sessionId ID of audio session the AudioTrack must be attached to, or
554      *   {@link AudioManager#AUDIO_SESSION_ID_GENERATE} if the session isn't known at construction
555      *   time. See also {@link AudioManager#generateAudioSessionId()} to obtain a session ID before
556      *   construction.
557      * @throws IllegalArgumentException
558      */
AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes, int mode, int sessionId)559     public AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
560             int mode, int sessionId)
561                     throws IllegalArgumentException {
562         this(attributes, format, bufferSizeInBytes, mode, sessionId, false /*offload*/);
563     }
564 
AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes, int mode, int sessionId, boolean offload)565     private AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
566             int mode, int sessionId, boolean offload)
567                     throws IllegalArgumentException {
568         super(attributes, AudioPlaybackConfiguration.PLAYER_TYPE_JAM_AUDIOTRACK);
569         // mState already == STATE_UNINITIALIZED
570 
571         if (format == null) {
572             throw new IllegalArgumentException("Illegal null AudioFormat");
573         }
574 
575         // Check if we should enable deep buffer mode
576         if (shouldEnablePowerSaving(mAttributes, format, bufferSizeInBytes, mode)) {
577             mAttributes = new AudioAttributes.Builder(mAttributes)
578                 .replaceFlags((mAttributes.getAllFlags()
579                         | AudioAttributes.FLAG_DEEP_BUFFER)
580                         & ~AudioAttributes.FLAG_LOW_LATENCY)
581                 .build();
582         }
583 
584         // remember which looper is associated with the AudioTrack instantiation
585         Looper looper;
586         if ((looper = Looper.myLooper()) == null) {
587             looper = Looper.getMainLooper();
588         }
589 
590         int rate = format.getSampleRate();
591         if (rate == AudioFormat.SAMPLE_RATE_UNSPECIFIED) {
592             rate = 0;
593         }
594 
595         int channelIndexMask = 0;
596         if ((format.getPropertySetMask()
597                 & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK) != 0) {
598             channelIndexMask = format.getChannelIndexMask();
599         }
600         int channelMask = 0;
601         if ((format.getPropertySetMask()
602                 & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) != 0) {
603             channelMask = format.getChannelMask();
604         } else if (channelIndexMask == 0) { // if no masks at all, use stereo
605             channelMask = AudioFormat.CHANNEL_OUT_FRONT_LEFT
606                     | AudioFormat.CHANNEL_OUT_FRONT_RIGHT;
607         }
608         int encoding = AudioFormat.ENCODING_DEFAULT;
609         if ((format.getPropertySetMask() & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_ENCODING) != 0) {
610             encoding = format.getEncoding();
611         }
612         audioParamCheck(rate, channelMask, channelIndexMask, encoding, mode);
613         mStreamType = AudioSystem.STREAM_DEFAULT;
614 
615         audioBuffSizeCheck(bufferSizeInBytes);
616 
617         mInitializationLooper = looper;
618 
619         if (sessionId < 0) {
620             throw new IllegalArgumentException("Invalid audio session ID: "+sessionId);
621         }
622 
623         int[] sampleRate = new int[] {mSampleRate};
624         int[] session = new int[1];
625         session[0] = sessionId;
626         // native initialization
627         int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes,
628                 sampleRate, mChannelMask, mChannelIndexMask, mAudioFormat,
629                 mNativeBufferSizeInBytes, mDataLoadMode, session, 0 /*nativeTrackInJavaObj*/,
630                 offload);
631         if (initResult != SUCCESS) {
632             loge("Error code "+initResult+" when initializing AudioTrack.");
633             return; // with mState == STATE_UNINITIALIZED
634         }
635 
636         mSampleRate = sampleRate[0];
637         mSessionId = session[0];
638 
639         if ((mAttributes.getFlags() & AudioAttributes.FLAG_HW_AV_SYNC) != 0) {
640             int frameSizeInBytes;
641             if (AudioFormat.isEncodingLinearFrames(mAudioFormat)) {
642                 frameSizeInBytes = mChannelCount * AudioFormat.getBytesPerSample(mAudioFormat);
643             } else {
644                 frameSizeInBytes = 1;
645             }
646             mOffset = ((int) Math.ceil(HEADER_V2_SIZE_BYTES / frameSizeInBytes)) * frameSizeInBytes;
647         }
648 
649         if (mDataLoadMode == MODE_STATIC) {
650             mState = STATE_NO_STATIC_DATA;
651         } else {
652             mState = STATE_INITIALIZED;
653         }
654 
655         baseRegisterPlayer();
656     }
657 
658     /**
659      * A constructor which explicitly connects a Native (C++) AudioTrack. For use by
660      * the AudioTrackRoutingProxy subclass.
661      * @param nativeTrackInJavaObj a C/C++ pointer to a native AudioTrack
662      * (associated with an OpenSL ES player).
663      * IMPORTANT: For "N", this method is ONLY called to setup a Java routing proxy,
664      * i.e. IAndroidConfiguration::AcquireJavaProxy(). If we call with a 0 in nativeTrackInJavaObj
665      * it means that the OpenSL player interface hasn't been realized, so there is no native
666      * Audiotrack to connect to. In this case wait to call deferred_connect() until the
667      * OpenSLES interface is realized.
668      */
AudioTrack(long nativeTrackInJavaObj)669     /*package*/ AudioTrack(long nativeTrackInJavaObj) {
670         super(new AudioAttributes.Builder().build(),
671                 AudioPlaybackConfiguration.PLAYER_TYPE_JAM_AUDIOTRACK);
672         // "final"s
673         mNativeTrackInJavaObj = 0;
674         mJniData = 0;
675 
676         // remember which looper is associated with the AudioTrack instantiation
677         Looper looper;
678         if ((looper = Looper.myLooper()) == null) {
679             looper = Looper.getMainLooper();
680         }
681         mInitializationLooper = looper;
682 
683         // other initialization...
684         if (nativeTrackInJavaObj != 0) {
685             baseRegisterPlayer();
686             deferred_connect(nativeTrackInJavaObj);
687         } else {
688             mState = STATE_UNINITIALIZED;
689         }
690     }
691 
692     /**
693      * @hide
694      */
deferred_connect(long nativeTrackInJavaObj)695     /* package */ void deferred_connect(long nativeTrackInJavaObj) {
696         if (mState != STATE_INITIALIZED) {
697             // Note that for this native_setup, we are providing an already created/initialized
698             // *Native* AudioTrack, so the attributes parameters to native_setup() are ignored.
699             int[] session = { 0 };
700             int[] rates = { 0 };
701             int initResult = native_setup(new WeakReference<AudioTrack>(this),
702                     null /*mAttributes - NA*/,
703                     rates /*sampleRate - NA*/,
704                     0 /*mChannelMask - NA*/,
705                     0 /*mChannelIndexMask - NA*/,
706                     0 /*mAudioFormat - NA*/,
707                     0 /*mNativeBufferSizeInBytes - NA*/,
708                     0 /*mDataLoadMode - NA*/,
709                     session,
710                     nativeTrackInJavaObj,
711                     false /*offload*/);
712             if (initResult != SUCCESS) {
713                 loge("Error code "+initResult+" when initializing AudioTrack.");
714                 return; // with mState == STATE_UNINITIALIZED
715             }
716 
717             mSessionId = session[0];
718 
719             mState = STATE_INITIALIZED;
720         }
721     }
722 
723     /**
724      * Builder class for {@link AudioTrack} objects.
725      * Use this class to configure and create an <code>AudioTrack</code> instance. By setting audio
726      * attributes and audio format parameters, you indicate which of those vary from the default
727      * behavior on the device.
728      * <p> Here is an example where <code>Builder</code> is used to specify all {@link AudioFormat}
729      * parameters, to be used by a new <code>AudioTrack</code> instance:
730      *
731      * <pre class="prettyprint">
732      * AudioTrack player = new AudioTrack.Builder()
733      *         .setAudioAttributes(new AudioAttributes.Builder()
734      *                  .setUsage(AudioAttributes.USAGE_ALARM)
735      *                  .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
736      *                  .build())
737      *         .setAudioFormat(new AudioFormat.Builder()
738      *                 .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
739      *                 .setSampleRate(44100)
740      *                 .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
741      *                 .build())
742      *         .setBufferSizeInBytes(minBuffSize)
743      *         .build();
744      * </pre>
745      * <p>
746      * If the audio attributes are not set with {@link #setAudioAttributes(AudioAttributes)},
747      * attributes comprising {@link AudioAttributes#USAGE_MEDIA} will be used.
748      * <br>If the audio format is not specified or is incomplete, its channel configuration will be
749      * {@link AudioFormat#CHANNEL_OUT_STEREO} and the encoding will be
750      * {@link AudioFormat#ENCODING_PCM_16BIT}.
751      * The sample rate will depend on the device actually selected for playback and can be queried
752      * with {@link #getSampleRate()} method.
753      * <br>If the buffer size is not specified with {@link #setBufferSizeInBytes(int)},
754      * and the mode is {@link AudioTrack#MODE_STREAM}, the minimum buffer size is used.
755      * <br>If the transfer mode is not specified with {@link #setTransferMode(int)},
756      * <code>MODE_STREAM</code> will be used.
757      * <br>If the session ID is not specified with {@link #setSessionId(int)}, a new one will
758      * be generated.
759      * <br>Offload is false by default.
760      */
761     public static class Builder {
762         private AudioAttributes mAttributes;
763         private AudioFormat mFormat;
764         private int mBufferSizeInBytes;
765         private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
766         private int mMode = MODE_STREAM;
767         private int mPerformanceMode = PERFORMANCE_MODE_NONE;
768         private boolean mOffload = false;
769 
770         /**
771          * Constructs a new Builder with the default values as described above.
772          */
Builder()773         public Builder() {
774         }
775 
776         /**
777          * Sets the {@link AudioAttributes}.
778          * @param attributes a non-null {@link AudioAttributes} instance that describes the audio
779          *     data to be played.
780          * @return the same Builder instance.
781          * @throws IllegalArgumentException
782          */
setAudioAttributes(@onNull AudioAttributes attributes)783         public @NonNull Builder setAudioAttributes(@NonNull AudioAttributes attributes)
784                 throws IllegalArgumentException {
785             if (attributes == null) {
786                 throw new IllegalArgumentException("Illegal null AudioAttributes argument");
787             }
788             // keep reference, we only copy the data when building
789             mAttributes = attributes;
790             return this;
791         }
792 
793         /**
794          * Sets the format of the audio data to be played by the {@link AudioTrack}.
795          * See {@link AudioFormat.Builder} for configuring the audio format parameters such
796          * as encoding, channel mask and sample rate.
797          * @param format a non-null {@link AudioFormat} instance.
798          * @return the same Builder instance.
799          * @throws IllegalArgumentException
800          */
setAudioFormat(@onNull AudioFormat format)801         public @NonNull Builder setAudioFormat(@NonNull AudioFormat format)
802                 throws IllegalArgumentException {
803             if (format == null) {
804                 throw new IllegalArgumentException("Illegal null AudioFormat argument");
805             }
806             // keep reference, we only copy the data when building
807             mFormat = format;
808             return this;
809         }
810 
811         /**
812          * Sets the total size (in bytes) of the buffer where audio data is read from for playback.
813          * If using the {@link AudioTrack} in streaming mode
814          * (see {@link AudioTrack#MODE_STREAM}, you can write data into this buffer in smaller
815          * chunks than this size. See {@link #getMinBufferSize(int, int, int)} to determine
816          * the estimated minimum buffer size for the creation of an AudioTrack instance
817          * in streaming mode.
818          * <br>If using the <code>AudioTrack</code> in static mode (see
819          * {@link AudioTrack#MODE_STATIC}), this is the maximum size of the sound that will be
820          * played by this instance.
821          * @param bufferSizeInBytes
822          * @return the same Builder instance.
823          * @throws IllegalArgumentException
824          */
setBufferSizeInBytes(int bufferSizeInBytes)825         public @NonNull Builder setBufferSizeInBytes(int bufferSizeInBytes)
826                 throws IllegalArgumentException {
827             if (bufferSizeInBytes <= 0) {
828                 throw new IllegalArgumentException("Invalid buffer size " + bufferSizeInBytes);
829             }
830             mBufferSizeInBytes = bufferSizeInBytes;
831             return this;
832         }
833 
834         /**
835          * Sets the mode under which buffers of audio data are transferred from the
836          * {@link AudioTrack} to the framework.
837          * @param mode one of {@link AudioTrack#MODE_STREAM}, {@link AudioTrack#MODE_STATIC}.
838          * @return the same Builder instance.
839          * @throws IllegalArgumentException
840          */
setTransferMode(@ransferMode int mode)841         public @NonNull Builder setTransferMode(@TransferMode int mode)
842                 throws IllegalArgumentException {
843             switch(mode) {
844                 case MODE_STREAM:
845                 case MODE_STATIC:
846                     mMode = mode;
847                     break;
848                 default:
849                     throw new IllegalArgumentException("Invalid transfer mode " + mode);
850             }
851             return this;
852         }
853 
854         /**
855          * Sets the session ID the {@link AudioTrack} will be attached to.
856          * @param sessionId a strictly positive ID number retrieved from another
857          *     <code>AudioTrack</code> via {@link AudioTrack#getAudioSessionId()} or allocated by
858          *     {@link AudioManager} via {@link AudioManager#generateAudioSessionId()}, or
859          *     {@link AudioManager#AUDIO_SESSION_ID_GENERATE}.
860          * @return the same Builder instance.
861          * @throws IllegalArgumentException
862          */
setSessionId(int sessionId)863         public @NonNull Builder setSessionId(int sessionId)
864                 throws IllegalArgumentException {
865             if ((sessionId != AudioManager.AUDIO_SESSION_ID_GENERATE) && (sessionId < 1)) {
866                 throw new IllegalArgumentException("Invalid audio session ID " + sessionId);
867             }
868             mSessionId = sessionId;
869             return this;
870         }
871 
872         /**
873          * Sets the {@link AudioTrack} performance mode.  This is an advisory request which
874          * may not be supported by the particular device, and the framework is free
875          * to ignore such request if it is incompatible with other requests or hardware.
876          *
877          * @param performanceMode one of
878          * {@link AudioTrack#PERFORMANCE_MODE_NONE},
879          * {@link AudioTrack#PERFORMANCE_MODE_LOW_LATENCY},
880          * or {@link AudioTrack#PERFORMANCE_MODE_POWER_SAVING}.
881          * @return the same Builder instance.
882          * @throws IllegalArgumentException if {@code performanceMode} is not valid.
883          */
setPerformanceMode(@erformanceMode int performanceMode)884         public @NonNull Builder setPerformanceMode(@PerformanceMode int performanceMode) {
885             switch (performanceMode) {
886                 case PERFORMANCE_MODE_NONE:
887                 case PERFORMANCE_MODE_LOW_LATENCY:
888                 case PERFORMANCE_MODE_POWER_SAVING:
889                     mPerformanceMode = performanceMode;
890                     break;
891                 default:
892                     throw new IllegalArgumentException(
893                             "Invalid performance mode " + performanceMode);
894             }
895             return this;
896         }
897 
898         /**
899          * @hide
900          * Sets whether this track will play through the offloaded audio path.
901          * When set to true, at build time, the audio format will be checked against
902          * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat)} to verify the audio format
903          * used by this track is supported on the device's offload path (if any).
904          * <br>Offload is only supported for media audio streams, and therefore requires that
905          * the usage be {@link AudioAttributes#USAGE_MEDIA}.
906          * @param offload true to require the offload path for playback.
907          * @return the same Builder instance.
908          */
setOffloadedPlayback(boolean offload)909         public @NonNull Builder setOffloadedPlayback(boolean offload) {
910             mOffload = offload;
911             return this;
912         }
913 
914         /**
915          * Builds an {@link AudioTrack} instance initialized with all the parameters set
916          * on this <code>Builder</code>.
917          * @return a new successfully initialized {@link AudioTrack} instance.
918          * @throws UnsupportedOperationException if the parameters set on the <code>Builder</code>
919          *     were incompatible, or if they are not supported by the device,
920          *     or if the device was not available.
921          */
build()922         public @NonNull AudioTrack build() throws UnsupportedOperationException {
923             if (mAttributes == null) {
924                 mAttributes = new AudioAttributes.Builder()
925                         .setUsage(AudioAttributes.USAGE_MEDIA)
926                         .build();
927             }
928             switch (mPerformanceMode) {
929             case PERFORMANCE_MODE_LOW_LATENCY:
930                 mAttributes = new AudioAttributes.Builder(mAttributes)
931                     .replaceFlags((mAttributes.getAllFlags()
932                             | AudioAttributes.FLAG_LOW_LATENCY)
933                             & ~AudioAttributes.FLAG_DEEP_BUFFER)
934                     .build();
935                 break;
936             case PERFORMANCE_MODE_NONE:
937                 if (!shouldEnablePowerSaving(mAttributes, mFormat, mBufferSizeInBytes, mMode)) {
938                     break; // do not enable deep buffer mode.
939                 }
940                 // permitted to fall through to enable deep buffer
941             case PERFORMANCE_MODE_POWER_SAVING:
942                 mAttributes = new AudioAttributes.Builder(mAttributes)
943                 .replaceFlags((mAttributes.getAllFlags()
944                         | AudioAttributes.FLAG_DEEP_BUFFER)
945                         & ~AudioAttributes.FLAG_LOW_LATENCY)
946                 .build();
947                 break;
948             }
949 
950             if (mFormat == null) {
951                 mFormat = new AudioFormat.Builder()
952                         .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
953                         //.setSampleRate(AudioFormat.SAMPLE_RATE_UNSPECIFIED)
954                         .setEncoding(AudioFormat.ENCODING_DEFAULT)
955                         .build();
956             }
957 
958             //TODO tie offload to PERFORMANCE_MODE_POWER_SAVING?
959             if (mOffload) {
960                 if (mAttributes.getUsage() != AudioAttributes.USAGE_MEDIA) {
961                     throw new UnsupportedOperationException(
962                             "Cannot create AudioTrack, offload requires USAGE_MEDIA");
963                 }
964                 if (!AudioSystem.isOffloadSupported(mFormat)) {
965                     throw new UnsupportedOperationException(
966                             "Cannot create AudioTrack, offload format not supported");
967                 }
968             }
969 
970             try {
971                 // If the buffer size is not specified in streaming mode,
972                 // use a single frame for the buffer size and let the
973                 // native code figure out the minimum buffer size.
974                 if (mMode == MODE_STREAM && mBufferSizeInBytes == 0) {
975                     mBufferSizeInBytes = mFormat.getChannelCount()
976                             * mFormat.getBytesPerSample(mFormat.getEncoding());
977                 }
978                 final AudioTrack track = new AudioTrack(
979                         mAttributes, mFormat, mBufferSizeInBytes, mMode, mSessionId, mOffload);
980                 if (track.getState() == STATE_UNINITIALIZED) {
981                     // release is not necessary
982                     throw new UnsupportedOperationException("Cannot create AudioTrack");
983                 }
984                 return track;
985             } catch (IllegalArgumentException e) {
986                 throw new UnsupportedOperationException(e.getMessage());
987             }
988         }
989     }
990 
991     // mask of all the positional channels supported, however the allowed combinations
992     // are further restricted by the matching left/right rule and CHANNEL_COUNT_MAX
993     private static final int SUPPORTED_OUT_CHANNELS =
994             AudioFormat.CHANNEL_OUT_FRONT_LEFT |
995             AudioFormat.CHANNEL_OUT_FRONT_RIGHT |
996             AudioFormat.CHANNEL_OUT_FRONT_CENTER |
997             AudioFormat.CHANNEL_OUT_LOW_FREQUENCY |
998             AudioFormat.CHANNEL_OUT_BACK_LEFT |
999             AudioFormat.CHANNEL_OUT_BACK_RIGHT |
1000             AudioFormat.CHANNEL_OUT_BACK_CENTER |
1001             AudioFormat.CHANNEL_OUT_SIDE_LEFT |
1002             AudioFormat.CHANNEL_OUT_SIDE_RIGHT;
1003 
1004     // Returns a boolean whether the attributes, format, bufferSizeInBytes, mode allow
1005     // power saving to be automatically enabled for an AudioTrack. Returns false if
1006     // power saving is already enabled in the attributes parameter.
shouldEnablePowerSaving( @ullable AudioAttributes attributes, @Nullable AudioFormat format, int bufferSizeInBytes, int mode)1007     private static boolean shouldEnablePowerSaving(
1008             @Nullable AudioAttributes attributes, @Nullable AudioFormat format,
1009             int bufferSizeInBytes, int mode) {
1010         // If no attributes, OK
1011         // otherwise check attributes for USAGE_MEDIA and CONTENT_UNKNOWN, MUSIC, or MOVIE.
1012         if (attributes != null &&
1013                 (attributes.getAllFlags() != 0  // cannot have any special flags
1014                 || attributes.getUsage() != AudioAttributes.USAGE_MEDIA
1015                 || (attributes.getContentType() != AudioAttributes.CONTENT_TYPE_UNKNOWN
1016                     && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MUSIC
1017                     && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MOVIE))) {
1018             return false;
1019         }
1020 
1021         // Format must be fully specified and be linear pcm
1022         if (format == null
1023                 || format.getSampleRate() == AudioFormat.SAMPLE_RATE_UNSPECIFIED
1024                 || !AudioFormat.isEncodingLinearPcm(format.getEncoding())
1025                 || !AudioFormat.isValidEncoding(format.getEncoding())
1026                 || format.getChannelCount() < 1) {
1027             return false;
1028         }
1029 
1030         // Mode must be streaming
1031         if (mode != MODE_STREAM) {
1032             return false;
1033         }
1034 
1035         // A buffer size of 0 is always compatible with deep buffer (when called from the Builder)
1036         // but for app compatibility we only use deep buffer power saving for large buffer sizes.
1037         if (bufferSizeInBytes != 0) {
1038             final long BUFFER_TARGET_MODE_STREAM_MS = 100;
1039             final int MILLIS_PER_SECOND = 1000;
1040             final long bufferTargetSize =
1041                     BUFFER_TARGET_MODE_STREAM_MS
1042                     * format.getChannelCount()
1043                     * format.getBytesPerSample(format.getEncoding())
1044                     * format.getSampleRate()
1045                     / MILLIS_PER_SECOND;
1046             if (bufferSizeInBytes < bufferTargetSize) {
1047                 return false;
1048             }
1049         }
1050 
1051         return true;
1052     }
1053 
1054     // Convenience method for the constructor's parameter checks.
1055     // This is where constructor IllegalArgumentException-s are thrown
1056     // postconditions:
1057     //    mChannelCount is valid
1058     //    mChannelMask is valid
1059     //    mAudioFormat is valid
1060     //    mSampleRate is valid
1061     //    mDataLoadMode is valid
audioParamCheck(int sampleRateInHz, int channelConfig, int channelIndexMask, int audioFormat, int mode)1062     private void audioParamCheck(int sampleRateInHz, int channelConfig, int channelIndexMask,
1063                                  int audioFormat, int mode) {
1064         //--------------
1065         // sample rate, note these values are subject to change
1066         if ((sampleRateInHz < AudioFormat.SAMPLE_RATE_HZ_MIN ||
1067                 sampleRateInHz > AudioFormat.SAMPLE_RATE_HZ_MAX) &&
1068                 sampleRateInHz != AudioFormat.SAMPLE_RATE_UNSPECIFIED) {
1069             throw new IllegalArgumentException(sampleRateInHz
1070                     + "Hz is not a supported sample rate.");
1071         }
1072         mSampleRate = sampleRateInHz;
1073 
1074         // IEC61937 is based on stereo. We could coerce it to stereo.
1075         // But the application needs to know the stream is stereo so that
1076         // it is encoded and played correctly. So better to just reject it.
1077         if (audioFormat == AudioFormat.ENCODING_IEC61937
1078                 && channelConfig != AudioFormat.CHANNEL_OUT_STEREO) {
1079             throw new IllegalArgumentException(
1080                     "ENCODING_IEC61937 must be configured as CHANNEL_OUT_STEREO");
1081         }
1082 
1083         //--------------
1084         // channel config
1085         mChannelConfiguration = channelConfig;
1086 
1087         switch (channelConfig) {
1088         case AudioFormat.CHANNEL_OUT_DEFAULT: //AudioFormat.CHANNEL_CONFIGURATION_DEFAULT
1089         case AudioFormat.CHANNEL_OUT_MONO:
1090         case AudioFormat.CHANNEL_CONFIGURATION_MONO:
1091             mChannelCount = 1;
1092             mChannelMask = AudioFormat.CHANNEL_OUT_MONO;
1093             break;
1094         case AudioFormat.CHANNEL_OUT_STEREO:
1095         case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
1096             mChannelCount = 2;
1097             mChannelMask = AudioFormat.CHANNEL_OUT_STEREO;
1098             break;
1099         default:
1100             if (channelConfig == AudioFormat.CHANNEL_INVALID && channelIndexMask != 0) {
1101                 mChannelCount = 0;
1102                 break; // channel index configuration only
1103             }
1104             if (!isMultichannelConfigSupported(channelConfig)) {
1105                 // input channel configuration features unsupported channels
1106                 throw new IllegalArgumentException("Unsupported channel configuration.");
1107             }
1108             mChannelMask = channelConfig;
1109             mChannelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
1110         }
1111         // check the channel index configuration (if present)
1112         mChannelIndexMask = channelIndexMask;
1113         if (mChannelIndexMask != 0) {
1114             // restrictive: indexMask could allow up to AUDIO_CHANNEL_BITS_LOG2
1115             final int indexMask = (1 << CHANNEL_COUNT_MAX) - 1;
1116             if ((channelIndexMask & ~indexMask) != 0) {
1117                 throw new IllegalArgumentException("Unsupported channel index configuration "
1118                         + channelIndexMask);
1119             }
1120             int channelIndexCount = Integer.bitCount(channelIndexMask);
1121             if (mChannelCount == 0) {
1122                  mChannelCount = channelIndexCount;
1123             } else if (mChannelCount != channelIndexCount) {
1124                 throw new IllegalArgumentException("Channel count must match");
1125             }
1126         }
1127 
1128         //--------------
1129         // audio format
1130         if (audioFormat == AudioFormat.ENCODING_DEFAULT) {
1131             audioFormat = AudioFormat.ENCODING_PCM_16BIT;
1132         }
1133 
1134         if (!AudioFormat.isPublicEncoding(audioFormat)) {
1135             throw new IllegalArgumentException("Unsupported audio encoding.");
1136         }
1137         mAudioFormat = audioFormat;
1138 
1139         //--------------
1140         // audio load mode
1141         if (((mode != MODE_STREAM) && (mode != MODE_STATIC)) ||
1142                 ((mode != MODE_STREAM) && !AudioFormat.isEncodingLinearPcm(mAudioFormat))) {
1143             throw new IllegalArgumentException("Invalid mode.");
1144         }
1145         mDataLoadMode = mode;
1146     }
1147 
1148     /**
1149      * Convenience method to check that the channel configuration (a.k.a channel mask) is supported
1150      * @param channelConfig the mask to validate
1151      * @return false if the AudioTrack can't be used with such a mask
1152      */
isMultichannelConfigSupported(int channelConfig)1153     private static boolean isMultichannelConfigSupported(int channelConfig) {
1154         // check for unsupported channels
1155         if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) {
1156             loge("Channel configuration features unsupported channels");
1157             return false;
1158         }
1159         final int channelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
1160         if (channelCount > CHANNEL_COUNT_MAX) {
1161             loge("Channel configuration contains too many channels " +
1162                     channelCount + ">" + CHANNEL_COUNT_MAX);
1163             return false;
1164         }
1165         // check for unsupported multichannel combinations:
1166         // - FL/FR must be present
1167         // - L/R channels must be paired (e.g. no single L channel)
1168         final int frontPair =
1169                 AudioFormat.CHANNEL_OUT_FRONT_LEFT | AudioFormat.CHANNEL_OUT_FRONT_RIGHT;
1170         if ((channelConfig & frontPair) != frontPair) {
1171                 loge("Front channels must be present in multichannel configurations");
1172                 return false;
1173         }
1174         final int backPair =
1175                 AudioFormat.CHANNEL_OUT_BACK_LEFT | AudioFormat.CHANNEL_OUT_BACK_RIGHT;
1176         if ((channelConfig & backPair) != 0) {
1177             if ((channelConfig & backPair) != backPair) {
1178                 loge("Rear channels can't be used independently");
1179                 return false;
1180             }
1181         }
1182         final int sidePair =
1183                 AudioFormat.CHANNEL_OUT_SIDE_LEFT | AudioFormat.CHANNEL_OUT_SIDE_RIGHT;
1184         if ((channelConfig & sidePair) != 0
1185                 && (channelConfig & sidePair) != sidePair) {
1186             loge("Side channels can't be used independently");
1187             return false;
1188         }
1189         return true;
1190     }
1191 
1192 
1193     // Convenience method for the constructor's audio buffer size check.
1194     // preconditions:
1195     //    mChannelCount is valid
1196     //    mAudioFormat is valid
1197     // postcondition:
1198     //    mNativeBufferSizeInBytes is valid (multiple of frame size, positive)
audioBuffSizeCheck(int audioBufferSize)1199     private void audioBuffSizeCheck(int audioBufferSize) {
1200         // NB: this section is only valid with PCM or IEC61937 data.
1201         //     To update when supporting compressed formats
1202         int frameSizeInBytes;
1203         if (AudioFormat.isEncodingLinearFrames(mAudioFormat)) {
1204             frameSizeInBytes = mChannelCount * AudioFormat.getBytesPerSample(mAudioFormat);
1205         } else {
1206             frameSizeInBytes = 1;
1207         }
1208         if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
1209             throw new IllegalArgumentException("Invalid audio buffer size.");
1210         }
1211 
1212         mNativeBufferSizeInBytes = audioBufferSize;
1213         mNativeBufferSizeInFrames = audioBufferSize / frameSizeInBytes;
1214     }
1215 
1216 
1217     /**
1218      * Releases the native AudioTrack resources.
1219      */
release()1220     public void release() {
1221         // even though native_release() stops the native AudioTrack, we need to stop
1222         // AudioTrack subclasses too.
1223         try {
1224             stop();
1225         } catch(IllegalStateException ise) {
1226             // don't raise an exception, we're releasing the resources.
1227         }
1228         baseRelease();
1229         native_release();
1230         mState = STATE_UNINITIALIZED;
1231     }
1232 
1233     @Override
finalize()1234     protected void finalize() {
1235         baseRelease();
1236         native_finalize();
1237     }
1238 
1239     //--------------------------------------------------------------------------
1240     // Getters
1241     //--------------------
1242     /**
1243      * Returns the minimum gain value, which is the constant 0.0.
1244      * Gain values less than 0.0 will be clamped to 0.0.
1245      * <p>The word "volume" in the API name is historical; this is actually a linear gain.
1246      * @return the minimum value, which is the constant 0.0.
1247      */
getMinVolume()1248     static public float getMinVolume() {
1249         return GAIN_MIN;
1250     }
1251 
1252     /**
1253      * Returns the maximum gain value, which is greater than or equal to 1.0.
1254      * Gain values greater than the maximum will be clamped to the maximum.
1255      * <p>The word "volume" in the API name is historical; this is actually a gain.
1256      * expressed as a linear multiplier on sample values, where a maximum value of 1.0
1257      * corresponds to a gain of 0 dB (sample values left unmodified).
1258      * @return the maximum value, which is greater than or equal to 1.0.
1259      */
getMaxVolume()1260     static public float getMaxVolume() {
1261         return GAIN_MAX;
1262     }
1263 
1264     /**
1265      * Returns the configured audio source sample rate in Hz.
1266      * The initial source sample rate depends on the constructor parameters,
1267      * but the source sample rate may change if {@link #setPlaybackRate(int)} is called.
1268      * If the constructor had a specific sample rate, then the initial sink sample rate is that
1269      * value.
1270      * If the constructor had {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED},
1271      * then the initial sink sample rate is a route-dependent default value based on the source [sic].
1272      */
getSampleRate()1273     public int getSampleRate() {
1274         return mSampleRate;
1275     }
1276 
1277     /**
1278      * Returns the current playback sample rate rate in Hz.
1279      */
getPlaybackRate()1280     public int getPlaybackRate() {
1281         return native_get_playback_rate();
1282     }
1283 
1284     /**
1285      * Returns the current playback parameters.
1286      * See {@link #setPlaybackParams(PlaybackParams)} to set playback parameters
1287      * @return current {@link PlaybackParams}.
1288      * @throws IllegalStateException if track is not initialized.
1289      */
getPlaybackParams()1290     public @NonNull PlaybackParams getPlaybackParams() {
1291         return native_get_playback_params();
1292     }
1293 
1294     /**
1295      * Returns the configured audio data encoding. See {@link AudioFormat#ENCODING_PCM_8BIT},
1296      * {@link AudioFormat#ENCODING_PCM_16BIT}, and {@link AudioFormat#ENCODING_PCM_FLOAT}.
1297      */
getAudioFormat()1298     public int getAudioFormat() {
1299         return mAudioFormat;
1300     }
1301 
1302     /**
1303      * Returns the volume stream type of this AudioTrack.
1304      * Compare the result against {@link AudioManager#STREAM_VOICE_CALL},
1305      * {@link AudioManager#STREAM_SYSTEM}, {@link AudioManager#STREAM_RING},
1306      * {@link AudioManager#STREAM_MUSIC}, {@link AudioManager#STREAM_ALARM},
1307      * {@link AudioManager#STREAM_NOTIFICATION}, {@link AudioManager#STREAM_DTMF} or
1308      * {@link AudioManager#STREAM_ACCESSIBILITY}.
1309      */
getStreamType()1310     public int getStreamType() {
1311         return mStreamType;
1312     }
1313 
1314     /**
1315      * Returns the configured channel position mask.
1316      * <p> For example, refer to {@link AudioFormat#CHANNEL_OUT_MONO},
1317      * {@link AudioFormat#CHANNEL_OUT_STEREO}, {@link AudioFormat#CHANNEL_OUT_5POINT1}.
1318      * This method may return {@link AudioFormat#CHANNEL_INVALID} if
1319      * a channel index mask was used. Consider
1320      * {@link #getFormat()} instead, to obtain an {@link AudioFormat},
1321      * which contains both the channel position mask and the channel index mask.
1322      */
getChannelConfiguration()1323     public int getChannelConfiguration() {
1324         return mChannelConfiguration;
1325     }
1326 
1327     /**
1328      * Returns the configured <code>AudioTrack</code> format.
1329      * @return an {@link AudioFormat} containing the
1330      * <code>AudioTrack</code> parameters at the time of configuration.
1331      */
getFormat()1332     public @NonNull AudioFormat getFormat() {
1333         AudioFormat.Builder builder = new AudioFormat.Builder()
1334             .setSampleRate(mSampleRate)
1335             .setEncoding(mAudioFormat);
1336         if (mChannelConfiguration != AudioFormat.CHANNEL_INVALID) {
1337             builder.setChannelMask(mChannelConfiguration);
1338         }
1339         if (mChannelIndexMask != AudioFormat.CHANNEL_INVALID /* 0 */) {
1340             builder.setChannelIndexMask(mChannelIndexMask);
1341         }
1342         return builder.build();
1343     }
1344 
1345     /**
1346      * Returns the configured number of channels.
1347      */
getChannelCount()1348     public int getChannelCount() {
1349         return mChannelCount;
1350     }
1351 
1352     /**
1353      * Returns the state of the AudioTrack instance. This is useful after the
1354      * AudioTrack instance has been created to check if it was initialized
1355      * properly. This ensures that the appropriate resources have been acquired.
1356      * @see #STATE_UNINITIALIZED
1357      * @see #STATE_INITIALIZED
1358      * @see #STATE_NO_STATIC_DATA
1359      */
getState()1360     public int getState() {
1361         return mState;
1362     }
1363 
1364     /**
1365      * Returns the playback state of the AudioTrack instance.
1366      * @see #PLAYSTATE_STOPPED
1367      * @see #PLAYSTATE_PAUSED
1368      * @see #PLAYSTATE_PLAYING
1369      */
getPlayState()1370     public int getPlayState() {
1371         synchronized (mPlayStateLock) {
1372             return mPlayState;
1373         }
1374     }
1375 
1376 
1377     /**
1378      * Returns the effective size of the <code>AudioTrack</code> buffer
1379      * that the application writes to.
1380      * <p> This will be less than or equal to the result of
1381      * {@link #getBufferCapacityInFrames()}.
1382      * It will be equal if {@link #setBufferSizeInFrames(int)} has never been called.
1383      * <p> If the track is subsequently routed to a different output sink, the buffer
1384      * size and capacity may enlarge to accommodate.
1385      * <p> If the <code>AudioTrack</code> encoding indicates compressed data,
1386      * e.g. {@link AudioFormat#ENCODING_AC3}, then the frame count returned is
1387      * the size of the <code>AudioTrack</code> buffer in bytes.
1388      * <p> See also {@link AudioManager#getProperty(String)} for key
1389      * {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
1390      * @return current size in frames of the <code>AudioTrack</code> buffer.
1391      * @throws IllegalStateException if track is not initialized.
1392      */
getBufferSizeInFrames()1393     public int getBufferSizeInFrames() {
1394         return native_get_buffer_size_frames();
1395     }
1396 
1397     /**
1398      * Limits the effective size of the <code>AudioTrack</code> buffer
1399      * that the application writes to.
1400      * <p> A write to this AudioTrack will not fill the buffer beyond this limit.
1401      * If a blocking write is used then the write will block until the data
1402      * can fit within this limit.
1403      * <p>Changing this limit modifies the latency associated with
1404      * the buffer for this track. A smaller size will give lower latency
1405      * but there may be more glitches due to buffer underruns.
1406      * <p>The actual size used may not be equal to this requested size.
1407      * It will be limited to a valid range with a maximum of
1408      * {@link #getBufferCapacityInFrames()}.
1409      * It may also be adjusted slightly for internal reasons.
1410      * If bufferSizeInFrames is less than zero then {@link #ERROR_BAD_VALUE}
1411      * will be returned.
1412      * <p>This method is only supported for PCM audio.
1413      * It is not supported for compressed audio tracks.
1414      *
1415      * @param bufferSizeInFrames requested buffer size in frames
1416      * @return the actual buffer size in frames or an error code,
1417      *    {@link #ERROR_BAD_VALUE}, {@link #ERROR_INVALID_OPERATION}
1418      * @throws IllegalStateException if track is not initialized.
1419      */
setBufferSizeInFrames(int bufferSizeInFrames)1420     public int setBufferSizeInFrames(int bufferSizeInFrames) {
1421         if (mDataLoadMode == MODE_STATIC || mState == STATE_UNINITIALIZED) {
1422             return ERROR_INVALID_OPERATION;
1423         }
1424         if (bufferSizeInFrames < 0) {
1425             return ERROR_BAD_VALUE;
1426         }
1427         return native_set_buffer_size_frames(bufferSizeInFrames);
1428     }
1429 
1430     /**
1431      *  Returns the maximum size of the <code>AudioTrack</code> buffer in frames.
1432      *  <p> If the track's creation mode is {@link #MODE_STATIC},
1433      *  it is equal to the specified bufferSizeInBytes on construction, converted to frame units.
1434      *  A static track's frame count will not change.
1435      *  <p> If the track's creation mode is {@link #MODE_STREAM},
1436      *  it is greater than or equal to the specified bufferSizeInBytes converted to frame units.
1437      *  For streaming tracks, this value may be rounded up to a larger value if needed by
1438      *  the target output sink, and
1439      *  if the track is subsequently routed to a different output sink, the
1440      *  frame count may enlarge to accommodate.
1441      *  <p> If the <code>AudioTrack</code> encoding indicates compressed data,
1442      *  e.g. {@link AudioFormat#ENCODING_AC3}, then the frame count returned is
1443      *  the size of the <code>AudioTrack</code> buffer in bytes.
1444      *  <p> See also {@link AudioManager#getProperty(String)} for key
1445      *  {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
1446      *  @return maximum size in frames of the <code>AudioTrack</code> buffer.
1447      *  @throws IllegalStateException if track is not initialized.
1448      */
getBufferCapacityInFrames()1449     public int getBufferCapacityInFrames() {
1450         return native_get_buffer_capacity_frames();
1451     }
1452 
1453     /**
1454      *  Returns the frame count of the native <code>AudioTrack</code> buffer.
1455      *  @return current size in frames of the <code>AudioTrack</code> buffer.
1456      *  @throws IllegalStateException
1457      *  @deprecated Use the identical public method {@link #getBufferSizeInFrames()} instead.
1458      */
1459     @Deprecated
getNativeFrameCount()1460     protected int getNativeFrameCount() {
1461         return native_get_buffer_capacity_frames();
1462     }
1463 
1464     /**
1465      * Returns marker position expressed in frames.
1466      * @return marker position in wrapping frame units similar to {@link #getPlaybackHeadPosition},
1467      * or zero if marker is disabled.
1468      */
getNotificationMarkerPosition()1469     public int getNotificationMarkerPosition() {
1470         return native_get_marker_pos();
1471     }
1472 
1473     /**
1474      * Returns the notification update period expressed in frames.
1475      * Zero means that no position update notifications are being delivered.
1476      */
getPositionNotificationPeriod()1477     public int getPositionNotificationPeriod() {
1478         return native_get_pos_update_period();
1479     }
1480 
1481     /**
1482      * Returns the playback head position expressed in frames.
1483      * Though the "int" type is signed 32-bits, the value should be reinterpreted as if it is
1484      * unsigned 32-bits.  That is, the next position after 0x7FFFFFFF is (int) 0x80000000.
1485      * This is a continuously advancing counter.  It will wrap (overflow) periodically,
1486      * for example approximately once every 27:03:11 hours:minutes:seconds at 44.1 kHz.
1487      * It is reset to zero by {@link #flush()}, {@link #reloadStaticData()}, and {@link #stop()}.
1488      * If the track's creation mode is {@link #MODE_STATIC}, the return value indicates
1489      * the total number of frames played since reset,
1490      * <i>not</i> the current offset within the buffer.
1491      */
getPlaybackHeadPosition()1492     public int getPlaybackHeadPosition() {
1493         return native_get_position();
1494     }
1495 
1496     /**
1497      * Returns this track's estimated latency in milliseconds. This includes the latency due
1498      * to AudioTrack buffer size, AudioMixer (if any) and audio hardware driver.
1499      *
1500      * DO NOT UNHIDE. The existing approach for doing A/V sync has too many problems. We need
1501      * a better solution.
1502      * @hide
1503      */
getLatency()1504     public int getLatency() {
1505         return native_get_latency();
1506     }
1507 
1508     /**
1509      * Returns the number of underrun occurrences in the application-level write buffer
1510      * since the AudioTrack was created.
1511      * An underrun occurs if the application does not write audio
1512      * data quickly enough, causing the buffer to underflow
1513      * and a potential audio glitch or pop.
1514      * <p>
1515      * Underruns are less likely when buffer sizes are large.
1516      * It may be possible to eliminate underruns by recreating the AudioTrack with
1517      * a larger buffer.
1518      * Or by using {@link #setBufferSizeInFrames(int)} to dynamically increase the
1519      * effective size of the buffer.
1520      */
getUnderrunCount()1521     public int getUnderrunCount() {
1522         return native_get_underrun_count();
1523     }
1524 
1525     /**
1526      * Returns the current performance mode of the {@link AudioTrack}.
1527      *
1528      * @return one of {@link AudioTrack#PERFORMANCE_MODE_NONE},
1529      * {@link AudioTrack#PERFORMANCE_MODE_LOW_LATENCY},
1530      * or {@link AudioTrack#PERFORMANCE_MODE_POWER_SAVING}.
1531      * Use {@link AudioTrack.Builder#setPerformanceMode}
1532      * in the {@link AudioTrack.Builder} to enable a performance mode.
1533      * @throws IllegalStateException if track is not initialized.
1534      */
getPerformanceMode()1535     public @PerformanceMode int getPerformanceMode() {
1536         final int flags = native_get_flags();
1537         if ((flags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
1538             return PERFORMANCE_MODE_LOW_LATENCY;
1539         } else if ((flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
1540             return PERFORMANCE_MODE_POWER_SAVING;
1541         } else {
1542             return PERFORMANCE_MODE_NONE;
1543         }
1544     }
1545 
1546     /**
1547      *  Returns the output sample rate in Hz for the specified stream type.
1548      */
getNativeOutputSampleRate(int streamType)1549     static public int getNativeOutputSampleRate(int streamType) {
1550         return native_get_output_sample_rate(streamType);
1551     }
1552 
1553     /**
1554      * Returns the estimated minimum buffer size required for an AudioTrack
1555      * object to be created in the {@link #MODE_STREAM} mode.
1556      * The size is an estimate because it does not consider either the route or the sink,
1557      * since neither is known yet.  Note that this size doesn't
1558      * guarantee a smooth playback under load, and higher values should be chosen according to
1559      * the expected frequency at which the buffer will be refilled with additional data to play.
1560      * For example, if you intend to dynamically set the source sample rate of an AudioTrack
1561      * to a higher value than the initial source sample rate, be sure to configure the buffer size
1562      * based on the highest planned sample rate.
1563      * @param sampleRateInHz the source sample rate expressed in Hz.
1564      *   {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} is not permitted.
1565      * @param channelConfig describes the configuration of the audio channels.
1566      *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
1567      *   {@link AudioFormat#CHANNEL_OUT_STEREO}
1568      * @param audioFormat the format in which the audio data is represented.
1569      *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
1570      *   {@link AudioFormat#ENCODING_PCM_8BIT},
1571      *   and {@link AudioFormat#ENCODING_PCM_FLOAT}.
1572      * @return {@link #ERROR_BAD_VALUE} if an invalid parameter was passed,
1573      *   or {@link #ERROR} if unable to query for output properties,
1574      *   or the minimum buffer size expressed in bytes.
1575      */
getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat)1576     static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
1577         int channelCount = 0;
1578         switch(channelConfig) {
1579         case AudioFormat.CHANNEL_OUT_MONO:
1580         case AudioFormat.CHANNEL_CONFIGURATION_MONO:
1581             channelCount = 1;
1582             break;
1583         case AudioFormat.CHANNEL_OUT_STEREO:
1584         case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
1585             channelCount = 2;
1586             break;
1587         default:
1588             if (!isMultichannelConfigSupported(channelConfig)) {
1589                 loge("getMinBufferSize(): Invalid channel configuration.");
1590                 return ERROR_BAD_VALUE;
1591             } else {
1592                 channelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
1593             }
1594         }
1595 
1596         if (!AudioFormat.isPublicEncoding(audioFormat)) {
1597             loge("getMinBufferSize(): Invalid audio format.");
1598             return ERROR_BAD_VALUE;
1599         }
1600 
1601         // sample rate, note these values are subject to change
1602         // Note: AudioFormat.SAMPLE_RATE_UNSPECIFIED is not allowed
1603         if ( (sampleRateInHz < AudioFormat.SAMPLE_RATE_HZ_MIN) ||
1604                 (sampleRateInHz > AudioFormat.SAMPLE_RATE_HZ_MAX) ) {
1605             loge("getMinBufferSize(): " + sampleRateInHz + " Hz is not a supported sample rate.");
1606             return ERROR_BAD_VALUE;
1607         }
1608 
1609         int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
1610         if (size <= 0) {
1611             loge("getMinBufferSize(): error querying hardware");
1612             return ERROR;
1613         }
1614         else {
1615             return size;
1616         }
1617     }
1618 
1619     /**
1620      * Returns the audio session ID.
1621      *
1622      * @return the ID of the audio session this AudioTrack belongs to.
1623      */
getAudioSessionId()1624     public int getAudioSessionId() {
1625         return mSessionId;
1626     }
1627 
1628    /**
1629     * Poll for a timestamp on demand.
1630     * <p>
1631     * If you need to track timestamps during initial warmup or after a routing or mode change,
1632     * you should request a new timestamp periodically until the reported timestamps
1633     * show that the frame position is advancing, or until it becomes clear that
1634     * timestamps are unavailable for this route.
1635     * <p>
1636     * After the clock is advancing at a stable rate,
1637     * query for a new timestamp approximately once every 10 seconds to once per minute.
1638     * Calling this method more often is inefficient.
1639     * It is also counter-productive to call this method more often than recommended,
1640     * because the short-term differences between successive timestamp reports are not meaningful.
1641     * If you need a high-resolution mapping between frame position and presentation time,
1642     * consider implementing that at application level, based on low-resolution timestamps.
1643     * <p>
1644     * The audio data at the returned position may either already have been
1645     * presented, or may have not yet been presented but is committed to be presented.
1646     * It is not possible to request the time corresponding to a particular position,
1647     * or to request the (fractional) position corresponding to a particular time.
1648     * If you need such features, consider implementing them at application level.
1649     *
1650     * @param timestamp a reference to a non-null AudioTimestamp instance allocated
1651     *        and owned by caller.
1652     * @return true if a timestamp is available, or false if no timestamp is available.
1653     *         If a timestamp if available,
1654     *         the AudioTimestamp instance is filled in with a position in frame units, together
1655     *         with the estimated time when that frame was presented or is committed to
1656     *         be presented.
1657     *         In the case that no timestamp is available, any supplied instance is left unaltered.
1658     *         A timestamp may be temporarily unavailable while the audio clock is stabilizing,
1659     *         or during and immediately after a route change.
1660     *         A timestamp is permanently unavailable for a given route if the route does not support
1661     *         timestamps.  In this case, the approximate frame position can be obtained
1662     *         using {@link #getPlaybackHeadPosition}.
1663     *         However, it may be useful to continue to query for
1664     *         timestamps occasionally, to recover after a route change.
1665     */
1666     // Add this text when the "on new timestamp" API is added:
1667     //   Use if you need to get the most recent timestamp outside of the event callback handler.
getTimestamp(AudioTimestamp timestamp)1668     public boolean getTimestamp(AudioTimestamp timestamp)
1669     {
1670         if (timestamp == null) {
1671             throw new IllegalArgumentException();
1672         }
1673         // It's unfortunate, but we have to either create garbage every time or use synchronized
1674         long[] longArray = new long[2];
1675         int ret = native_get_timestamp(longArray);
1676         if (ret != SUCCESS) {
1677             return false;
1678         }
1679         timestamp.framePosition = longArray[0];
1680         timestamp.nanoTime = longArray[1];
1681         return true;
1682     }
1683 
1684     /**
1685      * Poll for a timestamp on demand.
1686      * <p>
1687      * Same as {@link #getTimestamp(AudioTimestamp)} but with a more useful return code.
1688      *
1689      * @param timestamp a reference to a non-null AudioTimestamp instance allocated
1690      *        and owned by caller.
1691      * @return {@link #SUCCESS} if a timestamp is available
1692      *         {@link #ERROR_WOULD_BLOCK} if called in STOPPED or FLUSHED state, or if called
1693      *         immediately after start/ACTIVE, when the number of frames consumed is less than the
1694      *         overall hardware latency to physical output. In WOULD_BLOCK cases, one might poll
1695      *         again, or use {@link #getPlaybackHeadPosition}, or use 0 position and current time
1696      *         for the timestamp.
1697      *         {@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
1698      *         needs to be recreated.
1699      *         {@link #ERROR_INVALID_OPERATION} if current route does not support
1700      *         timestamps. In this case, the approximate frame position can be obtained
1701      *         using {@link #getPlaybackHeadPosition}.
1702      *
1703      *         The AudioTimestamp instance is filled in with a position in frame units, together
1704      *         with the estimated time when that frame was presented or is committed to
1705      *         be presented.
1706      * @hide
1707      */
1708      // Add this text when the "on new timestamp" API is added:
1709      //   Use if you need to get the most recent timestamp outside of the event callback handler.
getTimestampWithStatus(AudioTimestamp timestamp)1710      public int getTimestampWithStatus(AudioTimestamp timestamp)
1711      {
1712          if (timestamp == null) {
1713              throw new IllegalArgumentException();
1714          }
1715          // It's unfortunate, but we have to either create garbage every time or use synchronized
1716          long[] longArray = new long[2];
1717          int ret = native_get_timestamp(longArray);
1718          timestamp.framePosition = longArray[0];
1719          timestamp.nanoTime = longArray[1];
1720          return ret;
1721      }
1722 
1723     /**
1724      *  Return Metrics data about the current AudioTrack instance.
1725      *
1726      * @return a {@link PersistableBundle} containing the set of attributes and values
1727      * available for the media being handled by this instance of AudioTrack
1728      * The attributes are descibed in {@link MetricsConstants}.
1729      *
1730      * Additional vendor-specific fields may also be present in
1731      * the return value.
1732      */
getMetrics()1733     public PersistableBundle getMetrics() {
1734         PersistableBundle bundle = native_getMetrics();
1735         return bundle;
1736     }
1737 
native_getMetrics()1738     private native PersistableBundle native_getMetrics();
1739 
1740     //--------------------------------------------------------------------------
1741     // Initialization / configuration
1742     //--------------------
1743     /**
1744      * Sets the listener the AudioTrack notifies when a previously set marker is reached or
1745      * for each periodic playback head position update.
1746      * Notifications will be received in the same thread as the one in which the AudioTrack
1747      * instance was created.
1748      * @param listener
1749      */
setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener)1750     public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener) {
1751         setPlaybackPositionUpdateListener(listener, null);
1752     }
1753 
1754     /**
1755      * Sets the listener the AudioTrack notifies when a previously set marker is reached or
1756      * for each periodic playback head position update.
1757      * Use this method to receive AudioTrack events in the Handler associated with another
1758      * thread than the one in which you created the AudioTrack instance.
1759      * @param listener
1760      * @param handler the Handler that will receive the event notification messages.
1761      */
setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener, Handler handler)1762     public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener,
1763                                                     Handler handler) {
1764         if (listener != null) {
1765             mEventHandlerDelegate = new NativePositionEventHandlerDelegate(this, listener, handler);
1766         } else {
1767             mEventHandlerDelegate = null;
1768         }
1769     }
1770 
1771 
clampGainOrLevel(float gainOrLevel)1772     private static float clampGainOrLevel(float gainOrLevel) {
1773         if (Float.isNaN(gainOrLevel)) {
1774             throw new IllegalArgumentException();
1775         }
1776         if (gainOrLevel < GAIN_MIN) {
1777             gainOrLevel = GAIN_MIN;
1778         } else if (gainOrLevel > GAIN_MAX) {
1779             gainOrLevel = GAIN_MAX;
1780         }
1781         return gainOrLevel;
1782     }
1783 
1784 
1785      /**
1786      * Sets the specified left and right output gain values on the AudioTrack.
1787      * <p>Gain values are clamped to the closed interval [0.0, max] where
1788      * max is the value of {@link #getMaxVolume}.
1789      * A value of 0.0 results in zero gain (silence), and
1790      * a value of 1.0 means unity gain (signal unchanged).
1791      * The default value is 1.0 meaning unity gain.
1792      * <p>The word "volume" in the API name is historical; this is actually a linear gain.
1793      * @param leftGain output gain for the left channel.
1794      * @param rightGain output gain for the right channel
1795      * @return error code or success, see {@link #SUCCESS},
1796      *    {@link #ERROR_INVALID_OPERATION}
1797      * @deprecated Applications should use {@link #setVolume} instead, as it
1798      * more gracefully scales down to mono, and up to multi-channel content beyond stereo.
1799      */
1800     @Deprecated
setStereoVolume(float leftGain, float rightGain)1801     public int setStereoVolume(float leftGain, float rightGain) {
1802         if (mState == STATE_UNINITIALIZED) {
1803             return ERROR_INVALID_OPERATION;
1804         }
1805 
1806         baseSetVolume(leftGain, rightGain);
1807         return SUCCESS;
1808     }
1809 
1810     @Override
playerSetVolume(boolean muting, float leftVolume, float rightVolume)1811     void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
1812         leftVolume = clampGainOrLevel(muting ? 0.0f : leftVolume);
1813         rightVolume = clampGainOrLevel(muting ? 0.0f : rightVolume);
1814 
1815         native_setVolume(leftVolume, rightVolume);
1816     }
1817 
1818 
1819     /**
1820      * Sets the specified output gain value on all channels of this track.
1821      * <p>Gain values are clamped to the closed interval [0.0, max] where
1822      * max is the value of {@link #getMaxVolume}.
1823      * A value of 0.0 results in zero gain (silence), and
1824      * a value of 1.0 means unity gain (signal unchanged).
1825      * The default value is 1.0 meaning unity gain.
1826      * <p>This API is preferred over {@link #setStereoVolume}, as it
1827      * more gracefully scales down to mono, and up to multi-channel content beyond stereo.
1828      * <p>The word "volume" in the API name is historical; this is actually a linear gain.
1829      * @param gain output gain for all channels.
1830      * @return error code or success, see {@link #SUCCESS},
1831      *    {@link #ERROR_INVALID_OPERATION}
1832      */
setVolume(float gain)1833     public int setVolume(float gain) {
1834         return setStereoVolume(gain, gain);
1835     }
1836 
1837     @Override
playerApplyVolumeShaper( @onNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation)1838     /* package */ int playerApplyVolumeShaper(
1839             @NonNull VolumeShaper.Configuration configuration,
1840             @NonNull VolumeShaper.Operation operation) {
1841         return native_applyVolumeShaper(configuration, operation);
1842     }
1843 
1844     @Override
playerGetVolumeShaperState(int id)1845     /* package */ @Nullable VolumeShaper.State playerGetVolumeShaperState(int id) {
1846         return native_getVolumeShaperState(id);
1847     }
1848 
1849     @Override
createVolumeShaper( @onNull VolumeShaper.Configuration configuration)1850     public @NonNull VolumeShaper createVolumeShaper(
1851             @NonNull VolumeShaper.Configuration configuration) {
1852         return new VolumeShaper(configuration, this);
1853     }
1854 
1855     /**
1856      * Sets the playback sample rate for this track. This sets the sampling rate at which
1857      * the audio data will be consumed and played back
1858      * (as set by the sampleRateInHz parameter in the
1859      * {@link #AudioTrack(int, int, int, int, int, int)} constructor),
1860      * not the original sampling rate of the
1861      * content. For example, setting it to half the sample rate of the content will cause the
1862      * playback to last twice as long, but will also result in a pitch shift down by one octave.
1863      * The valid sample rate range is from 1 Hz to twice the value returned by
1864      * {@link #getNativeOutputSampleRate(int)}.
1865      * Use {@link #setPlaybackParams(PlaybackParams)} for speed control.
1866      * <p> This method may also be used to repurpose an existing <code>AudioTrack</code>
1867      * for playback of content of differing sample rate,
1868      * but with identical encoding and channel mask.
1869      * @param sampleRateInHz the sample rate expressed in Hz
1870      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
1871      *    {@link #ERROR_INVALID_OPERATION}
1872      */
setPlaybackRate(int sampleRateInHz)1873     public int setPlaybackRate(int sampleRateInHz) {
1874         if (mState != STATE_INITIALIZED) {
1875             return ERROR_INVALID_OPERATION;
1876         }
1877         if (sampleRateInHz <= 0) {
1878             return ERROR_BAD_VALUE;
1879         }
1880         return native_set_playback_rate(sampleRateInHz);
1881     }
1882 
1883 
1884     /**
1885      * Sets the playback parameters.
1886      * This method returns failure if it cannot apply the playback parameters.
1887      * One possible cause is that the parameters for speed or pitch are out of range.
1888      * Another possible cause is that the <code>AudioTrack</code> is streaming
1889      * (see {@link #MODE_STREAM}) and the
1890      * buffer size is too small. For speeds greater than 1.0f, the <code>AudioTrack</code> buffer
1891      * on configuration must be larger than the speed multiplied by the minimum size
1892      * {@link #getMinBufferSize(int, int, int)}) to allow proper playback.
1893      * @param params see {@link PlaybackParams}. In particular,
1894      * speed, pitch, and audio mode should be set.
1895      * @throws IllegalArgumentException if the parameters are invalid or not accepted.
1896      * @throws IllegalStateException if track is not initialized.
1897      */
setPlaybackParams(@onNull PlaybackParams params)1898     public void setPlaybackParams(@NonNull PlaybackParams params) {
1899         if (params == null) {
1900             throw new IllegalArgumentException("params is null");
1901         }
1902         native_set_playback_params(params);
1903     }
1904 
1905 
1906     /**
1907      * Sets the position of the notification marker.  At most one marker can be active.
1908      * @param markerInFrames marker position in wrapping frame units similar to
1909      * {@link #getPlaybackHeadPosition}, or zero to disable the marker.
1910      * To set a marker at a position which would appear as zero due to wraparound,
1911      * a workaround is to use a non-zero position near zero, such as -1 or 1.
1912      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
1913      *  {@link #ERROR_INVALID_OPERATION}
1914      */
setNotificationMarkerPosition(int markerInFrames)1915     public int setNotificationMarkerPosition(int markerInFrames) {
1916         if (mState == STATE_UNINITIALIZED) {
1917             return ERROR_INVALID_OPERATION;
1918         }
1919         return native_set_marker_pos(markerInFrames);
1920     }
1921 
1922 
1923     /**
1924      * Sets the period for the periodic notification event.
1925      * @param periodInFrames update period expressed in frames.
1926      * Zero period means no position updates.  A negative period is not allowed.
1927      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION}
1928      */
setPositionNotificationPeriod(int periodInFrames)1929     public int setPositionNotificationPeriod(int periodInFrames) {
1930         if (mState == STATE_UNINITIALIZED) {
1931             return ERROR_INVALID_OPERATION;
1932         }
1933         return native_set_pos_update_period(periodInFrames);
1934     }
1935 
1936 
1937     /**
1938      * Sets the playback head position within the static buffer.
1939      * The track must be stopped or paused for the position to be changed,
1940      * and must use the {@link #MODE_STATIC} mode.
1941      * @param positionInFrames playback head position within buffer, expressed in frames.
1942      * Zero corresponds to start of buffer.
1943      * The position must not be greater than the buffer size in frames, or negative.
1944      * Though this method and {@link #getPlaybackHeadPosition()} have similar names,
1945      * the position values have different meanings.
1946      * <br>
1947      * If looping is currently enabled and the new position is greater than or equal to the
1948      * loop end marker, the behavior varies by API level:
1949      * as of {@link android.os.Build.VERSION_CODES#M},
1950      * the looping is first disabled and then the position is set.
1951      * For earlier API levels, the behavior is unspecified.
1952      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
1953      *    {@link #ERROR_INVALID_OPERATION}
1954      */
setPlaybackHeadPosition(int positionInFrames)1955     public int setPlaybackHeadPosition(int positionInFrames) {
1956         if (mDataLoadMode == MODE_STREAM || mState == STATE_UNINITIALIZED ||
1957                 getPlayState() == PLAYSTATE_PLAYING) {
1958             return ERROR_INVALID_OPERATION;
1959         }
1960         if (!(0 <= positionInFrames && positionInFrames <= mNativeBufferSizeInFrames)) {
1961             return ERROR_BAD_VALUE;
1962         }
1963         return native_set_position(positionInFrames);
1964     }
1965 
1966     /**
1967      * Sets the loop points and the loop count. The loop can be infinite.
1968      * Similarly to setPlaybackHeadPosition,
1969      * the track must be stopped or paused for the loop points to be changed,
1970      * and must use the {@link #MODE_STATIC} mode.
1971      * @param startInFrames loop start marker expressed in frames.
1972      * Zero corresponds to start of buffer.
1973      * The start marker must not be greater than or equal to the buffer size in frames, or negative.
1974      * @param endInFrames loop end marker expressed in frames.
1975      * The total buffer size in frames corresponds to end of buffer.
1976      * The end marker must not be greater than the buffer size in frames.
1977      * For looping, the end marker must not be less than or equal to the start marker,
1978      * but to disable looping
1979      * it is permitted for start marker, end marker, and loop count to all be 0.
1980      * If any input parameters are out of range, this method returns {@link #ERROR_BAD_VALUE}.
1981      * If the loop period (endInFrames - startInFrames) is too small for the implementation to
1982      * support,
1983      * {@link #ERROR_BAD_VALUE} is returned.
1984      * The loop range is the interval [startInFrames, endInFrames).
1985      * <br>
1986      * As of {@link android.os.Build.VERSION_CODES#M}, the position is left unchanged,
1987      * unless it is greater than or equal to the loop end marker, in which case
1988      * it is forced to the loop start marker.
1989      * For earlier API levels, the effect on position is unspecified.
1990      * @param loopCount the number of times the loop is looped; must be greater than or equal to -1.
1991      *    A value of -1 means infinite looping, and 0 disables looping.
1992      *    A value of positive N means to "loop" (go back) N times.  For example,
1993      *    a value of one means to play the region two times in total.
1994      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
1995      *    {@link #ERROR_INVALID_OPERATION}
1996      */
setLoopPoints(int startInFrames, int endInFrames, int loopCount)1997     public int setLoopPoints(int startInFrames, int endInFrames, int loopCount) {
1998         if (mDataLoadMode == MODE_STREAM || mState == STATE_UNINITIALIZED ||
1999                 getPlayState() == PLAYSTATE_PLAYING) {
2000             return ERROR_INVALID_OPERATION;
2001         }
2002         if (loopCount == 0) {
2003             ;   // explicitly allowed as an exception to the loop region range check
2004         } else if (!(0 <= startInFrames && startInFrames < mNativeBufferSizeInFrames &&
2005                 startInFrames < endInFrames && endInFrames <= mNativeBufferSizeInFrames)) {
2006             return ERROR_BAD_VALUE;
2007         }
2008         return native_set_loop(startInFrames, endInFrames, loopCount);
2009     }
2010 
2011     /**
2012      * Sets the audio presentation.
2013      * If the audio presentation is invalid then {@link #ERROR_BAD_VALUE} will be returned.
2014      * If a multi-stream decoder (MSD) is not present, or the format does not support
2015      * multiple presentations, then {@link #ERROR_INVALID_OPERATION} will be returned.
2016      * {@link #ERROR} is returned in case of any other error.
2017      * @param presentation see {@link AudioPresentation}. In particular, id should be set.
2018      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR},
2019      *    {@link #ERROR_BAD_VALUE}, {@link #ERROR_INVALID_OPERATION}
2020      * @throws IllegalArgumentException if the audio presentation is null.
2021      * @throws IllegalStateException if track is not initialized.
2022      */
setPresentation(@onNull AudioPresentation presentation)2023     public int setPresentation(@NonNull AudioPresentation presentation) {
2024         if (presentation == null) {
2025             throw new IllegalArgumentException("audio presentation is null");
2026         }
2027         return native_setPresentation(presentation.getPresentationId(),
2028                 presentation.getProgramId());
2029     }
2030 
2031     /**
2032      * Sets the initialization state of the instance. This method was originally intended to be used
2033      * in an AudioTrack subclass constructor to set a subclass-specific post-initialization state.
2034      * However, subclasses of AudioTrack are no longer recommended, so this method is obsolete.
2035      * @param state the state of the AudioTrack instance
2036      * @deprecated Only accessible by subclasses, which are not recommended for AudioTrack.
2037      */
2038     @Deprecated
setState(int state)2039     protected void setState(int state) {
2040         mState = state;
2041     }
2042 
2043 
2044     //---------------------------------------------------------
2045     // Transport control methods
2046     //--------------------
2047     /**
2048      * Starts playing an AudioTrack.
2049      * <p>
2050      * If track's creation mode is {@link #MODE_STATIC}, you must have called one of
2051      * the write methods ({@link #write(byte[], int, int)}, {@link #write(byte[], int, int, int)},
2052      * {@link #write(short[], int, int)}, {@link #write(short[], int, int, int)},
2053      * {@link #write(float[], int, int, int)}, or {@link #write(ByteBuffer, int, int)}) prior to
2054      * play().
2055      * <p>
2056      * If the mode is {@link #MODE_STREAM}, you can optionally prime the data path prior to
2057      * calling play(), by writing up to <code>bufferSizeInBytes</code> (from constructor).
2058      * If you don't call write() first, or if you call write() but with an insufficient amount of
2059      * data, then the track will be in underrun state at play().  In this case,
2060      * playback will not actually start playing until the data path is filled to a
2061      * device-specific minimum level.  This requirement for the path to be filled
2062      * to a minimum level is also true when resuming audio playback after calling stop().
2063      * Similarly the buffer will need to be filled up again after
2064      * the track underruns due to failure to call write() in a timely manner with sufficient data.
2065      * For portability, an application should prime the data path to the maximum allowed
2066      * by writing data until the write() method returns a short transfer count.
2067      * This allows play() to start immediately, and reduces the chance of underrun.
2068      *
2069      * @throws IllegalStateException if the track isn't properly initialized
2070      */
play()2071     public void play()
2072     throws IllegalStateException {
2073         if (mState != STATE_INITIALIZED) {
2074             throw new IllegalStateException("play() called on uninitialized AudioTrack.");
2075         }
2076         //FIXME use lambda to pass startImpl to superclass
2077         final int delay = getStartDelayMs();
2078         if (delay == 0) {
2079             startImpl();
2080         } else {
2081             new Thread() {
2082                 public void run() {
2083                     try {
2084                         Thread.sleep(delay);
2085                     } catch (InterruptedException e) {
2086                         e.printStackTrace();
2087                     }
2088                     baseSetStartDelayMs(0);
2089                     try {
2090                         startImpl();
2091                     } catch (IllegalStateException e) {
2092                         // fail silently for a state exception when it is happening after
2093                         // a delayed start, as the player state could have changed between the
2094                         // call to start() and the execution of startImpl()
2095                     }
2096                 }
2097             }.start();
2098         }
2099     }
2100 
startImpl()2101     private void startImpl() {
2102         synchronized(mPlayStateLock) {
2103             baseStart();
2104             native_start();
2105             mPlayState = PLAYSTATE_PLAYING;
2106         }
2107     }
2108 
2109     /**
2110      * Stops playing the audio data.
2111      * When used on an instance created in {@link #MODE_STREAM} mode, audio will stop playing
2112      * after the last buffer that was written has been played. For an immediate stop, use
2113      * {@link #pause()}, followed by {@link #flush()} to discard audio data that hasn't been played
2114      * back yet.
2115      * @throws IllegalStateException
2116      */
stop()2117     public void stop()
2118     throws IllegalStateException {
2119         if (mState != STATE_INITIALIZED) {
2120             throw new IllegalStateException("stop() called on uninitialized AudioTrack.");
2121         }
2122 
2123         // stop playing
2124         synchronized(mPlayStateLock) {
2125             native_stop();
2126             baseStop();
2127             mPlayState = PLAYSTATE_STOPPED;
2128             mAvSyncHeader = null;
2129             mAvSyncBytesRemaining = 0;
2130         }
2131     }
2132 
2133     /**
2134      * Pauses the playback of the audio data. Data that has not been played
2135      * back will not be discarded. Subsequent calls to {@link #play} will play
2136      * this data back. See {@link #flush()} to discard this data.
2137      *
2138      * @throws IllegalStateException
2139      */
pause()2140     public void pause()
2141     throws IllegalStateException {
2142         if (mState != STATE_INITIALIZED) {
2143             throw new IllegalStateException("pause() called on uninitialized AudioTrack.");
2144         }
2145 
2146         // pause playback
2147         synchronized(mPlayStateLock) {
2148             native_pause();
2149             basePause();
2150             mPlayState = PLAYSTATE_PAUSED;
2151         }
2152     }
2153 
2154 
2155     //---------------------------------------------------------
2156     // Audio data supply
2157     //--------------------
2158 
2159     /**
2160      * Flushes the audio data currently queued for playback. Any data that has
2161      * been written but not yet presented will be discarded.  No-op if not stopped or paused,
2162      * or if the track's creation mode is not {@link #MODE_STREAM}.
2163      * <BR> Note that although data written but not yet presented is discarded, there is no
2164      * guarantee that all of the buffer space formerly used by that data
2165      * is available for a subsequent write.
2166      * For example, a call to {@link #write(byte[], int, int)} with <code>sizeInBytes</code>
2167      * less than or equal to the total buffer size
2168      * may return a short actual transfer count.
2169      */
flush()2170     public void flush() {
2171         if (mState == STATE_INITIALIZED) {
2172             // flush the data in native layer
2173             native_flush();
2174             mAvSyncHeader = null;
2175             mAvSyncBytesRemaining = 0;
2176         }
2177 
2178     }
2179 
2180     /**
2181      * Writes the audio data to the audio sink for playback (streaming mode),
2182      * or copies audio data for later playback (static buffer mode).
2183      * The format specified in the AudioTrack constructor should be
2184      * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array.
2185      * The format can be {@link AudioFormat#ENCODING_PCM_16BIT}, but this is deprecated.
2186      * <p>
2187      * In streaming mode, the write will normally block until all the data has been enqueued for
2188      * playback, and will return a full transfer count.  However, if the track is stopped or paused
2189      * on entry, or another thread interrupts the write by calling stop or pause, or an I/O error
2190      * occurs during the write, then the write may return a short transfer count.
2191      * <p>
2192      * In static buffer mode, copies the data to the buffer starting at offset 0.
2193      * Note that the actual playback of this data might occur after this function returns.
2194      *
2195      * @param audioData the array that holds the data to play.
2196      * @param offsetInBytes the offset expressed in bytes in audioData where the data to write
2197      *    starts.
2198      *    Must not be negative, or cause the data access to go out of bounds of the array.
2199      * @param sizeInBytes the number of bytes to write in audioData after the offset.
2200      *    Must not be negative, or cause the data access to go out of bounds of the array.
2201      * @return zero or the positive number of bytes that were written, or one of the following
2202      *    error codes. The number of bytes will be a multiple of the frame size in bytes
2203      *    not to exceed sizeInBytes.
2204      * <ul>
2205      * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
2206      * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
2207      * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
2208      *    needs to be recreated. The dead object error code is not returned if some data was
2209      *    successfully transferred. In this case, the error is returned at the next write()</li>
2210      * <li>{@link #ERROR} in case of other error</li>
2211      * </ul>
2212      * This is equivalent to {@link #write(byte[], int, int, int)} with <code>writeMode</code>
2213      * set to  {@link #WRITE_BLOCKING}.
2214      */
write(@onNull byte[] audioData, int offsetInBytes, int sizeInBytes)2215     public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) {
2216         return write(audioData, offsetInBytes, sizeInBytes, WRITE_BLOCKING);
2217     }
2218 
2219     /**
2220      * Writes the audio data to the audio sink for playback (streaming mode),
2221      * or copies audio data for later playback (static buffer mode).
2222      * The format specified in the AudioTrack constructor should be
2223      * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array.
2224      * The format can be {@link AudioFormat#ENCODING_PCM_16BIT}, but this is deprecated.
2225      * <p>
2226      * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
2227      * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
2228      * for playback, and will return a full transfer count.  However, if the write mode is
2229      * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
2230      * interrupts the write by calling stop or pause, or an I/O error
2231      * occurs during the write, then the write may return a short transfer count.
2232      * <p>
2233      * In static buffer mode, copies the data to the buffer starting at offset 0,
2234      * and the write mode is ignored.
2235      * Note that the actual playback of this data might occur after this function returns.
2236      *
2237      * @param audioData the array that holds the data to play.
2238      * @param offsetInBytes the offset expressed in bytes in audioData where the data to write
2239      *    starts.
2240      *    Must not be negative, or cause the data access to go out of bounds of the array.
2241      * @param sizeInBytes the number of bytes to write in audioData after the offset.
2242      *    Must not be negative, or cause the data access to go out of bounds of the array.
2243      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
2244      *     effect in static mode.
2245      *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
2246      *         to the audio sink.
2247      *     <br>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
2248      *     queuing as much audio data for playback as possible without blocking.
2249      * @return zero or the positive number of bytes that were written, or one of the following
2250      *    error codes. The number of bytes will be a multiple of the frame size in bytes
2251      *    not to exceed sizeInBytes.
2252      * <ul>
2253      * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
2254      * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
2255      * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
2256      *    needs to be recreated. The dead object error code is not returned if some data was
2257      *    successfully transferred. In this case, the error is returned at the next write()</li>
2258      * <li>{@link #ERROR} in case of other error</li>
2259      * </ul>
2260      */
write(@onNull byte[] audioData, int offsetInBytes, int sizeInBytes, @WriteMode int writeMode)2261     public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
2262             @WriteMode int writeMode) {
2263 
2264         if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
2265             return ERROR_INVALID_OPERATION;
2266         }
2267 
2268         if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
2269             Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
2270             return ERROR_BAD_VALUE;
2271         }
2272 
2273         if ( (audioData == null) || (offsetInBytes < 0 ) || (sizeInBytes < 0)
2274                 || (offsetInBytes + sizeInBytes < 0)    // detect integer overflow
2275                 || (offsetInBytes + sizeInBytes > audioData.length)) {
2276             return ERROR_BAD_VALUE;
2277         }
2278 
2279         int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat,
2280                 writeMode == WRITE_BLOCKING);
2281 
2282         if ((mDataLoadMode == MODE_STATIC)
2283                 && (mState == STATE_NO_STATIC_DATA)
2284                 && (ret > 0)) {
2285             // benign race with respect to other APIs that read mState
2286             mState = STATE_INITIALIZED;
2287         }
2288 
2289         return ret;
2290     }
2291 
2292     /**
2293      * Writes the audio data to the audio sink for playback (streaming mode),
2294      * or copies audio data for later playback (static buffer mode).
2295      * The format specified in the AudioTrack constructor should be
2296      * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array.
2297      * <p>
2298      * In streaming mode, the write will normally block until all the data has been enqueued for
2299      * playback, and will return a full transfer count.  However, if the track is stopped or paused
2300      * on entry, or another thread interrupts the write by calling stop or pause, or an I/O error
2301      * occurs during the write, then the write may return a short transfer count.
2302      * <p>
2303      * In static buffer mode, copies the data to the buffer starting at offset 0.
2304      * Note that the actual playback of this data might occur after this function returns.
2305      *
2306      * @param audioData the array that holds the data to play.
2307      * @param offsetInShorts the offset expressed in shorts in audioData where the data to play
2308      *     starts.
2309      *    Must not be negative, or cause the data access to go out of bounds of the array.
2310      * @param sizeInShorts the number of shorts to read in audioData after the offset.
2311      *    Must not be negative, or cause the data access to go out of bounds of the array.
2312      * @return zero or the positive number of shorts that were written, or one of the following
2313      *    error codes. The number of shorts will be a multiple of the channel count not to
2314      *    exceed sizeInShorts.
2315      * <ul>
2316      * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
2317      * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
2318      * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
2319      *    needs to be recreated. The dead object error code is not returned if some data was
2320      *    successfully transferred. In this case, the error is returned at the next write()</li>
2321      * <li>{@link #ERROR} in case of other error</li>
2322      * </ul>
2323      * This is equivalent to {@link #write(short[], int, int, int)} with <code>writeMode</code>
2324      * set to  {@link #WRITE_BLOCKING}.
2325      */
write(@onNull short[] audioData, int offsetInShorts, int sizeInShorts)2326     public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts) {
2327         return write(audioData, offsetInShorts, sizeInShorts, WRITE_BLOCKING);
2328     }
2329 
2330     /**
2331      * Writes the audio data to the audio sink for playback (streaming mode),
2332      * or copies audio data for later playback (static buffer mode).
2333      * The format specified in the AudioTrack constructor should be
2334      * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array.
2335      * <p>
2336      * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
2337      * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
2338      * for playback, and will return a full transfer count.  However, if the write mode is
2339      * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
2340      * interrupts the write by calling stop or pause, or an I/O error
2341      * occurs during the write, then the write may return a short transfer count.
2342      * <p>
2343      * In static buffer mode, copies the data to the buffer starting at offset 0.
2344      * Note that the actual playback of this data might occur after this function returns.
2345      *
2346      * @param audioData the array that holds the data to write.
2347      * @param offsetInShorts the offset expressed in shorts in audioData where the data to write
2348      *     starts.
2349      *    Must not be negative, or cause the data access to go out of bounds of the array.
2350      * @param sizeInShorts the number of shorts to read in audioData after the offset.
2351      *    Must not be negative, or cause the data access to go out of bounds of the array.
2352      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
2353      *     effect in static mode.
2354      *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
2355      *         to the audio sink.
2356      *     <br>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
2357      *     queuing as much audio data for playback as possible without blocking.
2358      * @return zero or the positive number of shorts that were written, or one of the following
2359      *    error codes. The number of shorts will be a multiple of the channel count not to
2360      *    exceed sizeInShorts.
2361      * <ul>
2362      * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
2363      * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
2364      * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
2365      *    needs to be recreated. The dead object error code is not returned if some data was
2366      *    successfully transferred. In this case, the error is returned at the next write()</li>
2367      * <li>{@link #ERROR} in case of other error</li>
2368      * </ul>
2369      */
write(@onNull short[] audioData, int offsetInShorts, int sizeInShorts, @WriteMode int writeMode)2370     public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
2371             @WriteMode int writeMode) {
2372 
2373         if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
2374             return ERROR_INVALID_OPERATION;
2375         }
2376 
2377         if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
2378             Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
2379             return ERROR_BAD_VALUE;
2380         }
2381 
2382         if ( (audioData == null) || (offsetInShorts < 0 ) || (sizeInShorts < 0)
2383                 || (offsetInShorts + sizeInShorts < 0)  // detect integer overflow
2384                 || (offsetInShorts + sizeInShorts > audioData.length)) {
2385             return ERROR_BAD_VALUE;
2386         }
2387 
2388         int ret = native_write_short(audioData, offsetInShorts, sizeInShorts, mAudioFormat,
2389                 writeMode == WRITE_BLOCKING);
2390 
2391         if ((mDataLoadMode == MODE_STATIC)
2392                 && (mState == STATE_NO_STATIC_DATA)
2393                 && (ret > 0)) {
2394             // benign race with respect to other APIs that read mState
2395             mState = STATE_INITIALIZED;
2396         }
2397 
2398         return ret;
2399     }
2400 
2401     /**
2402      * Writes the audio data to the audio sink for playback (streaming mode),
2403      * or copies audio data for later playback (static buffer mode).
2404      * The format specified in the AudioTrack constructor should be
2405      * {@link AudioFormat#ENCODING_PCM_FLOAT} to correspond to the data in the array.
2406      * <p>
2407      * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
2408      * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
2409      * for playback, and will return a full transfer count.  However, if the write mode is
2410      * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
2411      * interrupts the write by calling stop or pause, or an I/O error
2412      * occurs during the write, then the write may return a short transfer count.
2413      * <p>
2414      * In static buffer mode, copies the data to the buffer starting at offset 0,
2415      * and the write mode is ignored.
2416      * Note that the actual playback of this data might occur after this function returns.
2417      *
2418      * @param audioData the array that holds the data to write.
2419      *     The implementation does not clip for sample values within the nominal range
2420      *     [-1.0f, 1.0f], provided that all gains in the audio pipeline are
2421      *     less than or equal to unity (1.0f), and in the absence of post-processing effects
2422      *     that could add energy, such as reverb.  For the convenience of applications
2423      *     that compute samples using filters with non-unity gain,
2424      *     sample values +3 dB beyond the nominal range are permitted.
2425      *     However such values may eventually be limited or clipped, depending on various gains
2426      *     and later processing in the audio path.  Therefore applications are encouraged
2427      *     to provide samples values within the nominal range.
2428      * @param offsetInFloats the offset, expressed as a number of floats,
2429      *     in audioData where the data to write starts.
2430      *    Must not be negative, or cause the data access to go out of bounds of the array.
2431      * @param sizeInFloats the number of floats to write in audioData after the offset.
2432      *    Must not be negative, or cause the data access to go out of bounds of the array.
2433      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
2434      *     effect in static mode.
2435      *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
2436      *         to the audio sink.
2437      *     <br>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
2438      *     queuing as much audio data for playback as possible without blocking.
2439      * @return zero or the positive number of floats that were written, or one of the following
2440      *    error codes. The number of floats will be a multiple of the channel count not to
2441      *    exceed sizeInFloats.
2442      * <ul>
2443      * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
2444      * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
2445      * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
2446      *    needs to be recreated. The dead object error code is not returned if some data was
2447      *    successfully transferred. In this case, the error is returned at the next write()</li>
2448      * <li>{@link #ERROR} in case of other error</li>
2449      * </ul>
2450      */
write(@onNull float[] audioData, int offsetInFloats, int sizeInFloats, @WriteMode int writeMode)2451     public int write(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats,
2452             @WriteMode int writeMode) {
2453 
2454         if (mState == STATE_UNINITIALIZED) {
2455             Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED");
2456             return ERROR_INVALID_OPERATION;
2457         }
2458 
2459         if (mAudioFormat != AudioFormat.ENCODING_PCM_FLOAT) {
2460             Log.e(TAG, "AudioTrack.write(float[] ...) requires format ENCODING_PCM_FLOAT");
2461             return ERROR_INVALID_OPERATION;
2462         }
2463 
2464         if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
2465             Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
2466             return ERROR_BAD_VALUE;
2467         }
2468 
2469         if ( (audioData == null) || (offsetInFloats < 0 ) || (sizeInFloats < 0)
2470                 || (offsetInFloats + sizeInFloats < 0)  // detect integer overflow
2471                 || (offsetInFloats + sizeInFloats > audioData.length)) {
2472             Log.e(TAG, "AudioTrack.write() called with invalid array, offset, or size");
2473             return ERROR_BAD_VALUE;
2474         }
2475 
2476         int ret = native_write_float(audioData, offsetInFloats, sizeInFloats, mAudioFormat,
2477                 writeMode == WRITE_BLOCKING);
2478 
2479         if ((mDataLoadMode == MODE_STATIC)
2480                 && (mState == STATE_NO_STATIC_DATA)
2481                 && (ret > 0)) {
2482             // benign race with respect to other APIs that read mState
2483             mState = STATE_INITIALIZED;
2484         }
2485 
2486         return ret;
2487     }
2488 
2489 
2490     /**
2491      * Writes the audio data to the audio sink for playback (streaming mode),
2492      * or copies audio data for later playback (static buffer mode).
2493      * The audioData in ByteBuffer should match the format specified in the AudioTrack constructor.
2494      * <p>
2495      * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
2496      * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
2497      * for playback, and will return a full transfer count.  However, if the write mode is
2498      * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
2499      * interrupts the write by calling stop or pause, or an I/O error
2500      * occurs during the write, then the write may return a short transfer count.
2501      * <p>
2502      * In static buffer mode, copies the data to the buffer starting at offset 0,
2503      * and the write mode is ignored.
2504      * Note that the actual playback of this data might occur after this function returns.
2505      *
2506      * @param audioData the buffer that holds the data to write, starting at the position reported
2507      *     by <code>audioData.position()</code>.
2508      *     <BR>Note that upon return, the buffer position (<code>audioData.position()</code>) will
2509      *     have been advanced to reflect the amount of data that was successfully written to
2510      *     the AudioTrack.
2511      * @param sizeInBytes number of bytes to write.  It is recommended but not enforced
2512      *     that the number of bytes requested be a multiple of the frame size (sample size in
2513      *     bytes multiplied by the channel count).
2514      *     <BR>Note this may differ from <code>audioData.remaining()</code>, but cannot exceed it.
2515      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
2516      *     effect in static mode.
2517      *     <BR>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
2518      *         to the audio sink.
2519      *     <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
2520      *     queuing as much audio data for playback as possible without blocking.
2521      * @return zero or the positive number of bytes that were written, or one of the following
2522      *    error codes.
2523      * <ul>
2524      * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
2525      * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
2526      * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
2527      *    needs to be recreated. The dead object error code is not returned if some data was
2528      *    successfully transferred. In this case, the error is returned at the next write()</li>
2529      * <li>{@link #ERROR} in case of other error</li>
2530      * </ul>
2531      */
write(@onNull ByteBuffer audioData, int sizeInBytes, @WriteMode int writeMode)2532     public int write(@NonNull ByteBuffer audioData, int sizeInBytes,
2533             @WriteMode int writeMode) {
2534 
2535         if (mState == STATE_UNINITIALIZED) {
2536             Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED");
2537             return ERROR_INVALID_OPERATION;
2538         }
2539 
2540         if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
2541             Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
2542             return ERROR_BAD_VALUE;
2543         }
2544 
2545         if ( (audioData == null) || (sizeInBytes < 0) || (sizeInBytes > audioData.remaining())) {
2546             Log.e(TAG, "AudioTrack.write() called with invalid size (" + sizeInBytes + ") value");
2547             return ERROR_BAD_VALUE;
2548         }
2549 
2550         int ret = 0;
2551         if (audioData.isDirect()) {
2552             ret = native_write_native_bytes(audioData,
2553                     audioData.position(), sizeInBytes, mAudioFormat,
2554                     writeMode == WRITE_BLOCKING);
2555         } else {
2556             ret = native_write_byte(NioUtils.unsafeArray(audioData),
2557                     NioUtils.unsafeArrayOffset(audioData) + audioData.position(),
2558                     sizeInBytes, mAudioFormat,
2559                     writeMode == WRITE_BLOCKING);
2560         }
2561 
2562         if ((mDataLoadMode == MODE_STATIC)
2563                 && (mState == STATE_NO_STATIC_DATA)
2564                 && (ret > 0)) {
2565             // benign race with respect to other APIs that read mState
2566             mState = STATE_INITIALIZED;
2567         }
2568 
2569         if (ret > 0) {
2570             audioData.position(audioData.position() + ret);
2571         }
2572 
2573         return ret;
2574     }
2575 
2576     /**
2577      * Writes the audio data to the audio sink for playback in streaming mode on a HW_AV_SYNC track.
2578      * The blocking behavior will depend on the write mode.
2579      * @param audioData the buffer that holds the data to write, starting at the position reported
2580      *     by <code>audioData.position()</code>.
2581      *     <BR>Note that upon return, the buffer position (<code>audioData.position()</code>) will
2582      *     have been advanced to reflect the amount of data that was successfully written to
2583      *     the AudioTrack.
2584      * @param sizeInBytes number of bytes to write.  It is recommended but not enforced
2585      *     that the number of bytes requested be a multiple of the frame size (sample size in
2586      *     bytes multiplied by the channel count).
2587      *     <BR>Note this may differ from <code>audioData.remaining()</code>, but cannot exceed it.
2588      * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}.
2589      *     <BR>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
2590      *         to the audio sink.
2591      *     <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
2592      *     queuing as much audio data for playback as possible without blocking.
2593      * @param timestamp The timestamp of the first decodable audio frame in the provided audioData.
2594      * @return zero or the positive number of bytes that were written, or one of the following
2595      *    error codes.
2596      * <ul>
2597      * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
2598      * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
2599      * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
2600      *    needs to be recreated. The dead object error code is not returned if some data was
2601      *    successfully transferred. In this case, the error is returned at the next write()</li>
2602      * <li>{@link #ERROR} in case of other error</li>
2603      * </ul>
2604      */
write(@onNull ByteBuffer audioData, int sizeInBytes, @WriteMode int writeMode, long timestamp)2605     public int write(@NonNull ByteBuffer audioData, int sizeInBytes,
2606             @WriteMode int writeMode, long timestamp) {
2607 
2608         if (mState == STATE_UNINITIALIZED) {
2609             Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED");
2610             return ERROR_INVALID_OPERATION;
2611         }
2612 
2613         if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
2614             Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
2615             return ERROR_BAD_VALUE;
2616         }
2617 
2618         if (mDataLoadMode != MODE_STREAM) {
2619             Log.e(TAG, "AudioTrack.write() with timestamp called for non-streaming mode track");
2620             return ERROR_INVALID_OPERATION;
2621         }
2622 
2623         if ((mAttributes.getFlags() & AudioAttributes.FLAG_HW_AV_SYNC) == 0) {
2624             Log.d(TAG, "AudioTrack.write() called on a regular AudioTrack. Ignoring pts...");
2625             return write(audioData, sizeInBytes, writeMode);
2626         }
2627 
2628         if ((audioData == null) || (sizeInBytes < 0) || (sizeInBytes > audioData.remaining())) {
2629             Log.e(TAG, "AudioTrack.write() called with invalid size (" + sizeInBytes + ") value");
2630             return ERROR_BAD_VALUE;
2631         }
2632 
2633         // create timestamp header if none exists
2634         if (mAvSyncHeader == null) {
2635             mAvSyncHeader = ByteBuffer.allocate(mOffset);
2636             mAvSyncHeader.order(ByteOrder.BIG_ENDIAN);
2637             mAvSyncHeader.putInt(0x55550002);
2638         }
2639 
2640         if (mAvSyncBytesRemaining == 0) {
2641             mAvSyncHeader.putInt(4, sizeInBytes);
2642             mAvSyncHeader.putLong(8, timestamp);
2643             mAvSyncHeader.putInt(16, mOffset);
2644             mAvSyncHeader.position(0);
2645             mAvSyncBytesRemaining = sizeInBytes;
2646         }
2647 
2648         // write timestamp header if not completely written already
2649         int ret = 0;
2650         if (mAvSyncHeader.remaining() != 0) {
2651             ret = write(mAvSyncHeader, mAvSyncHeader.remaining(), writeMode);
2652             if (ret < 0) {
2653                 Log.e(TAG, "AudioTrack.write() could not write timestamp header!");
2654                 mAvSyncHeader = null;
2655                 mAvSyncBytesRemaining = 0;
2656                 return ret;
2657             }
2658             if (mAvSyncHeader.remaining() > 0) {
2659                 Log.v(TAG, "AudioTrack.write() partial timestamp header written.");
2660                 return 0;
2661             }
2662         }
2663 
2664         // write audio data
2665         int sizeToWrite = Math.min(mAvSyncBytesRemaining, sizeInBytes);
2666         ret = write(audioData, sizeToWrite, writeMode);
2667         if (ret < 0) {
2668             Log.e(TAG, "AudioTrack.write() could not write audio data!");
2669             mAvSyncHeader = null;
2670             mAvSyncBytesRemaining = 0;
2671             return ret;
2672         }
2673 
2674         mAvSyncBytesRemaining -= ret;
2675 
2676         return ret;
2677     }
2678 
2679 
2680     /**
2681      * Sets the playback head position within the static buffer to zero,
2682      * that is it rewinds to start of static buffer.
2683      * The track must be stopped or paused, and
2684      * the track's creation mode must be {@link #MODE_STATIC}.
2685      * <p>
2686      * As of {@link android.os.Build.VERSION_CODES#M}, also resets the value returned by
2687      * {@link #getPlaybackHeadPosition()} to zero.
2688      * For earlier API levels, the reset behavior is unspecified.
2689      * <p>
2690      * Use {@link #setPlaybackHeadPosition(int)} with a zero position
2691      * if the reset of <code>getPlaybackHeadPosition()</code> is not needed.
2692      * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
2693      *  {@link #ERROR_INVALID_OPERATION}
2694      */
reloadStaticData()2695     public int reloadStaticData() {
2696         if (mDataLoadMode == MODE_STREAM || mState != STATE_INITIALIZED) {
2697             return ERROR_INVALID_OPERATION;
2698         }
2699         return native_reload_static();
2700     }
2701 
2702     //--------------------------------------------------------------------------
2703     // Audio effects management
2704     //--------------------
2705 
2706     /**
2707      * Attaches an auxiliary effect to the audio track. A typical auxiliary
2708      * effect is a reverberation effect which can be applied on any sound source
2709      * that directs a certain amount of its energy to this effect. This amount
2710      * is defined by setAuxEffectSendLevel().
2711      * {@see #setAuxEffectSendLevel(float)}.
2712      * <p>After creating an auxiliary effect (e.g.
2713      * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with
2714      * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling
2715      * this method to attach the audio track to the effect.
2716      * <p>To detach the effect from the audio track, call this method with a
2717      * null effect id.
2718      *
2719      * @param effectId system wide unique id of the effect to attach
2720      * @return error code or success, see {@link #SUCCESS},
2721      *    {@link #ERROR_INVALID_OPERATION}, {@link #ERROR_BAD_VALUE}
2722      */
attachAuxEffect(int effectId)2723     public int attachAuxEffect(int effectId) {
2724         if (mState == STATE_UNINITIALIZED) {
2725             return ERROR_INVALID_OPERATION;
2726         }
2727         return native_attachAuxEffect(effectId);
2728     }
2729 
2730     /**
2731      * Sets the send level of the audio track to the attached auxiliary effect
2732      * {@link #attachAuxEffect(int)}.  Effect levels
2733      * are clamped to the closed interval [0.0, max] where
2734      * max is the value of {@link #getMaxVolume}.
2735      * A value of 0.0 results in no effect, and a value of 1.0 is full send.
2736      * <p>By default the send level is 0.0f, so even if an effect is attached to the player
2737      * this method must be called for the effect to be applied.
2738      * <p>Note that the passed level value is a linear scalar. UI controls should be scaled
2739      * logarithmically: the gain applied by audio framework ranges from -72dB to at least 0dB,
2740      * so an appropriate conversion from linear UI input x to level is:
2741      * x == 0 -&gt; level = 0
2742      * 0 &lt; x &lt;= R -&gt; level = 10^(72*(x-R)/20/R)
2743      *
2744      * @param level linear send level
2745      * @return error code or success, see {@link #SUCCESS},
2746      *    {@link #ERROR_INVALID_OPERATION}, {@link #ERROR}
2747      */
setAuxEffectSendLevel(float level)2748     public int setAuxEffectSendLevel(float level) {
2749         if (mState == STATE_UNINITIALIZED) {
2750             return ERROR_INVALID_OPERATION;
2751         }
2752         return baseSetAuxEffectSendLevel(level);
2753     }
2754 
2755     @Override
playerSetAuxEffectSendLevel(boolean muting, float level)2756     int playerSetAuxEffectSendLevel(boolean muting, float level) {
2757         level = clampGainOrLevel(muting ? 0.0f : level);
2758         int err = native_setAuxEffectSendLevel(level);
2759         return err == 0 ? SUCCESS : ERROR;
2760     }
2761 
2762     //--------------------------------------------------------------------------
2763     // Explicit Routing
2764     //--------------------
2765     private AudioDeviceInfo mPreferredDevice = null;
2766 
2767     /**
2768      * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
2769      * the output from this AudioTrack.
2770      * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio sink.
2771      *  If deviceInfo is null, default routing is restored.
2772      * @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
2773      * does not correspond to a valid audio output device.
2774      */
2775     @Override
setPreferredDevice(AudioDeviceInfo deviceInfo)2776     public boolean setPreferredDevice(AudioDeviceInfo deviceInfo) {
2777         // Do some validation....
2778         if (deviceInfo != null && !deviceInfo.isSink()) {
2779             return false;
2780         }
2781         int preferredDeviceId = deviceInfo != null ? deviceInfo.getId() : 0;
2782         boolean status = native_setOutputDevice(preferredDeviceId);
2783         if (status == true) {
2784             synchronized (this) {
2785                 mPreferredDevice = deviceInfo;
2786             }
2787         }
2788         return status;
2789     }
2790 
2791     /**
2792      * Returns the selected output specified by {@link #setPreferredDevice}. Note that this
2793      * is not guaranteed to correspond to the actual device being used for playback.
2794      */
2795     @Override
getPreferredDevice()2796     public AudioDeviceInfo getPreferredDevice() {
2797         synchronized (this) {
2798             return mPreferredDevice;
2799         }
2800     }
2801 
2802     /**
2803      * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioTrack.
2804      * Note: The query is only valid if the AudioTrack is currently playing. If it is not,
2805      * <code>getRoutedDevice()</code> will return null.
2806      */
2807     @Override
getRoutedDevice()2808     public AudioDeviceInfo getRoutedDevice() {
2809         int deviceId = native_getRoutedDeviceId();
2810         if (deviceId == 0) {
2811             return null;
2812         }
2813         AudioDeviceInfo[] devices =
2814                 AudioManager.getDevicesStatic(AudioManager.GET_DEVICES_OUTPUTS);
2815         for (int i = 0; i < devices.length; i++) {
2816             if (devices[i].getId() == deviceId) {
2817                 return devices[i];
2818             }
2819         }
2820         return null;
2821     }
2822 
2823     /*
2824      * Call BEFORE adding a routing callback handler.
2825      */
2826     @GuardedBy("mRoutingChangeListeners")
testEnableNativeRoutingCallbacksLocked()2827     private void testEnableNativeRoutingCallbacksLocked() {
2828         if (mRoutingChangeListeners.size() == 0) {
2829             native_enableDeviceCallback();
2830         }
2831     }
2832 
2833     /*
2834      * Call AFTER removing a routing callback handler.
2835      */
2836     @GuardedBy("mRoutingChangeListeners")
testDisableNativeRoutingCallbacksLocked()2837     private void testDisableNativeRoutingCallbacksLocked() {
2838         if (mRoutingChangeListeners.size() == 0) {
2839             native_disableDeviceCallback();
2840         }
2841     }
2842 
2843     //--------------------------------------------------------------------------
2844     // (Re)Routing Info
2845     //--------------------
2846     /**
2847      * The list of AudioRouting.OnRoutingChangedListener interfaces added (with
2848      * {@link #addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, Handler)}
2849      * by an app to receive (re)routing notifications.
2850      */
2851     @GuardedBy("mRoutingChangeListeners")
2852     private ArrayMap<AudioRouting.OnRoutingChangedListener,
2853             NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<>();
2854 
2855    /**
2856     * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
2857     * changes on this AudioTrack.
2858     * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
2859     * notifications of rerouting events.
2860     * @param handler  Specifies the {@link Handler} object for the thread on which to execute
2861     * the callback. If <code>null</code>, the {@link Handler} associated with the main
2862     * {@link Looper} will be used.
2863     */
2864     @Override
addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener, Handler handler)2865     public void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener,
2866             Handler handler) {
2867         synchronized (mRoutingChangeListeners) {
2868             if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
2869                 testEnableNativeRoutingCallbacksLocked();
2870                 mRoutingChangeListeners.put(
2871                         listener, new NativeRoutingEventHandlerDelegate(this, listener,
2872                                 handler != null ? handler : new Handler(mInitializationLooper)));
2873             }
2874         }
2875     }
2876 
2877     /**
2878      * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
2879      * to receive rerouting notifications.
2880      * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
2881      * to remove.
2882      */
2883     @Override
removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener)2884     public void removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener) {
2885         synchronized (mRoutingChangeListeners) {
2886             if (mRoutingChangeListeners.containsKey(listener)) {
2887                 mRoutingChangeListeners.remove(listener);
2888             }
2889             testDisableNativeRoutingCallbacksLocked();
2890         }
2891     }
2892 
2893     //--------------------------------------------------------------------------
2894     // (Re)Routing Info
2895     //--------------------
2896     /**
2897      * Defines the interface by which applications can receive notifications of
2898      * routing changes for the associated {@link AudioTrack}.
2899      *
2900      * @deprecated users should switch to the general purpose
2901      *             {@link AudioRouting.OnRoutingChangedListener} class instead.
2902      */
2903     @Deprecated
2904     public interface OnRoutingChangedListener extends AudioRouting.OnRoutingChangedListener {
2905         /**
2906          * Called when the routing of an AudioTrack changes from either and
2907          * explicit or policy rerouting. Use {@link #getRoutedDevice()} to
2908          * retrieve the newly routed-to device.
2909          */
onRoutingChanged(AudioTrack audioTrack)2910         public void onRoutingChanged(AudioTrack audioTrack);
2911 
2912         @Override
onRoutingChanged(AudioRouting router)2913         default public void onRoutingChanged(AudioRouting router) {
2914             if (router instanceof AudioTrack) {
2915                 onRoutingChanged((AudioTrack) router);
2916             }
2917         }
2918     }
2919 
2920     /**
2921      * Adds an {@link OnRoutingChangedListener} to receive notifications of routing changes
2922      * on this AudioTrack.
2923      * @param listener The {@link OnRoutingChangedListener} interface to receive notifications
2924      * of rerouting events.
2925      * @param handler  Specifies the {@link Handler} object for the thread on which to execute
2926      * the callback. If <code>null</code>, the {@link Handler} associated with the main
2927      * {@link Looper} will be used.
2928      * @deprecated users should switch to the general purpose
2929      *             {@link AudioRouting.OnRoutingChangedListener} class instead.
2930      */
2931     @Deprecated
addOnRoutingChangedListener(OnRoutingChangedListener listener, android.os.Handler handler)2932     public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
2933             android.os.Handler handler) {
2934         addOnRoutingChangedListener((AudioRouting.OnRoutingChangedListener) listener, handler);
2935     }
2936 
2937     /**
2938      * Removes an {@link OnRoutingChangedListener} which has been previously added
2939      * to receive rerouting notifications.
2940      * @param listener The previously added {@link OnRoutingChangedListener} interface to remove.
2941      * @deprecated users should switch to the general purpose
2942      *             {@link AudioRouting.OnRoutingChangedListener} class instead.
2943      */
2944     @Deprecated
removeOnRoutingChangedListener(OnRoutingChangedListener listener)2945     public void removeOnRoutingChangedListener(OnRoutingChangedListener listener) {
2946         removeOnRoutingChangedListener((AudioRouting.OnRoutingChangedListener) listener);
2947     }
2948 
2949     /**
2950      * Sends device list change notification to all listeners.
2951      */
broadcastRoutingChange()2952     private void broadcastRoutingChange() {
2953         AudioManager.resetAudioPortGeneration();
2954         synchronized (mRoutingChangeListeners) {
2955             for (NativeRoutingEventHandlerDelegate delegate : mRoutingChangeListeners.values()) {
2956                 delegate.notifyClient();
2957             }
2958         }
2959     }
2960 
2961     //---------------------------------------------------------
2962     // Interface definitions
2963     //--------------------
2964     /**
2965      * Interface definition for a callback to be invoked when the playback head position of
2966      * an AudioTrack has reached a notification marker or has increased by a certain period.
2967      */
2968     public interface OnPlaybackPositionUpdateListener  {
2969         /**
2970          * Called on the listener to notify it that the previously set marker has been reached
2971          * by the playback head.
2972          */
onMarkerReached(AudioTrack track)2973         void onMarkerReached(AudioTrack track);
2974 
2975         /**
2976          * Called on the listener to periodically notify it that the playback head has reached
2977          * a multiple of the notification period.
2978          */
onPeriodicNotification(AudioTrack track)2979         void onPeriodicNotification(AudioTrack track);
2980     }
2981 
2982     /**
2983      * @hide
2984      * Abstract class to receive event notification about the stream playback.
2985      * See {@link AudioTrack#setStreamEventCallback(Executor, StreamEventCallback)} to register
2986      * the callback on the given {@link AudioTrack} instance.
2987      */
2988     public abstract static class StreamEventCallback {
2989         /** @hide */ // add hidden empty constructor so it doesn't show in SDK
StreamEventCallback()2990         public StreamEventCallback() { }
2991         /**
2992          * Called when an offloaded track is no longer valid and has been discarded by the system.
2993          * An example of this happening is when an offloaded track has been paused too long, and
2994          * gets invalidated by the system to prevent any other offload.
2995          * @param track the {@link AudioTrack} on which the event happened
2996          */
onTearDown(AudioTrack track)2997         public void onTearDown(AudioTrack track) { }
2998         /**
2999          * Called when all the buffers of an offloaded track that were queued in the audio system
3000          * (e.g. the combination of the Android audio framework and the device's audio hardware)
3001          * have been played after {@link AudioTrack#stop()} has been called.
3002          * @param track the {@link AudioTrack} on which the event happened
3003          */
onStreamPresentationEnd(AudioTrack track)3004         public void onStreamPresentationEnd(AudioTrack track) { }
3005         /**
3006          * Called when more audio data can be written without blocking on an offloaded track.
3007          * @param track the {@link AudioTrack} on which the event happened
3008          */
onStreamDataRequest(AudioTrack track)3009         public void onStreamDataRequest(AudioTrack track) { }
3010     }
3011 
3012     private Executor mStreamEventExec;
3013     private StreamEventCallback mStreamEventCb;
3014     private final Object mStreamEventCbLock = new Object();
3015 
3016     /**
3017      * @hide
3018      * Sets the callback for the notification of stream events.
3019      * @param executor {@link Executor} to handle the callbacks
3020      * @param eventCallback the callback to receive the stream event notifications
3021      */
setStreamEventCallback(@onNull @allbackExecutor Executor executor, @NonNull StreamEventCallback eventCallback)3022     public void setStreamEventCallback(@NonNull @CallbackExecutor Executor executor,
3023             @NonNull StreamEventCallback eventCallback) {
3024         if (eventCallback == null) {
3025             throw new IllegalArgumentException("Illegal null StreamEventCallback");
3026         }
3027         if (executor == null) {
3028             throw new IllegalArgumentException("Illegal null Executor for the StreamEventCallback");
3029         }
3030         synchronized (mStreamEventCbLock) {
3031             mStreamEventExec = executor;
3032             mStreamEventCb = eventCallback;
3033         }
3034     }
3035 
3036     /**
3037      * @hide
3038      * Unregisters the callback for notification of stream events, previously set
3039      * by {@link #setStreamEventCallback(Executor, StreamEventCallback)}.
3040      */
removeStreamEventCallback()3041     public void removeStreamEventCallback() {
3042         synchronized (mStreamEventCbLock) {
3043             mStreamEventExec = null;
3044             mStreamEventCb = null;
3045         }
3046     }
3047 
3048     //---------------------------------------------------------
3049     // Inner classes
3050     //--------------------
3051     /**
3052      * Helper class to handle the forwarding of native events to the appropriate listener
3053      * (potentially) handled in a different thread
3054      */
3055     private class NativePositionEventHandlerDelegate {
3056         private final Handler mHandler;
3057 
NativePositionEventHandlerDelegate(final AudioTrack track, final OnPlaybackPositionUpdateListener listener, Handler handler)3058         NativePositionEventHandlerDelegate(final AudioTrack track,
3059                                    final OnPlaybackPositionUpdateListener listener,
3060                                    Handler handler) {
3061             // find the looper for our new event handler
3062             Looper looper;
3063             if (handler != null) {
3064                 looper = handler.getLooper();
3065             } else {
3066                 // no given handler, use the looper the AudioTrack was created in
3067                 looper = mInitializationLooper;
3068             }
3069 
3070             // construct the event handler with this looper
3071             if (looper != null) {
3072                 // implement the event handler delegate
3073                 mHandler = new Handler(looper) {
3074                     @Override
3075                     public void handleMessage(Message msg) {
3076                         if (track == null) {
3077                             return;
3078                         }
3079                         switch(msg.what) {
3080                         case NATIVE_EVENT_MARKER:
3081                             if (listener != null) {
3082                                 listener.onMarkerReached(track);
3083                             }
3084                             break;
3085                         case NATIVE_EVENT_NEW_POS:
3086                             if (listener != null) {
3087                                 listener.onPeriodicNotification(track);
3088                             }
3089                             break;
3090                         default:
3091                             loge("Unknown native event type: " + msg.what);
3092                             break;
3093                         }
3094                     }
3095                 };
3096             } else {
3097                 mHandler = null;
3098             }
3099         }
3100 
getHandler()3101         Handler getHandler() {
3102             return mHandler;
3103         }
3104     }
3105 
3106     //---------------------------------------------------------
3107     // Methods for IPlayer interface
3108     //--------------------
3109     @Override
playerStart()3110     void playerStart() {
3111         play();
3112     }
3113 
3114     @Override
playerPause()3115     void playerPause() {
3116         pause();
3117     }
3118 
3119     @Override
playerStop()3120     void playerStop() {
3121         stop();
3122     }
3123 
3124     //---------------------------------------------------------
3125     // Java methods called from the native side
3126     //--------------------
3127     @SuppressWarnings("unused")
postEventFromNative(Object audiotrack_ref, int what, int arg1, int arg2, Object obj)3128     private static void postEventFromNative(Object audiotrack_ref,
3129             int what, int arg1, int arg2, Object obj) {
3130         //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2);
3131         final AudioTrack track = (AudioTrack)((WeakReference)audiotrack_ref).get();
3132         if (track == null) {
3133             return;
3134         }
3135 
3136         if (what == AudioSystem.NATIVE_EVENT_ROUTING_CHANGE) {
3137             track.broadcastRoutingChange();
3138             return;
3139         }
3140 
3141         if (what == NATIVE_EVENT_MORE_DATA || what == NATIVE_EVENT_NEW_IAUDIOTRACK
3142                 || what == NATIVE_EVENT_STREAM_END) {
3143             final Executor exec;
3144             final StreamEventCallback cb;
3145             synchronized (track.mStreamEventCbLock) {
3146                 exec = track.mStreamEventExec;
3147                 cb = track.mStreamEventCb;
3148             }
3149             if ((exec == null) || (cb == null)) {
3150                 return;
3151             }
3152             switch (what) {
3153                 case NATIVE_EVENT_MORE_DATA:
3154                     exec.execute(() -> cb.onStreamDataRequest(track));
3155                     return;
3156                 case NATIVE_EVENT_NEW_IAUDIOTRACK:
3157                     // TODO also release track as it's not longer usable
3158                     exec.execute(() -> cb.onTearDown(track));
3159                     return;
3160                 case NATIVE_EVENT_STREAM_END:
3161                     exec.execute(() -> cb.onStreamPresentationEnd(track));
3162                     return;
3163             }
3164         }
3165 
3166         NativePositionEventHandlerDelegate delegate = track.mEventHandlerDelegate;
3167         if (delegate != null) {
3168             Handler handler = delegate.getHandler();
3169             if (handler != null) {
3170                 Message m = handler.obtainMessage(what, arg1, arg2, obj);
3171                 handler.sendMessage(m);
3172             }
3173         }
3174     }
3175 
3176 
3177     //---------------------------------------------------------
3178     // Native methods called from the Java side
3179     //--------------------
3180 
3181     // post-condition: mStreamType is overwritten with a value
3182     //     that reflects the audio attributes (e.g. an AudioAttributes object with a usage of
3183     //     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, long nativeAudioTrack, boolean offload)3184     private native final int native_setup(Object /*WeakReference<AudioTrack>*/ audiotrack_this,
3185             Object /*AudioAttributes*/ attributes,
3186             int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
3187             int buffSizeInBytes, int mode, int[] sessionId, long nativeAudioTrack,
3188             boolean offload);
3189 
native_finalize()3190     private native final void native_finalize();
3191 
3192     /**
3193      * @hide
3194      */
native_release()3195     public native final void native_release();
3196 
native_start()3197     private native final void native_start();
3198 
native_stop()3199     private native final void native_stop();
3200 
native_pause()3201     private native final void native_pause();
3202 
native_flush()3203     private native final void native_flush();
3204 
native_write_byte(byte[] audioData, int offsetInBytes, int sizeInBytes, int format, boolean isBlocking)3205     private native final int native_write_byte(byte[] audioData,
3206                                                int offsetInBytes, int sizeInBytes, int format,
3207                                                boolean isBlocking);
3208 
native_write_short(short[] audioData, int offsetInShorts, int sizeInShorts, int format, boolean isBlocking)3209     private native final int native_write_short(short[] audioData,
3210                                                 int offsetInShorts, int sizeInShorts, int format,
3211                                                 boolean isBlocking);
3212 
native_write_float(float[] audioData, int offsetInFloats, int sizeInFloats, int format, boolean isBlocking)3213     private native final int native_write_float(float[] audioData,
3214                                                 int offsetInFloats, int sizeInFloats, int format,
3215                                                 boolean isBlocking);
3216 
native_write_native_bytes(Object audioData, int positionInBytes, int sizeInBytes, int format, boolean blocking)3217     private native final int native_write_native_bytes(Object audioData,
3218             int positionInBytes, int sizeInBytes, int format, boolean blocking);
3219 
native_reload_static()3220     private native final int native_reload_static();
3221 
native_get_buffer_size_frames()3222     private native final int native_get_buffer_size_frames();
native_set_buffer_size_frames(int bufferSizeInFrames)3223     private native final int native_set_buffer_size_frames(int bufferSizeInFrames);
native_get_buffer_capacity_frames()3224     private native final int native_get_buffer_capacity_frames();
3225 
native_setVolume(float leftVolume, float rightVolume)3226     private native final void native_setVolume(float leftVolume, float rightVolume);
3227 
native_set_playback_rate(int sampleRateInHz)3228     private native final int native_set_playback_rate(int sampleRateInHz);
native_get_playback_rate()3229     private native final int native_get_playback_rate();
3230 
native_set_playback_params(@onNull PlaybackParams params)3231     private native final void native_set_playback_params(@NonNull PlaybackParams params);
native_get_playback_params()3232     private native final @NonNull PlaybackParams native_get_playback_params();
3233 
native_set_marker_pos(int marker)3234     private native final int native_set_marker_pos(int marker);
native_get_marker_pos()3235     private native final int native_get_marker_pos();
3236 
native_set_pos_update_period(int updatePeriod)3237     private native final int native_set_pos_update_period(int updatePeriod);
native_get_pos_update_period()3238     private native final int native_get_pos_update_period();
3239 
native_set_position(int position)3240     private native final int native_set_position(int position);
native_get_position()3241     private native final int native_get_position();
3242 
native_get_latency()3243     private native final int native_get_latency();
3244 
native_get_underrun_count()3245     private native final int native_get_underrun_count();
3246 
native_get_flags()3247     private native final int native_get_flags();
3248 
3249     // longArray must be a non-null array of length >= 2
3250     // [0] is assigned the frame position
3251     // [1] is assigned the time in CLOCK_MONOTONIC nanoseconds
native_get_timestamp(long[] longArray)3252     private native final int native_get_timestamp(long[] longArray);
3253 
native_set_loop(int start, int end, int loopCount)3254     private native final int native_set_loop(int start, int end, int loopCount);
3255 
native_get_output_sample_rate(int streamType)3256     static private native final int native_get_output_sample_rate(int streamType);
native_get_min_buff_size( int sampleRateInHz, int channelConfig, int audioFormat)3257     static private native final int native_get_min_buff_size(
3258             int sampleRateInHz, int channelConfig, int audioFormat);
3259 
native_attachAuxEffect(int effectId)3260     private native final int native_attachAuxEffect(int effectId);
native_setAuxEffectSendLevel(float level)3261     private native final int native_setAuxEffectSendLevel(float level);
3262 
native_setOutputDevice(int deviceId)3263     private native final boolean native_setOutputDevice(int deviceId);
native_getRoutedDeviceId()3264     private native final int native_getRoutedDeviceId();
native_enableDeviceCallback()3265     private native final void native_enableDeviceCallback();
native_disableDeviceCallback()3266     private native final void native_disableDeviceCallback();
native_get_FCC_8()3267     static private native int native_get_FCC_8();
3268 
native_applyVolumeShaper( @onNull VolumeShaper.Configuration configuration, @NonNull VolumeShaper.Operation operation)3269     private native int native_applyVolumeShaper(
3270             @NonNull VolumeShaper.Configuration configuration,
3271             @NonNull VolumeShaper.Operation operation);
3272 
native_getVolumeShaperState(int id)3273     private native @Nullable VolumeShaper.State native_getVolumeShaperState(int id);
native_setPresentation(int presentationId, int programId)3274     private native final int native_setPresentation(int presentationId, int programId);
3275 
3276     //---------------------------------------------------------
3277     // Utility methods
3278     //------------------
3279 
logd(String msg)3280     private static void logd(String msg) {
3281         Log.d(TAG, msg);
3282     }
3283 
loge(String msg)3284     private static void loge(String msg) {
3285         Log.e(TAG, msg);
3286     }
3287 
3288     public final static class MetricsConstants
3289     {
MetricsConstants()3290         private MetricsConstants() {}
3291 
3292         /**
3293          * Key to extract the Stream Type for this track
3294          * from the {@link AudioTrack#getMetrics} return value.
3295          * The value is a String.
3296          */
3297         public static final String STREAMTYPE = "android.media.audiotrack.streamtype";
3298 
3299         /**
3300          * Key to extract the Content Type for this track
3301          * from the {@link AudioTrack#getMetrics} return value.
3302          * The value is a String.
3303          */
3304         public static final String CONTENTTYPE = "android.media.audiotrack.type";
3305 
3306         /**
3307          * Key to extract the Content Type for this track
3308          * from the {@link AudioTrack#getMetrics} return value.
3309          * The value is a String.
3310          */
3311         public static final String USAGE = "android.media.audiotrack.usage";
3312 
3313         /**
3314          * Key to extract the sample rate for this track in Hz
3315          * from the {@link AudioTrack#getMetrics} return value.
3316          * The value is an integer.
3317          */
3318         public static final String SAMPLERATE = "android.media.audiorecord.samplerate";
3319 
3320         /**
3321          * Key to extract the channel mask information for this track
3322          * from the {@link AudioTrack#getMetrics} return value.
3323          *
3324          * The value is a Long integer.
3325          */
3326         public static final String CHANNELMASK = "android.media.audiorecord.channelmask";
3327 
3328     }
3329 }
3330