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