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; 24import java.util.Iterator; 25import java.util.Set; 26 27import android.annotation.IntDef; 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 /** 120 * State of an AudioTrack that was not successfully initialized upon creation. 121 */ 122 public static final int STATE_UNINITIALIZED = 0; 123 /** 124 * State of an AudioTrack that is ready to be used. 125 */ 126 public static final int STATE_INITIALIZED = 1; 127 /** 128 * State of a successfully initialized AudioTrack that uses static data, 129 * but that hasn't received that data yet. 130 */ 131 public static final int STATE_NO_STATIC_DATA = 2; 132 133 /** 134 * Denotes a successful operation. 135 */ 136 public static final int SUCCESS = AudioSystem.SUCCESS; 137 /** 138 * Denotes a generic operation failure. 139 */ 140 public static final int ERROR = AudioSystem.ERROR; 141 /** 142 * Denotes a failure due to the use of an invalid value. 143 */ 144 public static final int ERROR_BAD_VALUE = AudioSystem.BAD_VALUE; 145 /** 146 * Denotes a failure due to the improper use of a method. 147 */ 148 public static final int ERROR_INVALID_OPERATION = AudioSystem.INVALID_OPERATION; 149 150 // Error codes: 151 // to keep in sync with frameworks/base/core/jni/android_media_AudioTrack.cpp 152 private static final int ERROR_NATIVESETUP_AUDIOSYSTEM = -16; 153 private static final int ERROR_NATIVESETUP_INVALIDCHANNELMASK = -17; 154 private static final int ERROR_NATIVESETUP_INVALIDFORMAT = -18; 155 private static final int ERROR_NATIVESETUP_INVALIDSTREAMTYPE = -19; 156 private static final int ERROR_NATIVESETUP_NATIVEINITFAILED = -20; 157 158 // Events: 159 // to keep in sync with frameworks/av/include/media/AudioTrack.h 160 /** 161 * Event id denotes when playback head has reached a previously set marker. 162 */ 163 private static final int NATIVE_EVENT_MARKER = 3; 164 /** 165 * Event id denotes when previously set update period has elapsed during playback. 166 */ 167 private static final int NATIVE_EVENT_NEW_POS = 4; 168 169 private final static String TAG = "android.media.AudioTrack"; 170 171 172 /** @hide */ 173 @IntDef({ 174 WRITE_BLOCKING, 175 WRITE_NON_BLOCKING 176 }) 177 @Retention(RetentionPolicy.SOURCE) 178 public @interface WriteMode {} 179 180 /** 181 * The write mode indicating the write operation will block until all data has been written, 182 * to be used in {@link #write(ByteBuffer, int, int)} 183 */ 184 public final static int WRITE_BLOCKING = 0; 185 /** 186 * The write mode indicating the write operation will return immediately after 187 * queuing as much audio data for playback as possible without blocking, to be used in 188 * {@link #write(ByteBuffer, int, int)}. 189 */ 190 public final static int WRITE_NON_BLOCKING = 1; 191 192 //-------------------------------------------------------------------------- 193 // Member variables 194 //-------------------- 195 /** 196 * Indicates the state of the AudioTrack instance. 197 */ 198 private int mState = STATE_UNINITIALIZED; 199 /** 200 * Indicates the play state of the AudioTrack instance. 201 */ 202 private int mPlayState = PLAYSTATE_STOPPED; 203 /** 204 * Lock to make sure mPlayState updates are reflecting the actual state of the object. 205 */ 206 private final Object mPlayStateLock = new Object(); 207 /** 208 * Sizes of the native audio buffer. 209 */ 210 private int mNativeBufferSizeInBytes = 0; 211 private int mNativeBufferSizeInFrames = 0; 212 /** 213 * Handler for events coming from the native code. 214 */ 215 private NativeEventHandlerDelegate mEventHandlerDelegate; 216 /** 217 * Looper associated with the thread that creates the AudioTrack instance. 218 */ 219 private final Looper mInitializationLooper; 220 /** 221 * The audio data source sampling rate in Hz. 222 */ 223 private int mSampleRate; // initialized by all constructors 224 /** 225 * The number of audio output channels (1 is mono, 2 is stereo). 226 */ 227 private int mChannelCount = 1; 228 /** 229 * The audio channel mask. 230 */ 231 private int mChannels = AudioFormat.CHANNEL_OUT_MONO; 232 233 /** 234 * The type of the audio stream to play. See 235 * {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM}, 236 * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC}, 237 * {@link AudioManager#STREAM_ALARM}, {@link AudioManager#STREAM_NOTIFICATION}, and 238 * {@link AudioManager#STREAM_DTMF}. 239 */ 240 private int mStreamType = AudioManager.STREAM_MUSIC; 241 242 private final AudioAttributes mAttributes; 243 /** 244 * The way audio is consumed by the audio sink, streaming or static. 245 */ 246 private int mDataLoadMode = MODE_STREAM; 247 /** 248 * The current audio channel configuration. 249 */ 250 private int mChannelConfiguration = AudioFormat.CHANNEL_OUT_MONO; 251 /** 252 * The encoding of the audio samples. 253 * @see AudioFormat#ENCODING_PCM_8BIT 254 * @see AudioFormat#ENCODING_PCM_16BIT 255 * @see AudioFormat#ENCODING_PCM_FLOAT 256 */ 257 private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT; 258 /** 259 * Audio session ID 260 */ 261 private int mSessionId = AudioSystem.AUDIO_SESSION_ALLOCATE; 262 /** 263 * Reference to the app-ops service. 264 */ 265 private final IAppOpsService mAppOps; 266 267 //-------------------------------- 268 // Used exclusively by native code 269 //-------------------- 270 /** 271 * Accessed by native methods: provides access to C++ AudioTrack object. 272 */ 273 @SuppressWarnings("unused") 274 private long mNativeTrackInJavaObj; 275 /** 276 * Accessed by native methods: provides access to the JNI data (i.e. resources used by 277 * the native AudioTrack object, but not stored in it). 278 */ 279 @SuppressWarnings("unused") 280 private long mJniData; 281 282 283 //-------------------------------------------------------------------------- 284 // Constructor, Finalize 285 //-------------------- 286 /** 287 * Class constructor. 288 * @param streamType the type of the audio stream. See 289 * {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM}, 290 * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC}, 291 * {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}. 292 * @param sampleRateInHz the initial source sample rate expressed in Hz. 293 * @param channelConfig describes the configuration of the audio channels. 294 * See {@link AudioFormat#CHANNEL_OUT_MONO} and 295 * {@link AudioFormat#CHANNEL_OUT_STEREO} 296 * @param audioFormat the format in which the audio data is represented. 297 * See {@link AudioFormat#ENCODING_PCM_16BIT}, 298 * {@link AudioFormat#ENCODING_PCM_8BIT}, 299 * and {@link AudioFormat#ENCODING_PCM_FLOAT}. 300 * @param bufferSizeInBytes the total size (in bytes) of the internal buffer where audio data is 301 * read from for playback. 302 * If track's creation mode is {@link #MODE_STREAM}, you can write data into 303 * this buffer in chunks less than or equal to this size, and it is typical to use 304 * chunks of 1/2 of the total size to permit double-buffering. 305 * If the track's creation mode is {@link #MODE_STATIC}, 306 * this is the maximum length sample, or audio clip, that can be played by this instance. 307 * See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size 308 * for the successful creation of an AudioTrack instance in streaming mode. Using values 309 * smaller than getMinBufferSize() will result in an initialization failure. 310 * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM} 311 * @throws java.lang.IllegalArgumentException 312 */ 313 public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, 314 int bufferSizeInBytes, int mode) 315 throws IllegalArgumentException { 316 this(streamType, sampleRateInHz, channelConfig, audioFormat, 317 bufferSizeInBytes, mode, AudioSystem.AUDIO_SESSION_ALLOCATE); 318 } 319 320 /** 321 * Class constructor with audio session. Use this constructor when the AudioTrack must be 322 * attached to a particular audio session. The primary use of the audio session ID is to 323 * associate audio effects to a particular instance of AudioTrack: if an audio session ID 324 * is provided when creating an AudioEffect, this effect will be applied only to audio tracks 325 * and media players in the same session and not to the output mix. 326 * When an AudioTrack is created without specifying a session, it will create its own session 327 * which can be retrieved by calling the {@link #getAudioSessionId()} method. 328 * If a non-zero session ID is provided, this AudioTrack will share effects attached to this 329 * session 330 * with all other media players or audio tracks in the same session, otherwise a new session 331 * will be created for this track if none is supplied. 332 * @param streamType the type of the audio stream. See 333 * {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM}, 334 * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC}, 335 * {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}. 336 * @param sampleRateInHz the initial source sample rate expressed in Hz. 337 * @param channelConfig describes the configuration of the audio channels. 338 * See {@link AudioFormat#CHANNEL_OUT_MONO} and 339 * {@link AudioFormat#CHANNEL_OUT_STEREO} 340 * @param audioFormat the format in which the audio data is represented. 341 * See {@link AudioFormat#ENCODING_PCM_16BIT} and 342 * {@link AudioFormat#ENCODING_PCM_8BIT}, 343 * and {@link AudioFormat#ENCODING_PCM_FLOAT}. 344 * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read 345 * from for playback. If using the AudioTrack in streaming mode, you can write data into 346 * this buffer in smaller chunks than this size. If using the AudioTrack in static mode, 347 * this is the maximum size of the sound that will be played for this instance. 348 * See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size 349 * for the successful creation of an AudioTrack instance in streaming mode. Using values 350 * smaller than getMinBufferSize() will result in an initialization failure. 351 * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM} 352 * @param sessionId Id of audio session the AudioTrack must be attached to 353 * @throws java.lang.IllegalArgumentException 354 */ 355 public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, 356 int bufferSizeInBytes, int mode, int sessionId) 357 throws IllegalArgumentException { 358 // mState already == STATE_UNINITIALIZED 359 this((new AudioAttributes.Builder()) 360 .setLegacyStreamType(streamType) 361 .build(), 362 (new AudioFormat.Builder()) 363 .setChannelMask(channelConfig) 364 .setEncoding(audioFormat) 365 .setSampleRate(sampleRateInHz) 366 .build(), 367 bufferSizeInBytes, 368 mode, sessionId); 369 } 370 371 /** 372 * Class constructor with {@link AudioAttributes} and {@link AudioFormat}. 373 * @param attributes a non-null {@link AudioAttributes} instance. 374 * @param format a non-null {@link AudioFormat} instance describing the format of the data 375 * that will be played through this AudioTrack. See {@link AudioFormat.Builder} for 376 * configuring the audio format parameters such as encoding, channel mask and sample rate. 377 * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read 378 * from for playback. If using the AudioTrack in streaming mode, you can write data into 379 * this buffer in smaller chunks than this size. If using the AudioTrack in static mode, 380 * this is the maximum size of the sound that will be played for this instance. 381 * See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size 382 * for the successful creation of an AudioTrack instance in streaming mode. Using values 383 * smaller than getMinBufferSize() will result in an initialization failure. 384 * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}. 385 * @param sessionId ID of audio session the AudioTrack must be attached to, or 386 * {@link AudioManager#AUDIO_SESSION_ID_GENERATE} if the session isn't known at construction 387 * time. See also {@link AudioManager#generateAudioSessionId()} to obtain a session ID before 388 * construction. 389 * @throws IllegalArgumentException 390 */ 391 public AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes, 392 int mode, int sessionId) 393 throws IllegalArgumentException { 394 // mState already == STATE_UNINITIALIZED 395 396 if (attributes == null) { 397 throw new IllegalArgumentException("Illegal null AudioAttributes"); 398 } 399 if (format == null) { 400 throw new IllegalArgumentException("Illegal null AudioFormat"); 401 } 402 403 // remember which looper is associated with the AudioTrack instantiation 404 Looper looper; 405 if ((looper = Looper.myLooper()) == null) { 406 looper = Looper.getMainLooper(); 407 } 408 409 int rate = 0; 410 if ((format.getPropertySetMask() & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) != 0) 411 { 412 rate = format.getSampleRate(); 413 } else { 414 rate = AudioSystem.getPrimaryOutputSamplingRate(); 415 if (rate <= 0) { 416 rate = 44100; 417 } 418 } 419 int channelMask = AudioFormat.CHANNEL_OUT_FRONT_LEFT | AudioFormat.CHANNEL_OUT_FRONT_RIGHT; 420 if ((format.getPropertySetMask() & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) != 0) 421 { 422 channelMask = format.getChannelMask(); 423 } 424 int encoding = AudioFormat.ENCODING_DEFAULT; 425 if ((format.getPropertySetMask() & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_ENCODING) != 0) { 426 encoding = format.getEncoding(); 427 } 428 audioParamCheck(rate, channelMask, encoding, mode); 429 mStreamType = AudioSystem.STREAM_DEFAULT; 430 431 audioBuffSizeCheck(bufferSizeInBytes); 432 433 mInitializationLooper = looper; 434 IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE); 435 mAppOps = IAppOpsService.Stub.asInterface(b); 436 437 mAttributes = (new AudioAttributes.Builder(attributes).build()); 438 439 if (sessionId < 0) { 440 throw new IllegalArgumentException("Invalid audio session ID: "+sessionId); 441 } 442 443 int[] session = new int[1]; 444 session[0] = sessionId; 445 // native initialization 446 int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes, 447 mSampleRate, mChannels, mAudioFormat, 448 mNativeBufferSizeInBytes, mDataLoadMode, session); 449 if (initResult != SUCCESS) { 450 loge("Error code "+initResult+" when initializing AudioTrack."); 451 return; // with mState == STATE_UNINITIALIZED 452 } 453 454 mSessionId = session[0]; 455 456 if (mDataLoadMode == MODE_STATIC) { 457 mState = STATE_NO_STATIC_DATA; 458 } else { 459 mState = STATE_INITIALIZED; 460 } 461 } 462 463 // mask of all the channels supported by this implementation 464 private static final int SUPPORTED_OUT_CHANNELS = 465 AudioFormat.CHANNEL_OUT_FRONT_LEFT | 466 AudioFormat.CHANNEL_OUT_FRONT_RIGHT | 467 AudioFormat.CHANNEL_OUT_FRONT_CENTER | 468 AudioFormat.CHANNEL_OUT_LOW_FREQUENCY | 469 AudioFormat.CHANNEL_OUT_BACK_LEFT | 470 AudioFormat.CHANNEL_OUT_BACK_RIGHT | 471 AudioFormat.CHANNEL_OUT_BACK_CENTER | 472 AudioFormat.CHANNEL_OUT_SIDE_LEFT | 473 AudioFormat.CHANNEL_OUT_SIDE_RIGHT; 474 475 // Convenience method for the constructor's parameter checks. 476 // This is where constructor IllegalArgumentException-s are thrown 477 // postconditions: 478 // mChannelCount is valid 479 // mChannels is valid 480 // mAudioFormat is valid 481 // mSampleRate is valid 482 // mDataLoadMode is valid 483 private void audioParamCheck(int sampleRateInHz, 484 int channelConfig, int audioFormat, int mode) { 485 //-------------- 486 // sample rate, note these values are subject to change 487 if (sampleRateInHz < SAMPLE_RATE_HZ_MIN || sampleRateInHz > SAMPLE_RATE_HZ_MAX) { 488 throw new IllegalArgumentException(sampleRateInHz 489 + "Hz is not a supported sample rate."); 490 } 491 mSampleRate = sampleRateInHz; 492 493 //-------------- 494 // channel config 495 mChannelConfiguration = channelConfig; 496 497 switch (channelConfig) { 498 case AudioFormat.CHANNEL_OUT_DEFAULT: //AudioFormat.CHANNEL_CONFIGURATION_DEFAULT 499 case AudioFormat.CHANNEL_OUT_MONO: 500 case AudioFormat.CHANNEL_CONFIGURATION_MONO: 501 mChannelCount = 1; 502 mChannels = AudioFormat.CHANNEL_OUT_MONO; 503 break; 504 case AudioFormat.CHANNEL_OUT_STEREO: 505 case AudioFormat.CHANNEL_CONFIGURATION_STEREO: 506 mChannelCount = 2; 507 mChannels = AudioFormat.CHANNEL_OUT_STEREO; 508 break; 509 default: 510 if (!isMultichannelConfigSupported(channelConfig)) { 511 // input channel configuration features unsupported channels 512 throw new IllegalArgumentException("Unsupported channel configuration."); 513 } 514 mChannels = channelConfig; 515 mChannelCount = Integer.bitCount(channelConfig); 516 } 517 518 //-------------- 519 // audio format 520 if (audioFormat == AudioFormat.ENCODING_DEFAULT) { 521 audioFormat = AudioFormat.ENCODING_PCM_16BIT; 522 } 523 524 if (!AudioFormat.isValidEncoding(audioFormat)) { 525 throw new IllegalArgumentException("Unsupported audio encoding."); 526 } 527 mAudioFormat = audioFormat; 528 529 //-------------- 530 // audio load mode 531 if (((mode != MODE_STREAM) && (mode != MODE_STATIC)) || 532 ((mode != MODE_STREAM) && !AudioFormat.isEncodingLinearPcm(mAudioFormat))) { 533 throw new IllegalArgumentException("Invalid mode."); 534 } 535 mDataLoadMode = mode; 536 } 537 538 /** 539 * Convenience method to check that the channel configuration (a.k.a channel mask) is supported 540 * @param channelConfig the mask to validate 541 * @return false if the AudioTrack can't be used with such a mask 542 */ 543 private static boolean isMultichannelConfigSupported(int channelConfig) { 544 // check for unsupported channels 545 if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) { 546 loge("Channel configuration features unsupported channels"); 547 return false; 548 } 549 final int channelCount = Integer.bitCount(channelConfig); 550 if (channelCount > CHANNEL_COUNT_MAX) { 551 loge("Channel configuration contains too many channels " + 552 channelCount + ">" + CHANNEL_COUNT_MAX); 553 return false; 554 } 555 // check for unsupported multichannel combinations: 556 // - FL/FR must be present 557 // - L/R channels must be paired (e.g. no single L channel) 558 final int frontPair = 559 AudioFormat.CHANNEL_OUT_FRONT_LEFT | AudioFormat.CHANNEL_OUT_FRONT_RIGHT; 560 if ((channelConfig & frontPair) != frontPair) { 561 loge("Front channels must be present in multichannel configurations"); 562 return false; 563 } 564 final int backPair = 565 AudioFormat.CHANNEL_OUT_BACK_LEFT | AudioFormat.CHANNEL_OUT_BACK_RIGHT; 566 if ((channelConfig & backPair) != 0) { 567 if ((channelConfig & backPair) != backPair) { 568 loge("Rear channels can't be used independently"); 569 return false; 570 } 571 } 572 final int sidePair = 573 AudioFormat.CHANNEL_OUT_SIDE_LEFT | AudioFormat.CHANNEL_OUT_SIDE_RIGHT; 574 if ((channelConfig & sidePair) != 0 575 && (channelConfig & sidePair) != sidePair) { 576 loge("Side channels can't be used independently"); 577 return false; 578 } 579 return true; 580 } 581 582 583 // Convenience method for the constructor's audio buffer size check. 584 // preconditions: 585 // mChannelCount is valid 586 // mAudioFormat is valid 587 // postcondition: 588 // mNativeBufferSizeInBytes is valid (multiple of frame size, positive) 589 private void audioBuffSizeCheck(int audioBufferSize) { 590 // NB: this section is only valid with PCM data. 591 // To update when supporting compressed formats 592 int frameSizeInBytes; 593 if (AudioFormat.isEncodingLinearPcm(mAudioFormat)) { 594 frameSizeInBytes = mChannelCount 595 * (AudioFormat.getBytesPerSample(mAudioFormat)); 596 } else { 597 frameSizeInBytes = 1; 598 } 599 if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) { 600 throw new IllegalArgumentException("Invalid audio buffer size."); 601 } 602 603 mNativeBufferSizeInBytes = audioBufferSize; 604 mNativeBufferSizeInFrames = audioBufferSize / frameSizeInBytes; 605 } 606 607 608 /** 609 * Releases the native AudioTrack resources. 610 */ 611 public void release() { 612 // even though native_release() stops the native AudioTrack, we need to stop 613 // AudioTrack subclasses too. 614 try { 615 stop(); 616 } catch(IllegalStateException ise) { 617 // don't raise an exception, we're releasing the resources. 618 } 619 native_release(); 620 mState = STATE_UNINITIALIZED; 621 } 622 623 @Override 624 protected void finalize() { 625 native_finalize(); 626 } 627 628 //-------------------------------------------------------------------------- 629 // Getters 630 //-------------------- 631 /** 632 * Returns the minimum gain value, which is the constant 0.0. 633 * Gain values less than 0.0 will be clamped to 0.0. 634 * <p>The word "volume" in the API name is historical; this is actually a linear gain. 635 * @return the minimum value, which is the constant 0.0. 636 */ 637 static public float getMinVolume() { 638 return GAIN_MIN; 639 } 640 641 /** 642 * Returns the maximum gain value, which is greater than or equal to 1.0. 643 * Gain values greater than the maximum will be clamped to the maximum. 644 * <p>The word "volume" in the API name is historical; this is actually a gain. 645 * expressed as a linear multiplier on sample values, where a maximum value of 1.0 646 * corresponds to a gain of 0 dB (sample values left unmodified). 647 * @return the maximum value, which is greater than or equal to 1.0. 648 */ 649 static public float getMaxVolume() { 650 return GAIN_MAX; 651 } 652 653 /** 654 * Returns the configured audio data sample rate in Hz 655 */ 656 public int getSampleRate() { 657 return mSampleRate; 658 } 659 660 /** 661 * Returns the current playback rate in Hz. 662 */ 663 public int getPlaybackRate() { 664 return native_get_playback_rate(); 665 } 666 667 /** 668 * Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_16BIT} 669 * and {@link AudioFormat#ENCODING_PCM_8BIT}. 670 */ 671 public int getAudioFormat() { 672 return mAudioFormat; 673 } 674 675 /** 676 * Returns the type of audio stream this AudioTrack is configured for. 677 * Compare the result against {@link AudioManager#STREAM_VOICE_CALL}, 678 * {@link AudioManager#STREAM_SYSTEM}, {@link AudioManager#STREAM_RING}, 679 * {@link AudioManager#STREAM_MUSIC}, {@link AudioManager#STREAM_ALARM}, 680 * {@link AudioManager#STREAM_NOTIFICATION}, or {@link AudioManager#STREAM_DTMF}. 681 */ 682 public int getStreamType() { 683 return mStreamType; 684 } 685 686 /** 687 * Returns the configured channel configuration. 688 * See {@link AudioFormat#CHANNEL_OUT_MONO} 689 * and {@link AudioFormat#CHANNEL_OUT_STEREO}. 690 */ 691 public int getChannelConfiguration() { 692 return mChannelConfiguration; 693 } 694 695 /** 696 * Returns the configured number of channels. 697 */ 698 public int getChannelCount() { 699 return mChannelCount; 700 } 701 702 /** 703 * Returns the state of the AudioTrack instance. This is useful after the 704 * AudioTrack instance has been created to check if it was initialized 705 * properly. This ensures that the appropriate resources have been acquired. 706 * @see #STATE_INITIALIZED 707 * @see #STATE_NO_STATIC_DATA 708 * @see #STATE_UNINITIALIZED 709 */ 710 public int getState() { 711 return mState; 712 } 713 714 /** 715 * Returns the playback state of the AudioTrack instance. 716 * @see #PLAYSTATE_STOPPED 717 * @see #PLAYSTATE_PAUSED 718 * @see #PLAYSTATE_PLAYING 719 */ 720 public int getPlayState() { 721 synchronized (mPlayStateLock) { 722 return mPlayState; 723 } 724 } 725 726 /** 727 * Returns the "native frame count", derived from the bufferSizeInBytes specified at 728 * creation time and converted to frame units. 729 * If track's creation mode is {@link #MODE_STATIC}, 730 * it is equal to the specified bufferSizeInBytes converted to frame units. 731 * If track's creation mode is {@link #MODE_STREAM}, 732 * it is typically greater than or equal to the specified bufferSizeInBytes converted to frame 733 * units; it may be rounded up to a larger value if needed by the target device implementation. 734 * @deprecated Only accessible by subclasses, which are not recommended for AudioTrack. 735 * See {@link AudioManager#getProperty(String)} for key 736 * {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}. 737 */ 738 @Deprecated 739 protected int getNativeFrameCount() { 740 return native_get_native_frame_count(); 741 } 742 743 /** 744 * Returns marker position expressed in frames. 745 * @return marker position in wrapping frame units similar to {@link #getPlaybackHeadPosition}, 746 * or zero if marker is disabled. 747 */ 748 public int getNotificationMarkerPosition() { 749 return native_get_marker_pos(); 750 } 751 752 /** 753 * Returns the notification update period expressed in frames. 754 * Zero means that no position update notifications are being delivered. 755 */ 756 public int getPositionNotificationPeriod() { 757 return native_get_pos_update_period(); 758 } 759 760 /** 761 * Returns the playback head position expressed in frames. 762 * Though the "int" type is signed 32-bits, the value should be reinterpreted as if it is 763 * unsigned 32-bits. That is, the next position after 0x7FFFFFFF is (int) 0x80000000. 764 * This is a continuously advancing counter. It will wrap (overflow) periodically, 765 * for example approximately once every 27:03:11 hours:minutes:seconds at 44.1 kHz. 766 * It is reset to zero by flush(), reload(), and stop(). 767 */ 768 public int getPlaybackHeadPosition() { 769 return native_get_position(); 770 } 771 772 /** 773 * Returns this track's estimated latency in milliseconds. This includes the latency due 774 * to AudioTrack buffer size, AudioMixer (if any) and audio hardware driver. 775 * 776 * DO NOT UNHIDE. The existing approach for doing A/V sync has too many problems. We need 777 * a better solution. 778 * @hide 779 */ 780 public int getLatency() { 781 return native_get_latency(); 782 } 783 784 /** 785 * Returns the output sample rate in Hz for the specified stream type. 786 */ 787 static public int getNativeOutputSampleRate(int streamType) { 788 return native_get_output_sample_rate(streamType); 789 } 790 791 /** 792 * Returns the minimum buffer size required for the successful creation of an AudioTrack 793 * object to be created in the {@link #MODE_STREAM} mode. Note that this size doesn't 794 * guarantee a smooth playback under load, and higher values should be chosen according to 795 * the expected frequency at which the buffer will be refilled with additional data to play. 796 * For example, if you intend to dynamically set the source sample rate of an AudioTrack 797 * to a higher value than the initial source sample rate, be sure to configure the buffer size 798 * based on the highest planned sample rate. 799 * @param sampleRateInHz the source sample rate expressed in Hz. 800 * @param channelConfig describes the configuration of the audio channels. 801 * See {@link AudioFormat#CHANNEL_OUT_MONO} and 802 * {@link AudioFormat#CHANNEL_OUT_STEREO} 803 * @param audioFormat the format in which the audio data is represented. 804 * See {@link AudioFormat#ENCODING_PCM_16BIT} and 805 * {@link AudioFormat#ENCODING_PCM_8BIT}, 806 * and {@link AudioFormat#ENCODING_PCM_FLOAT}. 807 * @return {@link #ERROR_BAD_VALUE} if an invalid parameter was passed, 808 * or {@link #ERROR} if unable to query for output properties, 809 * or the minimum buffer size expressed in bytes. 810 */ 811 static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) { 812 int channelCount = 0; 813 switch(channelConfig) { 814 case AudioFormat.CHANNEL_OUT_MONO: 815 case AudioFormat.CHANNEL_CONFIGURATION_MONO: 816 channelCount = 1; 817 break; 818 case AudioFormat.CHANNEL_OUT_STEREO: 819 case AudioFormat.CHANNEL_CONFIGURATION_STEREO: 820 channelCount = 2; 821 break; 822 default: 823 if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) { 824 // input channel configuration features unsupported channels 825 loge("getMinBufferSize(): Invalid channel configuration."); 826 return ERROR_BAD_VALUE; 827 } else { 828 channelCount = Integer.bitCount(channelConfig); 829 } 830 } 831 832 if (!AudioFormat.isValidEncoding(audioFormat)) { 833 loge("getMinBufferSize(): Invalid audio format."); 834 return ERROR_BAD_VALUE; 835 } 836 837 // sample rate, note these values are subject to change 838 if ( (sampleRateInHz < SAMPLE_RATE_HZ_MIN) || (sampleRateInHz > SAMPLE_RATE_HZ_MAX) ) { 839 loge("getMinBufferSize(): " + sampleRateInHz + " Hz is not a supported sample rate."); 840 return ERROR_BAD_VALUE; 841 } 842 843 int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat); 844 if (size <= 0) { 845 loge("getMinBufferSize(): error querying hardware"); 846 return ERROR; 847 } 848 else { 849 return size; 850 } 851 } 852 853 /** 854 * Returns the audio session ID. 855 * 856 * @return the ID of the audio session this AudioTrack belongs to. 857 */ 858 public int getAudioSessionId() { 859 return mSessionId; 860 } 861 862 /** 863 * Poll for a timestamp on demand. 864 * <p> 865 * If you need to track timestamps during initial warmup or after a routing or mode change, 866 * you should request a new timestamp once per second until the reported timestamps 867 * show that the audio clock is stable. 868 * Thereafter, query for a new timestamp approximately once every 10 seconds to once per minute. 869 * Calling this method more often is inefficient. 870 * It is also counter-productive to call this method more often than recommended, 871 * because the short-term differences between successive timestamp reports are not meaningful. 872 * If you need a high-resolution mapping between frame position and presentation time, 873 * consider implementing that at application level, based on low-resolution timestamps. 874 * <p> 875 * The audio data at the returned position may either already have been 876 * presented, or may have not yet been presented but is committed to be presented. 877 * It is not possible to request the time corresponding to a particular position, 878 * or to request the (fractional) position corresponding to a particular time. 879 * If you need such features, consider implementing them at application level. 880 * 881 * @param timestamp a reference to a non-null AudioTimestamp instance allocated 882 * and owned by caller. 883 * @return true if a timestamp is available, or false if no timestamp is available. 884 * If a timestamp if available, 885 * the AudioTimestamp instance is filled in with a position in frame units, together 886 * with the estimated time when that frame was presented or is committed to 887 * be presented. 888 * In the case that no timestamp is available, any supplied instance is left unaltered. 889 * A timestamp may be temporarily unavailable while the audio clock is stabilizing, 890 * or during and immediately after a route change. 891 */ 892 // Add this text when the "on new timestamp" API is added: 893 // Use if you need to get the most recent timestamp outside of the event callback handler. 894 public boolean getTimestamp(AudioTimestamp timestamp) 895 { 896 if (timestamp == null) { 897 throw new IllegalArgumentException(); 898 } 899 // It's unfortunate, but we have to either create garbage every time or use synchronized 900 long[] longArray = new long[2]; 901 int ret = native_get_timestamp(longArray); 902 if (ret != SUCCESS) { 903 return false; 904 } 905 timestamp.framePosition = longArray[0]; 906 timestamp.nanoTime = longArray[1]; 907 return true; 908 } 909 910 911 //-------------------------------------------------------------------------- 912 // Initialization / configuration 913 //-------------------- 914 /** 915 * Sets the listener the AudioTrack notifies when a previously set marker is reached or 916 * for each periodic playback head position update. 917 * Notifications will be received in the same thread as the one in which the AudioTrack 918 * instance was created. 919 * @param listener 920 */ 921 public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener) { 922 setPlaybackPositionUpdateListener(listener, null); 923 } 924 925 /** 926 * Sets the listener the AudioTrack notifies when a previously set marker is reached or 927 * for each periodic playback head position update. 928 * Use this method to receive AudioTrack events in the Handler associated with another 929 * thread than the one in which you created the AudioTrack instance. 930 * @param listener 931 * @param handler the Handler that will receive the event notification messages. 932 */ 933 public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener, 934 Handler handler) { 935 if (listener != null) { 936 mEventHandlerDelegate = new NativeEventHandlerDelegate(this, listener, handler); 937 } else { 938 mEventHandlerDelegate = null; 939 } 940 } 941 942 943 private static float clampGainOrLevel(float gainOrLevel) { 944 if (Float.isNaN(gainOrLevel)) { 945 throw new IllegalArgumentException(); 946 } 947 if (gainOrLevel < GAIN_MIN) { 948 gainOrLevel = GAIN_MIN; 949 } else if (gainOrLevel > GAIN_MAX) { 950 gainOrLevel = GAIN_MAX; 951 } 952 return gainOrLevel; 953 } 954 955 956 /** 957 * Sets the specified left and right output gain values on the AudioTrack. 958 * <p>Gain values are clamped to the closed interval [0.0, max] where 959 * max is the value of {@link #getMaxVolume}. 960 * A value of 0.0 results in zero gain (silence), and 961 * a value of 1.0 means unity gain (signal unchanged). 962 * The default value is 1.0 meaning unity gain. 963 * <p>The word "volume" in the API name is historical; this is actually a linear gain. 964 * @param leftGain output gain for the left channel. 965 * @param rightGain output gain for the right channel 966 * @return error code or success, see {@link #SUCCESS}, 967 * {@link #ERROR_INVALID_OPERATION} 968 * @deprecated Applications should use {@link #setVolume} instead, as it 969 * more gracefully scales down to mono, and up to multi-channel content beyond stereo. 970 */ 971 public int setStereoVolume(float leftGain, float rightGain) { 972 if (isRestricted()) { 973 return SUCCESS; 974 } 975 if (mState == STATE_UNINITIALIZED) { 976 return ERROR_INVALID_OPERATION; 977 } 978 979 leftGain = clampGainOrLevel(leftGain); 980 rightGain = clampGainOrLevel(rightGain); 981 982 native_setVolume(leftGain, rightGain); 983 984 return SUCCESS; 985 } 986 987 988 /** 989 * Sets the specified output gain value on all channels of this track. 990 * <p>Gain values are clamped to the closed interval [0.0, max] where 991 * max is the value of {@link #getMaxVolume}. 992 * A value of 0.0 results in zero gain (silence), and 993 * a value of 1.0 means unity gain (signal unchanged). 994 * The default value is 1.0 meaning unity gain. 995 * <p>This API is preferred over {@link #setStereoVolume}, as it 996 * more gracefully scales down to mono, and up to multi-channel content beyond stereo. 997 * <p>The word "volume" in the API name is historical; this is actually a linear gain. 998 * @param gain output gain for all channels. 999 * @return error code or success, see {@link #SUCCESS}, 1000 * {@link #ERROR_INVALID_OPERATION} 1001 */ 1002 public int setVolume(float gain) { 1003 return setStereoVolume(gain, gain); 1004 } 1005 1006 1007 /** 1008 * Sets the playback sample rate for this track. This sets the sampling rate at which 1009 * the audio data will be consumed and played back 1010 * (as set by the sampleRateInHz parameter in the 1011 * {@link #AudioTrack(int, int, int, int, int, int)} constructor), 1012 * not the original sampling rate of the 1013 * content. For example, setting it to half the sample rate of the content will cause the 1014 * playback to last twice as long, but will also result in a pitch shift down by one octave. 1015 * The valid sample rate range is from 1 Hz to twice the value returned by 1016 * {@link #getNativeOutputSampleRate(int)}. 1017 * @param sampleRateInHz the sample rate expressed in Hz 1018 * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, 1019 * {@link #ERROR_INVALID_OPERATION} 1020 */ 1021 public int setPlaybackRate(int sampleRateInHz) { 1022 if (mState != STATE_INITIALIZED) { 1023 return ERROR_INVALID_OPERATION; 1024 } 1025 if (sampleRateInHz <= 0) { 1026 return ERROR_BAD_VALUE; 1027 } 1028 return native_set_playback_rate(sampleRateInHz); 1029 } 1030 1031 1032 /** 1033 * Sets the position of the notification marker. At most one marker can be active. 1034 * @param markerInFrames marker position in wrapping frame units similar to 1035 * {@link #getPlaybackHeadPosition}, or zero to disable the marker. 1036 * To set a marker at a position which would appear as zero due to wraparound, 1037 * a workaround is to use a non-zero position near zero, such as -1 or 1. 1038 * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, 1039 * {@link #ERROR_INVALID_OPERATION} 1040 */ 1041 public int setNotificationMarkerPosition(int markerInFrames) { 1042 if (mState == STATE_UNINITIALIZED) { 1043 return ERROR_INVALID_OPERATION; 1044 } 1045 return native_set_marker_pos(markerInFrames); 1046 } 1047 1048 1049 /** 1050 * Sets the period for the periodic notification event. 1051 * @param periodInFrames update period expressed in frames 1052 * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION} 1053 */ 1054 public int setPositionNotificationPeriod(int periodInFrames) { 1055 if (mState == STATE_UNINITIALIZED) { 1056 return ERROR_INVALID_OPERATION; 1057 } 1058 return native_set_pos_update_period(periodInFrames); 1059 } 1060 1061 1062 /** 1063 * Sets the playback head position. 1064 * The track must be stopped or paused for the position to be changed, 1065 * and must use the {@link #MODE_STATIC} mode. 1066 * @param positionInFrames playback head position expressed in frames 1067 * Zero corresponds to start of buffer. 1068 * The position must not be greater than the buffer size in frames, or negative. 1069 * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, 1070 * {@link #ERROR_INVALID_OPERATION} 1071 */ 1072 public int setPlaybackHeadPosition(int positionInFrames) { 1073 if (mDataLoadMode == MODE_STREAM || mState == STATE_UNINITIALIZED || 1074 getPlayState() == PLAYSTATE_PLAYING) { 1075 return ERROR_INVALID_OPERATION; 1076 } 1077 if (!(0 <= positionInFrames && positionInFrames <= mNativeBufferSizeInFrames)) { 1078 return ERROR_BAD_VALUE; 1079 } 1080 return native_set_position(positionInFrames); 1081 } 1082 1083 /** 1084 * Sets the loop points and the loop count. The loop can be infinite. 1085 * Similarly to setPlaybackHeadPosition, 1086 * the track must be stopped or paused for the loop points to be changed, 1087 * and must use the {@link #MODE_STATIC} mode. 1088 * @param startInFrames loop start marker expressed in frames 1089 * Zero corresponds to start of buffer. 1090 * The start marker must not be greater than or equal to the buffer size in frames, or negative. 1091 * @param endInFrames loop end marker expressed in frames 1092 * The total buffer size in frames corresponds to end of buffer. 1093 * The end marker must not be greater than the buffer size in frames. 1094 * For looping, the end marker must not be less than or equal to the start marker, 1095 * but to disable looping 1096 * it is permitted for start marker, end marker, and loop count to all be 0. 1097 * @param loopCount the number of times the loop is looped. 1098 * A value of -1 means infinite looping, and 0 disables looping. 1099 * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, 1100 * {@link #ERROR_INVALID_OPERATION} 1101 */ 1102 public int setLoopPoints(int startInFrames, int endInFrames, int loopCount) { 1103 if (mDataLoadMode == MODE_STREAM || mState == STATE_UNINITIALIZED || 1104 getPlayState() == PLAYSTATE_PLAYING) { 1105 return ERROR_INVALID_OPERATION; 1106 } 1107 if (loopCount == 0) { 1108 ; // explicitly allowed as an exception to the loop region range check 1109 } else if (!(0 <= startInFrames && startInFrames < mNativeBufferSizeInFrames && 1110 startInFrames < endInFrames && endInFrames <= mNativeBufferSizeInFrames)) { 1111 return ERROR_BAD_VALUE; 1112 } 1113 return native_set_loop(startInFrames, endInFrames, loopCount); 1114 } 1115 1116 /** 1117 * Sets the initialization state of the instance. This method was originally intended to be used 1118 * in an AudioTrack subclass constructor to set a subclass-specific post-initialization state. 1119 * However, subclasses of AudioTrack are no longer recommended, so this method is obsolete. 1120 * @param state the state of the AudioTrack instance 1121 * @deprecated Only accessible by subclasses, which are not recommended for AudioTrack. 1122 */ 1123 @Deprecated 1124 protected void setState(int state) { 1125 mState = state; 1126 } 1127 1128 1129 //--------------------------------------------------------- 1130 // Transport control methods 1131 //-------------------- 1132 /** 1133 * Starts playing an AudioTrack. 1134 * If track's creation mode is {@link #MODE_STATIC}, you must have called write() prior. 1135 * 1136 * @throws IllegalStateException 1137 */ 1138 public void play() 1139 throws IllegalStateException { 1140 if (mState != STATE_INITIALIZED) { 1141 throw new IllegalStateException("play() called on uninitialized AudioTrack."); 1142 } 1143 if (isRestricted()) { 1144 setVolume(0); 1145 } 1146 synchronized(mPlayStateLock) { 1147 native_start(); 1148 mPlayState = PLAYSTATE_PLAYING; 1149 } 1150 } 1151 1152 private boolean isRestricted() { 1153 try { 1154 final int usage = AudioAttributes.usageForLegacyStreamType(mStreamType); 1155 final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, usage, 1156 Process.myUid(), ActivityThread.currentPackageName()); 1157 return mode != AppOpsManager.MODE_ALLOWED; 1158 } catch (RemoteException e) { 1159 return false; 1160 } 1161 } 1162 1163 /** 1164 * Stops playing the audio data. 1165 * When used on an instance created in {@link #MODE_STREAM} mode, audio will stop playing 1166 * after the last buffer that was written has been played. For an immediate stop, use 1167 * {@link #pause()}, followed by {@link #flush()} to discard audio data that hasn't been played 1168 * back yet. 1169 * @throws IllegalStateException 1170 */ 1171 public void stop() 1172 throws IllegalStateException { 1173 if (mState != STATE_INITIALIZED) { 1174 throw new IllegalStateException("stop() called on uninitialized AudioTrack."); 1175 } 1176 1177 // stop playing 1178 synchronized(mPlayStateLock) { 1179 native_stop(); 1180 mPlayState = PLAYSTATE_STOPPED; 1181 } 1182 } 1183 1184 /** 1185 * Pauses the playback of the audio data. Data that has not been played 1186 * back will not be discarded. Subsequent calls to {@link #play} will play 1187 * this data back. See {@link #flush()} to discard this data. 1188 * 1189 * @throws IllegalStateException 1190 */ 1191 public void pause() 1192 throws IllegalStateException { 1193 if (mState != STATE_INITIALIZED) { 1194 throw new IllegalStateException("pause() called on uninitialized AudioTrack."); 1195 } 1196 //logd("pause()"); 1197 1198 // pause playback 1199 synchronized(mPlayStateLock) { 1200 native_pause(); 1201 mPlayState = PLAYSTATE_PAUSED; 1202 } 1203 } 1204 1205 1206 //--------------------------------------------------------- 1207 // Audio data supply 1208 //-------------------- 1209 1210 /** 1211 * Flushes the audio data currently queued for playback. Any data that has 1212 * not been played back will be discarded. No-op if not stopped or paused, 1213 * or if the track's creation mode is not {@link #MODE_STREAM}. 1214 */ 1215 public void flush() { 1216 if (mState == STATE_INITIALIZED) { 1217 // flush the data in native layer 1218 native_flush(); 1219 } 1220 1221 } 1222 1223 /** 1224 * Writes the audio data to the audio sink for playback (streaming mode), 1225 * or copies audio data for later playback (static buffer mode). 1226 * In streaming mode, will block until all data has been written to the audio sink. 1227 * In static buffer mode, copies the data to the buffer starting at offset 0. 1228 * Note that the actual playback of this data might occur after this function 1229 * returns. This function is thread safe with respect to {@link #stop} calls, 1230 * in which case all of the specified data might not be written to the audio sink. 1231 * 1232 * @param audioData the array that holds the data to play. 1233 * @param offsetInBytes the offset expressed in bytes in audioData where the data to play 1234 * starts. 1235 * @param sizeInBytes the number of bytes to read in audioData after the offset. 1236 * @return the number of bytes that were written or {@link #ERROR_INVALID_OPERATION} 1237 * if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if 1238 * the parameters don't resolve to valid data and indexes, or 1239 * {@link AudioManager#ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and 1240 * needs to be recreated. 1241 */ 1242 1243 public int write(byte[] audioData, int offsetInBytes, int sizeInBytes) { 1244 1245 if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) { 1246 return ERROR_INVALID_OPERATION; 1247 } 1248 1249 if ( (audioData == null) || (offsetInBytes < 0 ) || (sizeInBytes < 0) 1250 || (offsetInBytes + sizeInBytes < 0) // detect integer overflow 1251 || (offsetInBytes + sizeInBytes > audioData.length)) { 1252 return ERROR_BAD_VALUE; 1253 } 1254 1255 int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat, 1256 true /*isBlocking*/); 1257 1258 if ((mDataLoadMode == MODE_STATIC) 1259 && (mState == STATE_NO_STATIC_DATA) 1260 && (ret > 0)) { 1261 // benign race with respect to other APIs that read mState 1262 mState = STATE_INITIALIZED; 1263 } 1264 1265 return ret; 1266 } 1267 1268 1269 /** 1270 * Writes the audio data to the audio sink for playback (streaming mode), 1271 * or copies audio data for later playback (static buffer mode). 1272 * In streaming mode, will block until all data has been written to the audio sink. 1273 * In static buffer mode, copies the data to the buffer starting at offset 0. 1274 * Note that the actual playback of this data might occur after this function 1275 * returns. This function is thread safe with respect to {@link #stop} calls, 1276 * in which case all of the specified data might not be written to the audio sink. 1277 * 1278 * @param audioData the array that holds the data to play. 1279 * @param offsetInShorts the offset expressed in shorts in audioData where the data to play 1280 * starts. 1281 * @param sizeInShorts the number of shorts to read in audioData after the offset. 1282 * @return the number of shorts that were written or {@link #ERROR_INVALID_OPERATION} 1283 * if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if 1284 * the parameters don't resolve to valid data and indexes. 1285 */ 1286 1287 public int write(short[] audioData, int offsetInShorts, int sizeInShorts) { 1288 1289 if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) { 1290 return ERROR_INVALID_OPERATION; 1291 } 1292 1293 if ( (audioData == null) || (offsetInShorts < 0 ) || (sizeInShorts < 0) 1294 || (offsetInShorts + sizeInShorts < 0) // detect integer overflow 1295 || (offsetInShorts + sizeInShorts > audioData.length)) { 1296 return ERROR_BAD_VALUE; 1297 } 1298 1299 int ret = native_write_short(audioData, offsetInShorts, sizeInShorts, mAudioFormat); 1300 1301 if ((mDataLoadMode == MODE_STATIC) 1302 && (mState == STATE_NO_STATIC_DATA) 1303 && (ret > 0)) { 1304 // benign race with respect to other APIs that read mState 1305 mState = STATE_INITIALIZED; 1306 } 1307 1308 return ret; 1309 } 1310 1311 1312 /** 1313 * Writes the audio data to the audio sink for playback (streaming mode), 1314 * or copies audio data for later playback (static buffer mode). 1315 * In static buffer mode, copies the data to the buffer starting at offset 0, 1316 * and the write mode is ignored. 1317 * In streaming mode, the blocking behavior will depend on the write mode. 1318 * <p> 1319 * Note that the actual playback of this data might occur after this function 1320 * returns. This function is thread safe with respect to {@link #stop} calls, 1321 * in which case all of the specified data might not be written to the audio sink. 1322 * <p> 1323 * @param audioData the array that holds the data to play. 1324 * The implementation does not clip for sample values within the nominal range 1325 * [-1.0f, 1.0f], provided that all gains in the audio pipeline are 1326 * less than or equal to unity (1.0f), and in the absence of post-processing effects 1327 * that could add energy, such as reverb. For the convenience of applications 1328 * that compute samples using filters with non-unity gain, 1329 * sample values +3 dB beyond the nominal range are permitted. 1330 * However such values may eventually be limited or clipped, depending on various gains 1331 * and later processing in the audio path. Therefore applications are encouraged 1332 * to provide samples values within the nominal range. 1333 * @param offsetInFloats the offset, expressed as a number of floats, 1334 * in audioData where the data to play starts. 1335 * @param sizeInFloats the number of floats to read in audioData after the offset. 1336 * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no 1337 * effect in static mode. 1338 * <BR>With {@link #WRITE_BLOCKING}, the write will block until all data has been written 1339 * to the audio sink. 1340 * <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after 1341 * queuing as much audio data for playback as possible without blocking. 1342 * @return the number of floats that were written, or {@link #ERROR_INVALID_OPERATION} 1343 * if the object wasn't properly initialized, or {@link #ERROR_BAD_VALUE} if 1344 * the parameters don't resolve to valid data and indexes. 1345 */ 1346 public int write(float[] audioData, int offsetInFloats, int sizeInFloats, 1347 @WriteMode int writeMode) { 1348 1349 if (mState == STATE_UNINITIALIZED) { 1350 Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED"); 1351 return ERROR_INVALID_OPERATION; 1352 } 1353 1354 if (mAudioFormat != AudioFormat.ENCODING_PCM_FLOAT) { 1355 Log.e(TAG, "AudioTrack.write(float[] ...) requires format ENCODING_PCM_FLOAT"); 1356 return ERROR_INVALID_OPERATION; 1357 } 1358 1359 if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) { 1360 Log.e(TAG, "AudioTrack.write() called with invalid blocking mode"); 1361 return ERROR_BAD_VALUE; 1362 } 1363 1364 if ( (audioData == null) || (offsetInFloats < 0 ) || (sizeInFloats < 0) 1365 || (offsetInFloats + sizeInFloats < 0) // detect integer overflow 1366 || (offsetInFloats + sizeInFloats > audioData.length)) { 1367 Log.e(TAG, "AudioTrack.write() called with invalid array, offset, or size"); 1368 return ERROR_BAD_VALUE; 1369 } 1370 1371 int ret = native_write_float(audioData, offsetInFloats, sizeInFloats, mAudioFormat, 1372 writeMode == WRITE_BLOCKING); 1373 1374 if ((mDataLoadMode == MODE_STATIC) 1375 && (mState == STATE_NO_STATIC_DATA) 1376 && (ret > 0)) { 1377 // benign race with respect to other APIs that read mState 1378 mState = STATE_INITIALIZED; 1379 } 1380 1381 return ret; 1382 } 1383 1384 1385 /** 1386 * Writes the audio data to the audio sink for playback (streaming mode), 1387 * or copies audio data for later playback (static buffer mode). 1388 * In static buffer mode, copies the data to the buffer starting at its 0 offset, and the write 1389 * mode is ignored. 1390 * In streaming mode, the blocking behavior will depend on the write mode. 1391 * @param audioData the buffer that holds the data to play, starting at the position reported 1392 * by <code>audioData.position()</code>. 1393 * <BR>Note that upon return, the buffer position (<code>audioData.position()</code>) will 1394 * have been advanced to reflect the amount of data that was successfully written to 1395 * the AudioTrack. 1396 * @param sizeInBytes number of bytes to write. 1397 * <BR>Note this may differ from <code>audioData.remaining()</code>, but cannot exceed it. 1398 * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no 1399 * effect in static mode. 1400 * <BR>With {@link #WRITE_BLOCKING}, the write will block until all data has been written 1401 * to the audio sink. 1402 * <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after 1403 * queuing as much audio data for playback as possible without blocking. 1404 * @return 0 or a positive number of bytes that were written, or 1405 * {@link #ERROR_BAD_VALUE}, {@link #ERROR_INVALID_OPERATION} 1406 */ 1407 public int write(ByteBuffer audioData, int sizeInBytes, 1408 @WriteMode int writeMode) { 1409 1410 if (mState == STATE_UNINITIALIZED) { 1411 Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED"); 1412 return ERROR_INVALID_OPERATION; 1413 } 1414 1415 if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) { 1416 Log.e(TAG, "AudioTrack.write() called with invalid blocking mode"); 1417 return ERROR_BAD_VALUE; 1418 } 1419 1420 if ( (audioData == null) || (sizeInBytes < 0) || (sizeInBytes > audioData.remaining())) { 1421 Log.e(TAG, "AudioTrack.write() called with invalid size (" + sizeInBytes + ") value"); 1422 return ERROR_BAD_VALUE; 1423 } 1424 1425 int ret = 0; 1426 if (audioData.isDirect()) { 1427 ret = native_write_native_bytes(audioData, 1428 audioData.position(), sizeInBytes, mAudioFormat, 1429 writeMode == WRITE_BLOCKING); 1430 } else { 1431 ret = native_write_byte(NioUtils.unsafeArray(audioData), 1432 NioUtils.unsafeArrayOffset(audioData) + audioData.position(), 1433 sizeInBytes, mAudioFormat, 1434 writeMode == WRITE_BLOCKING); 1435 } 1436 1437 if ((mDataLoadMode == MODE_STATIC) 1438 && (mState == STATE_NO_STATIC_DATA) 1439 && (ret > 0)) { 1440 // benign race with respect to other APIs that read mState 1441 mState = STATE_INITIALIZED; 1442 } 1443 1444 if (ret > 0) { 1445 audioData.position(audioData.position() + ret); 1446 } 1447 1448 return ret; 1449 } 1450 1451 /** 1452 * Notifies the native resource to reuse the audio data already loaded in the native 1453 * layer, that is to rewind to start of buffer. 1454 * The track's creation mode must be {@link #MODE_STATIC}. 1455 * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}, 1456 * {@link #ERROR_INVALID_OPERATION} 1457 */ 1458 public int reloadStaticData() { 1459 if (mDataLoadMode == MODE_STREAM || mState != STATE_INITIALIZED) { 1460 return ERROR_INVALID_OPERATION; 1461 } 1462 return native_reload_static(); 1463 } 1464 1465 //-------------------------------------------------------------------------- 1466 // Audio effects management 1467 //-------------------- 1468 1469 /** 1470 * Attaches an auxiliary effect to the audio track. A typical auxiliary 1471 * effect is a reverberation effect which can be applied on any sound source 1472 * that directs a certain amount of its energy to this effect. This amount 1473 * is defined by setAuxEffectSendLevel(). 1474 * {@see #setAuxEffectSendLevel(float)}. 1475 * <p>After creating an auxiliary effect (e.g. 1476 * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with 1477 * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling 1478 * this method to attach the audio track to the effect. 1479 * <p>To detach the effect from the audio track, call this method with a 1480 * null effect id. 1481 * 1482 * @param effectId system wide unique id of the effect to attach 1483 * @return error code or success, see {@link #SUCCESS}, 1484 * {@link #ERROR_INVALID_OPERATION}, {@link #ERROR_BAD_VALUE} 1485 */ 1486 public int attachAuxEffect(int effectId) { 1487 if (mState == STATE_UNINITIALIZED) { 1488 return ERROR_INVALID_OPERATION; 1489 } 1490 return native_attachAuxEffect(effectId); 1491 } 1492 1493 /** 1494 * Sets the send level of the audio track to the attached auxiliary effect 1495 * {@link #attachAuxEffect(int)}. Effect levels 1496 * are clamped to the closed interval [0.0, max] where 1497 * max is the value of {@link #getMaxVolume}. 1498 * A value of 0.0 results in no effect, and a value of 1.0 is full send. 1499 * <p>By default the send level is 0.0f, so even if an effect is attached to the player 1500 * this method must be called for the effect to be applied. 1501 * <p>Note that the passed level value is a linear scalar. UI controls should be scaled 1502 * logarithmically: the gain applied by audio framework ranges from -72dB to at least 0dB, 1503 * so an appropriate conversion from linear UI input x to level is: 1504 * x == 0 -> level = 0 1505 * 0 < x <= R -> level = 10^(72*(x-R)/20/R) 1506 * 1507 * @param level linear send level 1508 * @return error code or success, see {@link #SUCCESS}, 1509 * {@link #ERROR_INVALID_OPERATION}, {@link #ERROR} 1510 */ 1511 public int setAuxEffectSendLevel(float level) { 1512 if (isRestricted()) { 1513 return SUCCESS; 1514 } 1515 if (mState == STATE_UNINITIALIZED) { 1516 return ERROR_INVALID_OPERATION; 1517 } 1518 level = clampGainOrLevel(level); 1519 int err = native_setAuxEffectSendLevel(level); 1520 return err == 0 ? SUCCESS : ERROR; 1521 } 1522 1523 //--------------------------------------------------------- 1524 // Interface definitions 1525 //-------------------- 1526 /** 1527 * Interface definition for a callback to be invoked when the playback head position of 1528 * an AudioTrack has reached a notification marker or has increased by a certain period. 1529 */ 1530 public interface OnPlaybackPositionUpdateListener { 1531 /** 1532 * Called on the listener to notify it that the previously set marker has been reached 1533 * by the playback head. 1534 */ 1535 void onMarkerReached(AudioTrack track); 1536 1537 /** 1538 * Called on the listener to periodically notify it that the playback head has reached 1539 * a multiple of the notification period. 1540 */ 1541 void onPeriodicNotification(AudioTrack track); 1542 } 1543 1544 //--------------------------------------------------------- 1545 // Inner classes 1546 //-------------------- 1547 /** 1548 * Helper class to handle the forwarding of native events to the appropriate listener 1549 * (potentially) handled in a different thread 1550 */ 1551 private class NativeEventHandlerDelegate { 1552 private final Handler mHandler; 1553 1554 NativeEventHandlerDelegate(final AudioTrack track, 1555 final OnPlaybackPositionUpdateListener listener, 1556 Handler handler) { 1557 // find the looper for our new event handler 1558 Looper looper; 1559 if (handler != null) { 1560 looper = handler.getLooper(); 1561 } else { 1562 // no given handler, use the looper the AudioTrack was created in 1563 looper = mInitializationLooper; 1564 } 1565 1566 // construct the event handler with this looper 1567 if (looper != null) { 1568 // implement the event handler delegate 1569 mHandler = new Handler(looper) { 1570 @Override 1571 public void handleMessage(Message msg) { 1572 if (track == null) { 1573 return; 1574 } 1575 switch(msg.what) { 1576 case NATIVE_EVENT_MARKER: 1577 if (listener != null) { 1578 listener.onMarkerReached(track); 1579 } 1580 break; 1581 case NATIVE_EVENT_NEW_POS: 1582 if (listener != null) { 1583 listener.onPeriodicNotification(track); 1584 } 1585 break; 1586 default: 1587 loge("Unknown native event type: " + msg.what); 1588 break; 1589 } 1590 } 1591 }; 1592 } else { 1593 mHandler = null; 1594 } 1595 } 1596 1597 Handler getHandler() { 1598 return mHandler; 1599 } 1600 } 1601 1602 1603 //--------------------------------------------------------- 1604 // Java methods called from the native side 1605 //-------------------- 1606 @SuppressWarnings("unused") 1607 private static void postEventFromNative(Object audiotrack_ref, 1608 int what, int arg1, int arg2, Object obj) { 1609 //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2); 1610 AudioTrack track = (AudioTrack)((WeakReference)audiotrack_ref).get(); 1611 if (track == null) { 1612 return; 1613 } 1614 1615 NativeEventHandlerDelegate delegate = track.mEventHandlerDelegate; 1616 if (delegate != null) { 1617 Handler handler = delegate.getHandler(); 1618 if (handler != null) { 1619 Message m = handler.obtainMessage(what, arg1, arg2, obj); 1620 handler.sendMessage(m); 1621 } 1622 } 1623 1624 } 1625 1626 1627 //--------------------------------------------------------- 1628 // Native methods called from the Java side 1629 //-------------------- 1630 1631 // post-condition: mStreamType is overwritten with a value 1632 // that reflects the audio attributes (e.g. an AudioAttributes object with a usage of 1633 // AudioAttributes.USAGE_MEDIA will map to AudioManager.STREAM_MUSIC 1634 private native final int native_setup(Object /*WeakReference<AudioTrack>*/ audiotrack_this, 1635 Object /*AudioAttributes*/ attributes, 1636 int sampleRate, int channelMask, int audioFormat, 1637 int buffSizeInBytes, int mode, int[] sessionId); 1638 1639 private native final void native_finalize(); 1640 1641 private native final void native_release(); 1642 1643 private native final void native_start(); 1644 1645 private native final void native_stop(); 1646 1647 private native final void native_pause(); 1648 1649 private native final void native_flush(); 1650 1651 private native final int native_write_byte(byte[] audioData, 1652 int offsetInBytes, int sizeInBytes, int format, 1653 boolean isBlocking); 1654 1655 private native final int native_write_short(short[] audioData, 1656 int offsetInShorts, int sizeInShorts, int format); 1657 1658 private native final int native_write_float(float[] audioData, 1659 int offsetInFloats, int sizeInFloats, int format, 1660 boolean isBlocking); 1661 1662 private native final int native_write_native_bytes(Object audioData, 1663 int positionInBytes, int sizeInBytes, int format, boolean blocking); 1664 1665 private native final int native_reload_static(); 1666 1667 private native final int native_get_native_frame_count(); 1668 1669 private native final void native_setVolume(float leftVolume, float rightVolume); 1670 1671 private native final int native_set_playback_rate(int sampleRateInHz); 1672 private native final int native_get_playback_rate(); 1673 1674 private native final int native_set_marker_pos(int marker); 1675 private native final int native_get_marker_pos(); 1676 1677 private native final int native_set_pos_update_period(int updatePeriod); 1678 private native final int native_get_pos_update_period(); 1679 1680 private native final int native_set_position(int position); 1681 private native final int native_get_position(); 1682 1683 private native final int native_get_latency(); 1684 1685 // longArray must be a non-null array of length >= 2 1686 // [0] is assigned the frame position 1687 // [1] is assigned the time in CLOCK_MONOTONIC nanoseconds 1688 private native final int native_get_timestamp(long[] longArray); 1689 1690 private native final int native_set_loop(int start, int end, int loopCount); 1691 1692 static private native final int native_get_output_sample_rate(int streamType); 1693 static private native final int native_get_min_buff_size( 1694 int sampleRateInHz, int channelConfig, int audioFormat); 1695 1696 private native final int native_attachAuxEffect(int effectId); 1697 private native final int native_setAuxEffectSendLevel(float level); 1698 1699 //--------------------------------------------------------- 1700 // Utility methods 1701 //------------------ 1702 1703 private static void logd(String msg) { 1704 Log.d(TAG, msg); 1705 } 1706 1707 private static void loge(String msg) { 1708 Log.e(TAG, msg); 1709 } 1710 1711} 1712