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