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