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 number of channels from an input channel mask 132 * @param mask a combination of the CHANNEL_IN_* definitions, even CHANNEL_IN_DEFAULT 133 * @return number of channels for the mask 134 */ 135 public static int channelCountFromInChannelMask(int mask) { 136 return Integer.bitCount(mask); 137 } 138 /** 139 * @hide 140 * Return the number of channels from an output channel mask 141 * @param mask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT 142 * @return number of channels for the mask 143 */ 144 public static int channelCountFromOutChannelMask(int mask) { 145 return Integer.bitCount(mask); 146 } 147 /** 148 * @hide 149 * Return a channel mask ready to be used by native code 150 * @param mask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT 151 * @return a native channel mask 152 */ 153 public static int convertChannelOutMaskToNativeMask(int javaMask) { 154 return (javaMask >> 2); 155 } 156 157 /** 158 * @hide 159 * Return a java output channel mask 160 * @param mask a native channel mask 161 * @return a combination of the CHANNEL_OUT_* definitions 162 */ 163 public static int convertNativeChannelMaskToOutMask(int nativeMask) { 164 return (nativeMask << 2); 165 } 166 167 public static final int CHANNEL_IN_DEFAULT = 1; 168 // These directly match native 169 public static final int CHANNEL_IN_LEFT = 0x4; 170 public static final int CHANNEL_IN_RIGHT = 0x8; 171 public static final int CHANNEL_IN_FRONT = 0x10; 172 public static final int CHANNEL_IN_BACK = 0x20; 173 public static final int CHANNEL_IN_LEFT_PROCESSED = 0x40; 174 public static final int CHANNEL_IN_RIGHT_PROCESSED = 0x80; 175 public static final int CHANNEL_IN_FRONT_PROCESSED = 0x100; 176 public static final int CHANNEL_IN_BACK_PROCESSED = 0x200; 177 public static final int CHANNEL_IN_PRESSURE = 0x400; 178 public static final int CHANNEL_IN_X_AXIS = 0x800; 179 public static final int CHANNEL_IN_Y_AXIS = 0x1000; 180 public static final int CHANNEL_IN_Z_AXIS = 0x2000; 181 public static final int CHANNEL_IN_VOICE_UPLINK = 0x4000; 182 public static final int CHANNEL_IN_VOICE_DNLINK = 0x8000; 183 public static final int CHANNEL_IN_MONO = CHANNEL_IN_FRONT; 184 public static final int CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT); 185 /** @hide */ 186 public static final int CHANNEL_IN_FRONT_BACK = CHANNEL_IN_FRONT | CHANNEL_IN_BACK; 187 // CHANNEL_IN_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_IN_ALL 188 189 /** @hide */ 190 public static int getBytesPerSample(int audioFormat) 191 { 192 switch (audioFormat) { 193 case ENCODING_PCM_8BIT: 194 return 1; 195 case ENCODING_PCM_16BIT: 196 case ENCODING_DEFAULT: 197 return 2; 198 case ENCODING_PCM_FLOAT: 199 return 4; 200 case ENCODING_INVALID: 201 default: 202 throw new IllegalArgumentException("Bad audio format " + audioFormat); 203 } 204 } 205 206 /** @hide */ 207 public static boolean isValidEncoding(int audioFormat) 208 { 209 switch (audioFormat) { 210 case ENCODING_PCM_8BIT: 211 case ENCODING_PCM_16BIT: 212 case ENCODING_PCM_FLOAT: 213 case ENCODING_AC3: 214 case ENCODING_E_AC3: 215 return true; 216 default: 217 return false; 218 } 219 } 220 221 /** @hide */ 222 public static boolean isEncodingLinearPcm(int audioFormat) 223 { 224 switch (audioFormat) { 225 case ENCODING_PCM_8BIT: 226 case ENCODING_PCM_16BIT: 227 case ENCODING_PCM_FLOAT: 228 case ENCODING_DEFAULT: 229 return true; 230 case ENCODING_AC3: 231 case ENCODING_E_AC3: 232 return false; 233 case ENCODING_INVALID: 234 default: 235 throw new IllegalArgumentException("Bad audio format " + audioFormat); 236 } 237 } 238 239 /** @removed */ 240 public AudioFormat() 241 { 242 throw new UnsupportedOperationException("There is no valid usage of this constructor"); 243 } 244 245 /** 246 * Private constructor with an ignored argument to differentiate from the removed default ctor 247 * @param ignoredArgument 248 */ 249 private AudioFormat(int ignoredArgument) { 250 } 251 252 /** 253 * Constructor used by the JNI 254 */ 255 // Update sound trigger JNI in core/jni/android_hardware_SoundTrigger.cpp when modifying this 256 // constructor 257 private AudioFormat(int encoding, int sampleRate, int channelMask) { 258 mEncoding = encoding; 259 mSampleRate = sampleRate; 260 mChannelMask = channelMask; 261 mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_ENCODING | 262 AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE | 263 AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK; 264 } 265 266 /** @hide */ 267 public final static int AUDIO_FORMAT_HAS_PROPERTY_NONE = 0x0; 268 /** @hide */ 269 public final static int AUDIO_FORMAT_HAS_PROPERTY_ENCODING = 0x1 << 0; 270 /** @hide */ 271 public final static int AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE = 0x1 << 1; 272 /** @hide */ 273 public final static int AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK = 0x1 << 2; 274 275 private int mEncoding; 276 private int mSampleRate; 277 private int mChannelMask; 278 private int mPropertySetMask; 279 280 /** 281 * Return the encoding. 282 * @return one of the values that can be set in {@link Builder#setEncoding(int)} or 283 * {@link AudioFormat#ENCODING_INVALID} if not set. 284 */ 285 public int getEncoding() { 286 if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_ENCODING) == 0) { 287 return ENCODING_INVALID; 288 } 289 return mEncoding; 290 } 291 292 /** 293 * Return the sample rate. 294 * @return one of the values that can be set in {@link Builder#setSampleRate(int)} or 295 * 0 if not set. 296 */ 297 public int getSampleRate() { 298 if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) == 0) { 299 return 0; 300 } 301 return mSampleRate; 302 } 303 304 /** 305 * Return the channel mask. 306 * @return one of the values that can be set in {@link Builder#setChannelMask(int)} or 307 * {@link AudioFormat#CHANNEL_INVALID} if not set. 308 */ 309 public int getChannelMask() { 310 if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) == 0) { 311 return CHANNEL_INVALID; 312 } 313 return mChannelMask; 314 } 315 316 /** @hide */ 317 public int getPropertySetMask() { 318 return mPropertySetMask; 319 } 320 321 /** 322 * Builder class for {@link AudioFormat} objects. 323 * Use this class to configure and create an AudioFormat instance. By setting format 324 * characteristics such as audio encoding, channel mask or sample rate, you indicate which 325 * of those are to vary from the default behavior on this device wherever this audio format 326 * is used. 327 * <p>{@link AudioFormat} is for instance used in 328 * {@link AudioTrack#AudioTrack(AudioAttributes, AudioFormat, int, int, int)}. In this 329 * constructor, every format characteristic set on the <code>Builder</code> (e.g. with 330 * {@link #setSampleRate(int)}) will alter the default values used by an 331 * <code>AudioTrack</code>. In this case for audio playback with <code>AudioTrack</code>, the 332 * sample rate set in the <code>Builder</code> would override the platform output sample rate 333 * which would otherwise be selected by default. 334 */ 335 public static class Builder { 336 private int mEncoding = ENCODING_INVALID; 337 private int mSampleRate = 0; 338 private int mChannelMask = CHANNEL_INVALID; 339 private int mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_NONE; 340 341 /** 342 * Constructs a new Builder with none of the format characteristics set. 343 */ 344 public Builder() { 345 } 346 347 /** 348 * Constructs a new Builder from a given {@link AudioFormat}. 349 * @param af the {@link AudioFormat} object whose data will be reused in the new Builder. 350 */ 351 public Builder(AudioFormat af) { 352 mEncoding = af.mEncoding; 353 mSampleRate = af.mSampleRate; 354 mChannelMask = af.mChannelMask; 355 mPropertySetMask = af.mPropertySetMask; 356 } 357 358 /** 359 * Combines all of the format characteristics that have been set and return a new 360 * {@link AudioFormat} object. 361 * @return a new {@link AudioFormat} object 362 */ 363 public AudioFormat build() { 364 AudioFormat af = new AudioFormat(1980/*ignored*/); 365 af.mEncoding = mEncoding; 366 af.mSampleRate = mSampleRate; 367 af.mChannelMask = mChannelMask; 368 af.mPropertySetMask = mPropertySetMask; 369 return af; 370 } 371 372 /** 373 * Sets the data encoding format. 374 * @param encoding one of {@link AudioFormat#ENCODING_DEFAULT}, 375 * {@link AudioFormat#ENCODING_PCM_8BIT}, 376 * {@link AudioFormat#ENCODING_PCM_16BIT}, 377 * {@link AudioFormat#ENCODING_PCM_FLOAT}, 378 * {@link AudioFormat#ENCODING_AC3}, 379 * {@link AudioFormat#ENCODING_E_AC3}. 380 * @return the same Builder instance. 381 * @throws java.lang.IllegalArgumentException 382 */ 383 public Builder setEncoding(@Encoding int encoding) throws IllegalArgumentException { 384 switch (encoding) { 385 case ENCODING_DEFAULT: 386 mEncoding = ENCODING_PCM_16BIT; 387 break; 388 case ENCODING_PCM_8BIT: 389 case ENCODING_PCM_16BIT: 390 case ENCODING_PCM_FLOAT: 391 case ENCODING_AC3: 392 case ENCODING_E_AC3: 393 mEncoding = encoding; 394 break; 395 case ENCODING_INVALID: 396 default: 397 throw new IllegalArgumentException("Invalid encoding " + encoding); 398 } 399 mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_ENCODING; 400 return this; 401 } 402 403 /** 404 * Sets the channel mask. 405 * @param channelMask describes the configuration of the audio channels. 406 * <p>For output, the mask should be a combination of 407 * {@link AudioFormat#CHANNEL_OUT_FRONT_LEFT}, 408 * {@link AudioFormat#CHANNEL_OUT_FRONT_CENTER}, 409 * {@link AudioFormat#CHANNEL_OUT_FRONT_RIGHT}, 410 * {@link AudioFormat#CHANNEL_OUT_SIDE_LEFT}, 411 * {@link AudioFormat#CHANNEL_OUT_SIDE_RIGHT}, 412 * {@link AudioFormat#CHANNEL_OUT_BACK_LEFT}, 413 * {@link AudioFormat#CHANNEL_OUT_BACK_RIGHT}. 414 * <p>for input, the mask should be {@link AudioFormat#CHANNEL_IN_MONO} or 415 * {@link AudioFormat#CHANNEL_IN_STEREO}. {@link AudioFormat#CHANNEL_IN_MONO} is 416 * guaranteed to work on all devices. 417 * @return the same Builder instance. 418 */ 419 public Builder setChannelMask(int channelMask) { 420 // only validated when used, with input or output context 421 mChannelMask = channelMask; 422 mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK; 423 return this; 424 } 425 426 /** 427 * Sets the sample rate. 428 * @param sampleRate the sample rate expressed in Hz 429 * @return the same Builder instance. 430 * @throws java.lang.IllegalArgumentException 431 */ 432 public Builder setSampleRate(int sampleRate) throws IllegalArgumentException { 433 if ((sampleRate <= 0) || (sampleRate > 192000)) { 434 throw new IllegalArgumentException("Invalid sample rate " + sampleRate); 435 } 436 mSampleRate = sampleRate; 437 mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE; 438 return this; 439 } 440 } 441 442 @Override 443 public String toString () { 444 return new String("AudioFormat:" 445 + " props=" + mPropertySetMask 446 + " enc=" + mEncoding 447 + " chan=0x" + Integer.toHexString(mChannelMask) 448 + " rate=" + mSampleRate); 449 } 450 451 /** @hide */ 452 @IntDef({ 453 ENCODING_DEFAULT, 454 ENCODING_PCM_8BIT, 455 ENCODING_PCM_16BIT, 456 ENCODING_PCM_FLOAT, 457 ENCODING_AC3, 458 ENCODING_E_AC3 459 }) 460 @Retention(RetentionPolicy.SOURCE) 461 public @interface Encoding {} 462 463 } 464