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