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