1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.media; 18 19 import android.annotation.IntDef; 20 21 import java.lang.annotation.Retention; 22 import java.lang.annotation.RetentionPolicy; 23 24 /** 25 * The AudioFormat class is used to access a number of audio format and 26 * channel configuration constants. They are for instance used 27 * in {@link AudioTrack} and {@link AudioRecord}. 28 * 29 */ 30 public class AudioFormat { 31 32 //--------------------------------------------------------- 33 // Constants 34 //-------------------- 35 /** Invalid audio data format */ 36 public static final int ENCODING_INVALID = 0; 37 /** Default audio data format */ 38 public static final int ENCODING_DEFAULT = 1; 39 40 // These values must be kept in sync with core/jni/android_media_AudioFormat.h 41 /** Audio data format: PCM 16 bit per sample. Guaranteed to be supported by devices. */ 42 public static final int ENCODING_PCM_16BIT = 2; 43 /** Audio data format: PCM 8 bit per sample. Not guaranteed to be supported by devices. */ 44 public static final int ENCODING_PCM_8BIT = 3; 45 /** Audio data format: single-precision floating-point per sample */ 46 public static final int ENCODING_PCM_FLOAT = 4; 47 /** Audio data format: AC-3 compressed */ 48 public static final int ENCODING_AC3 = 5; 49 /** Audio data format: E-AC-3 compressed */ 50 public static final int ENCODING_E_AC3 = 6; 51 52 /** Invalid audio channel configuration */ 53 /** @deprecated use CHANNEL_INVALID instead */ 54 @Deprecated public static final int CHANNEL_CONFIGURATION_INVALID = 0; 55 /** Default audio channel configuration */ 56 /** @deprecated use CHANNEL_OUT_DEFAULT or CHANNEL_IN_DEFAULT instead */ 57 @Deprecated public static final int CHANNEL_CONFIGURATION_DEFAULT = 1; 58 /** Mono audio configuration */ 59 /** @deprecated use CHANNEL_OUT_MONO or CHANNEL_IN_MONO instead */ 60 @Deprecated public static final int CHANNEL_CONFIGURATION_MONO = 2; 61 /** Stereo (2 channel) audio configuration */ 62 /** @deprecated use CHANNEL_OUT_STEREO or CHANNEL_IN_STEREO instead */ 63 @Deprecated public static final int CHANNEL_CONFIGURATION_STEREO = 3; 64 65 /** Invalid audio channel mask */ 66 public static final int CHANNEL_INVALID = 0; 67 /** Default audio channel mask */ 68 public static final int CHANNEL_OUT_DEFAULT = 1; 69 70 // Output channel mask definitions below are translated to the native values defined in 71 // in /system/core/include/system/audio.h in the JNI code of AudioTrack 72 public static final int CHANNEL_OUT_FRONT_LEFT = 0x4; 73 public static final int CHANNEL_OUT_FRONT_RIGHT = 0x8; 74 public static final int CHANNEL_OUT_FRONT_CENTER = 0x10; 75 public static final int CHANNEL_OUT_LOW_FREQUENCY = 0x20; 76 public static final int CHANNEL_OUT_BACK_LEFT = 0x40; 77 public static final int CHANNEL_OUT_BACK_RIGHT = 0x80; 78 public static final int CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x100; 79 public static final int CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x200; 80 public static final int CHANNEL_OUT_BACK_CENTER = 0x400; 81 public static final int CHANNEL_OUT_SIDE_LEFT = 0x800; 82 public static final int CHANNEL_OUT_SIDE_RIGHT = 0x1000; 83 /** @hide */ 84 public static final int CHANNEL_OUT_TOP_CENTER = 0x2000; 85 /** @hide */ 86 public static final int CHANNEL_OUT_TOP_FRONT_LEFT = 0x4000; 87 /** @hide */ 88 public static final int CHANNEL_OUT_TOP_FRONT_CENTER = 0x8000; 89 /** @hide */ 90 public static final int CHANNEL_OUT_TOP_FRONT_RIGHT = 0x10000; 91 /** @hide */ 92 public static final int CHANNEL_OUT_TOP_BACK_LEFT = 0x20000; 93 /** @hide */ 94 public static final int CHANNEL_OUT_TOP_BACK_CENTER = 0x40000; 95 /** @hide */ 96 public static final int CHANNEL_OUT_TOP_BACK_RIGHT = 0x80000; 97 98 public static final int CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT; 99 public static final int CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT); 100 // aka QUAD_BACK 101 public static final int CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | 102 CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT); 103 /** @hide */ 104 public static final int CHANNEL_OUT_QUAD_SIDE = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | 105 CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT); 106 public static final int CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | 107 CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER); 108 // aka 5POINT1_BACK 109 public static final int CHANNEL_OUT_5POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | 110 CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT); 111 /** @hide */ 112 public static final int CHANNEL_OUT_5POINT1_SIDE = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | 113 CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | 114 CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT); 115 // TODO does this need an @deprecated ? 116 // different from AUDIO_CHANNEL_OUT_7POINT1 117 public static final int CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT | 118 CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT | 119 CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER); 120 /** @hide */ 121 // matches AUDIO_CHANNEL_OUT_7POINT1 122 public static final int CHANNEL_OUT_7POINT1_SURROUND = ( 123 CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_FRONT_RIGHT | 124 CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT | 125 CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT | 126 CHANNEL_OUT_LOW_FREQUENCY); 127 // CHANNEL_OUT_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_OUT_ALL 128 129 /** 130 * @hide 131 * Return the input channel mask corresponding to an output channel mask. 132 * This can be used for submix rerouting for the mask of the recorder to map to that of the mix. 133 * @param outMask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT 134 * @return a combination of CHANNEL_IN_* definitions matching an output channel mask 135 * @throws IllegalArgumentException 136 */ inChannelMaskFromOutChannelMask(int outMask)137 public static int inChannelMaskFromOutChannelMask(int outMask) throws IllegalArgumentException { 138 if (outMask == CHANNEL_OUT_DEFAULT) { 139 throw new IllegalArgumentException( 140 "Illegal CHANNEL_OUT_DEFAULT channel mask for input."); 141 } 142 switch (channelCountFromOutChannelMask(outMask)) { 143 case 1: 144 return CHANNEL_IN_MONO; 145 case 2: 146 return CHANNEL_IN_STEREO; 147 default: 148 throw new IllegalArgumentException("Unsupported channel configuration for input."); 149 } 150 } 151 152 /** 153 * @hide 154 * Return the number of channels from an input channel mask 155 * @param mask a combination of the CHANNEL_IN_* definitions, even CHANNEL_IN_DEFAULT 156 * @return number of channels for the mask 157 */ channelCountFromInChannelMask(int mask)158 public static int channelCountFromInChannelMask(int mask) { 159 return Integer.bitCount(mask); 160 } 161 /** 162 * @hide 163 * Return the number of channels from an output channel mask 164 * @param mask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT 165 * @return number of channels for the mask 166 */ channelCountFromOutChannelMask(int mask)167 public static int channelCountFromOutChannelMask(int mask) { 168 return Integer.bitCount(mask); 169 } 170 /** 171 * @hide 172 * Return a channel mask ready to be used by native code 173 * @param mask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT 174 * @return a native channel mask 175 */ convertChannelOutMaskToNativeMask(int javaMask)176 public static int convertChannelOutMaskToNativeMask(int javaMask) { 177 return (javaMask >> 2); 178 } 179 180 /** 181 * @hide 182 * Return a java output channel mask 183 * @param mask a native channel mask 184 * @return a combination of the CHANNEL_OUT_* definitions 185 */ convertNativeChannelMaskToOutMask(int nativeMask)186 public static int convertNativeChannelMaskToOutMask(int nativeMask) { 187 return (nativeMask << 2); 188 } 189 190 public static final int CHANNEL_IN_DEFAULT = 1; 191 // These directly match native 192 public static final int CHANNEL_IN_LEFT = 0x4; 193 public static final int CHANNEL_IN_RIGHT = 0x8; 194 public static final int CHANNEL_IN_FRONT = 0x10; 195 public static final int CHANNEL_IN_BACK = 0x20; 196 public static final int CHANNEL_IN_LEFT_PROCESSED = 0x40; 197 public static final int CHANNEL_IN_RIGHT_PROCESSED = 0x80; 198 public static final int CHANNEL_IN_FRONT_PROCESSED = 0x100; 199 public static final int CHANNEL_IN_BACK_PROCESSED = 0x200; 200 public static final int CHANNEL_IN_PRESSURE = 0x400; 201 public static final int CHANNEL_IN_X_AXIS = 0x800; 202 public static final int CHANNEL_IN_Y_AXIS = 0x1000; 203 public static final int CHANNEL_IN_Z_AXIS = 0x2000; 204 public static final int CHANNEL_IN_VOICE_UPLINK = 0x4000; 205 public static final int CHANNEL_IN_VOICE_DNLINK = 0x8000; 206 public static final int CHANNEL_IN_MONO = CHANNEL_IN_FRONT; 207 public static final int CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT); 208 /** @hide */ 209 public static final int CHANNEL_IN_FRONT_BACK = CHANNEL_IN_FRONT | CHANNEL_IN_BACK; 210 // CHANNEL_IN_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_IN_ALL 211 212 /** @hide */ getBytesPerSample(int audioFormat)213 public static int getBytesPerSample(int audioFormat) 214 { 215 switch (audioFormat) { 216 case ENCODING_PCM_8BIT: 217 return 1; 218 case ENCODING_PCM_16BIT: 219 case ENCODING_DEFAULT: 220 return 2; 221 case ENCODING_PCM_FLOAT: 222 return 4; 223 case ENCODING_INVALID: 224 default: 225 throw new IllegalArgumentException("Bad audio format " + audioFormat); 226 } 227 } 228 229 /** @hide */ isValidEncoding(int audioFormat)230 public static boolean isValidEncoding(int audioFormat) 231 { 232 switch (audioFormat) { 233 case ENCODING_PCM_8BIT: 234 case ENCODING_PCM_16BIT: 235 case ENCODING_PCM_FLOAT: 236 case ENCODING_AC3: 237 case ENCODING_E_AC3: 238 return true; 239 default: 240 return false; 241 } 242 } 243 244 /** @hide */ isEncodingLinearPcm(int audioFormat)245 public static boolean isEncodingLinearPcm(int audioFormat) 246 { 247 switch (audioFormat) { 248 case ENCODING_PCM_8BIT: 249 case ENCODING_PCM_16BIT: 250 case ENCODING_PCM_FLOAT: 251 case ENCODING_DEFAULT: 252 return true; 253 case ENCODING_AC3: 254 case ENCODING_E_AC3: 255 return false; 256 case ENCODING_INVALID: 257 default: 258 throw new IllegalArgumentException("Bad audio format " + audioFormat); 259 } 260 } 261 262 /** @removed */ AudioFormat()263 public AudioFormat() 264 { 265 throw new UnsupportedOperationException("There is no valid usage of this constructor"); 266 } 267 268 /** 269 * Private constructor with an ignored argument to differentiate from the removed default ctor 270 * @param ignoredArgument 271 */ AudioFormat(int ignoredArgument)272 private AudioFormat(int ignoredArgument) { 273 } 274 275 /** 276 * Constructor used by the JNI 277 */ 278 // Update sound trigger JNI in core/jni/android_hardware_SoundTrigger.cpp when modifying this 279 // constructor AudioFormat(int encoding, int sampleRate, int channelMask)280 private AudioFormat(int encoding, int sampleRate, int channelMask) { 281 mEncoding = encoding; 282 mSampleRate = sampleRate; 283 mChannelMask = channelMask; 284 mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_ENCODING | 285 AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE | 286 AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK; 287 } 288 289 /** @hide */ 290 public final static int AUDIO_FORMAT_HAS_PROPERTY_NONE = 0x0; 291 /** @hide */ 292 public final static int AUDIO_FORMAT_HAS_PROPERTY_ENCODING = 0x1 << 0; 293 /** @hide */ 294 public final static int AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE = 0x1 << 1; 295 /** @hide */ 296 public final static int AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK = 0x1 << 2; 297 298 private int mEncoding; 299 private int mSampleRate; 300 private int mChannelMask; 301 private int mPropertySetMask; 302 303 /** 304 * Return the encoding. 305 * @return one of the values that can be set in {@link Builder#setEncoding(int)} or 306 * {@link AudioFormat#ENCODING_INVALID} if not set. 307 */ getEncoding()308 public int getEncoding() { 309 if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_ENCODING) == 0) { 310 return ENCODING_INVALID; 311 } 312 return mEncoding; 313 } 314 315 /** 316 * Return the sample rate. 317 * @return one of the values that can be set in {@link Builder#setSampleRate(int)} or 318 * 0 if not set. 319 */ getSampleRate()320 public int getSampleRate() { 321 if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) == 0) { 322 return 0; 323 } 324 return mSampleRate; 325 } 326 327 /** 328 * Return the channel mask. 329 * @return one of the values that can be set in {@link Builder#setChannelMask(int)} or 330 * {@link AudioFormat#CHANNEL_INVALID} if not set. 331 */ getChannelMask()332 public int getChannelMask() { 333 if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) == 0) { 334 return CHANNEL_INVALID; 335 } 336 return mChannelMask; 337 } 338 339 /** @hide */ getPropertySetMask()340 public int getPropertySetMask() { 341 return mPropertySetMask; 342 } 343 344 /** 345 * Builder class for {@link AudioFormat} objects. 346 * Use this class to configure and create an AudioFormat instance. By setting format 347 * characteristics such as audio encoding, channel mask or sample rate, you indicate which 348 * of those are to vary from the default behavior on this device wherever this audio format 349 * is used. 350 * <p>{@link AudioFormat} is for instance used in 351 * {@link AudioTrack#AudioTrack(AudioAttributes, AudioFormat, int, int, int)}. In this 352 * constructor, every format characteristic set on the <code>Builder</code> (e.g. with 353 * {@link #setSampleRate(int)}) will alter the default values used by an 354 * <code>AudioTrack</code>. In this case for audio playback with <code>AudioTrack</code>, the 355 * sample rate set in the <code>Builder</code> would override the platform output sample rate 356 * which would otherwise be selected by default. 357 */ 358 public static class Builder { 359 private int mEncoding = ENCODING_INVALID; 360 private int mSampleRate = 0; 361 private int mChannelMask = CHANNEL_INVALID; 362 private int mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_NONE; 363 364 /** 365 * Constructs a new Builder with none of the format characteristics set. 366 */ Builder()367 public Builder() { 368 } 369 370 /** 371 * Constructs a new Builder from a given {@link AudioFormat}. 372 * @param af the {@link AudioFormat} object whose data will be reused in the new Builder. 373 */ Builder(AudioFormat af)374 public Builder(AudioFormat af) { 375 mEncoding = af.mEncoding; 376 mSampleRate = af.mSampleRate; 377 mChannelMask = af.mChannelMask; 378 mPropertySetMask = af.mPropertySetMask; 379 } 380 381 /** 382 * Combines all of the format characteristics that have been set and return a new 383 * {@link AudioFormat} object. 384 * @return a new {@link AudioFormat} object 385 */ build()386 public AudioFormat build() { 387 AudioFormat af = new AudioFormat(1980/*ignored*/); 388 af.mEncoding = mEncoding; 389 af.mSampleRate = mSampleRate; 390 af.mChannelMask = mChannelMask; 391 af.mPropertySetMask = mPropertySetMask; 392 return af; 393 } 394 395 /** 396 * Sets the data encoding format. 397 * @param encoding one of {@link AudioFormat#ENCODING_DEFAULT}, 398 * {@link AudioFormat#ENCODING_PCM_8BIT}, 399 * {@link AudioFormat#ENCODING_PCM_16BIT}, 400 * {@link AudioFormat#ENCODING_PCM_FLOAT}, 401 * {@link AudioFormat#ENCODING_AC3}, 402 * {@link AudioFormat#ENCODING_E_AC3}. 403 * @return the same Builder instance. 404 * @throws java.lang.IllegalArgumentException 405 */ setEncoding(@ncoding int encoding)406 public Builder setEncoding(@Encoding int encoding) throws IllegalArgumentException { 407 switch (encoding) { 408 case ENCODING_DEFAULT: 409 mEncoding = ENCODING_PCM_16BIT; 410 break; 411 case ENCODING_PCM_8BIT: 412 case ENCODING_PCM_16BIT: 413 case ENCODING_PCM_FLOAT: 414 case ENCODING_AC3: 415 case ENCODING_E_AC3: 416 mEncoding = encoding; 417 break; 418 case ENCODING_INVALID: 419 default: 420 throw new IllegalArgumentException("Invalid encoding " + encoding); 421 } 422 mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_ENCODING; 423 return this; 424 } 425 426 /** 427 * Sets the channel mask. 428 * @param channelMask describes the configuration of the audio channels. 429 * <p>For output, the mask should be a combination of 430 * {@link AudioFormat#CHANNEL_OUT_FRONT_LEFT}, 431 * {@link AudioFormat#CHANNEL_OUT_FRONT_CENTER}, 432 * {@link AudioFormat#CHANNEL_OUT_FRONT_RIGHT}, 433 * {@link AudioFormat#CHANNEL_OUT_SIDE_LEFT}, 434 * {@link AudioFormat#CHANNEL_OUT_SIDE_RIGHT}, 435 * {@link AudioFormat#CHANNEL_OUT_BACK_LEFT}, 436 * {@link AudioFormat#CHANNEL_OUT_BACK_RIGHT}. 437 * <p>for input, the mask should be {@link AudioFormat#CHANNEL_IN_MONO} or 438 * {@link AudioFormat#CHANNEL_IN_STEREO}. {@link AudioFormat#CHANNEL_IN_MONO} is 439 * guaranteed to work on all devices. 440 * @return the same Builder instance. 441 */ setChannelMask(int channelMask)442 public Builder setChannelMask(int channelMask) { 443 // only validated when used, with input or output context 444 mChannelMask = channelMask; 445 mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK; 446 return this; 447 } 448 449 /** 450 * Sets the sample rate. 451 * @param sampleRate the sample rate expressed in Hz 452 * @return the same Builder instance. 453 * @throws java.lang.IllegalArgumentException 454 */ setSampleRate(int sampleRate)455 public Builder setSampleRate(int sampleRate) throws IllegalArgumentException { 456 if ((sampleRate <= 0) || (sampleRate > 192000)) { 457 throw new IllegalArgumentException("Invalid sample rate " + sampleRate); 458 } 459 mSampleRate = sampleRate; 460 mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE; 461 return this; 462 } 463 } 464 465 @Override toString()466 public String toString () { 467 return new String("AudioFormat:" 468 + " props=" + mPropertySetMask 469 + " enc=" + mEncoding 470 + " chan=0x" + Integer.toHexString(mChannelMask) 471 + " rate=" + mSampleRate); 472 } 473 474 /** @hide */ 475 @IntDef({ 476 ENCODING_DEFAULT, 477 ENCODING_PCM_8BIT, 478 ENCODING_PCM_16BIT, 479 ENCODING_PCM_FLOAT, 480 ENCODING_AC3, 481 ENCODING_E_AC3 482 }) 483 @Retention(RetentionPolicy.SOURCE) 484 public @interface Encoding {} 485 486 } 487