AudioFormat.java revision 0498269c00e340a5cacf19c00d552c9a311cc604
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 android.annotation.IntDef; 20 21import java.lang.annotation.Retention; 22import 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 */ 30public 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 /** @hide */ 253 public final static int AUDIO_FORMAT_HAS_PROPERTY_NONE = 0x0; 254 /** @hide */ 255 public final static int AUDIO_FORMAT_HAS_PROPERTY_ENCODING = 0x1 << 0; 256 /** @hide */ 257 public final static int AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE = 0x1 << 1; 258 /** @hide */ 259 public final static int AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK = 0x1 << 2; 260 261 private int mEncoding; 262 private int mSampleRate; 263 private int mChannelMask; 264 private int mPropertySetMask; 265 266 /** 267 * Return the encoding. 268 * @return one of the values that can be set in {@link Builder#setEncoding(int)} or 269 * {@link AudioFormat#ENCODING_INVALID} if not set. 270 */ 271 public int getEncoding() { 272 if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_ENCODING) == 0) { 273 return ENCODING_INVALID; 274 } 275 return mEncoding; 276 } 277 278 /** 279 * Return the sample rate. 280 * @return one of the values that can be set in {@link Builder#setSampleRate(int)} or 281 * 0 if not set. 282 */ 283 public int getSampleRate() { 284 if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) == 0) { 285 return 0; 286 } 287 return mSampleRate; 288 } 289 290 /** 291 * Return the channel mask. 292 * @return one of the values that can be set in {@link Builder#setChannelMask(int)} or 293 * {@link AudioFormat#CHANNEL_INVALID} if not set. 294 */ 295 public int getChannelMask() { 296 if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) == 0) { 297 return CHANNEL_INVALID; 298 } 299 return mChannelMask; 300 } 301 302 /** @hide */ 303 public int getPropertySetMask() { 304 return mPropertySetMask; 305 } 306 307 /** 308 * Builder class for {@link AudioFormat} objects. 309 */ 310 public static class Builder { 311 private int mEncoding = ENCODING_PCM_16BIT; 312 private int mSampleRate = 0; 313 private int mChannelMask = CHANNEL_INVALID; 314 private int mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_NONE; 315 316 /** 317 * Constructs a new Builder with the defaults format values. 318 */ 319 public Builder() { 320 } 321 322 /** 323 * Constructs a new Builder from a given {@link AudioFormat}. 324 * @param af the {@link AudioFormat} object whose data will be reused in the new Builder. 325 */ 326 public Builder(AudioFormat af) { 327 mEncoding = af.mEncoding; 328 mSampleRate = af.mSampleRate; 329 mChannelMask = af.mChannelMask; 330 mPropertySetMask = af.mPropertySetMask; 331 } 332 333 /** 334 * Combines all of the format characteristics that have been set and return a new 335 * {@link AudioFormat} object. 336 * @return a new {@link AudioFormat} object 337 */ 338 public AudioFormat build() { 339 AudioFormat af = new AudioFormat(1980/*ignored*/); 340 af.mEncoding = mEncoding; 341 af.mSampleRate = mSampleRate; 342 af.mChannelMask = mChannelMask; 343 af.mPropertySetMask = mPropertySetMask; 344 return af; 345 } 346 347 /** 348 * Sets the data encoding format. 349 * @param encoding one of {@link AudioFormat#ENCODING_DEFAULT}, 350 * {@link AudioFormat#ENCODING_PCM_8BIT}, 351 * {@link AudioFormat#ENCODING_PCM_16BIT}, 352 * {@link AudioFormat#ENCODING_PCM_FLOAT}, 353 * {@link AudioFormat#ENCODING_AC3}, 354 * {@link AudioFormat#ENCODING_E_AC3}. 355 * @return the same Builder instance. 356 * @throws java.lang.IllegalArgumentException 357 */ 358 public Builder setEncoding(@Encoding int encoding) throws IllegalArgumentException { 359 switch (encoding) { 360 case ENCODING_DEFAULT: 361 mEncoding = ENCODING_PCM_16BIT; 362 break; 363 case ENCODING_PCM_8BIT: 364 case ENCODING_PCM_16BIT: 365 case ENCODING_PCM_FLOAT: 366 case ENCODING_AC3: 367 case ENCODING_E_AC3: 368 mEncoding = encoding; 369 break; 370 case ENCODING_INVALID: 371 default: 372 throw new IllegalArgumentException("Invalid encoding " + encoding); 373 } 374 mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_ENCODING; 375 return this; 376 } 377 378 /** 379 * Sets the channel mask. 380 * @param channelMask describes the configuration of the audio channels. 381 * <p>For output, the mask should be a combination of 382 * {@link AudioFormat#CHANNEL_OUT_FRONT_LEFT}, 383 * {@link AudioFormat#CHANNEL_OUT_FRONT_CENTER}, 384 * {@link AudioFormat#CHANNEL_OUT_FRONT_RIGHT}, 385 * {@link AudioFormat#CHANNEL_OUT_SIDE_LEFT}, 386 * {@link AudioFormat#CHANNEL_OUT_SIDE_RIGHT}, 387 * {@link AudioFormat#CHANNEL_OUT_BACK_LEFT}, 388 * {@link AudioFormat#CHANNEL_OUT_BACK_RIGHT}. 389 * <p>for input, the mask should be {@link AudioFormat#CHANNEL_IN_MONO} or 390 * {@link AudioFormat#CHANNEL_IN_STEREO}. {@link AudioFormat#CHANNEL_IN_MONO} is 391 * guaranteed to work on all devices. 392 * @return the same Builder instance. 393 */ 394 public Builder setChannelMask(int channelMask) { 395 // only validated when used, with input or output context 396 mChannelMask = channelMask; 397 mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK; 398 return this; 399 } 400 401 /** 402 * Sets the sample rate. 403 * @param sampleRate the sample rate expressed in Hz 404 * @return the same Builder instance. 405 * @throws java.lang.IllegalArgumentException 406 */ 407 public Builder setSampleRate(int sampleRate) throws IllegalArgumentException { 408 if ((sampleRate <= 0) || (sampleRate > 192000)) { 409 throw new IllegalArgumentException("Invalid sample rate " + sampleRate); 410 } 411 mSampleRate = sampleRate; 412 mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE; 413 return this; 414 } 415 } 416 417 @Override 418 public String toString () { 419 return new String("AudioFormat:" 420 + " props=" + mPropertySetMask 421 + " enc=" + mEncoding 422 + " chan=0x" + Integer.toHexString(mChannelMask) 423 + " rate=" + mSampleRate); 424 } 425 426 /** @hide */ 427 @IntDef({ 428 ENCODING_DEFAULT, 429 ENCODING_PCM_8BIT, 430 ENCODING_PCM_16BIT, 431 ENCODING_PCM_FLOAT, 432 ENCODING_AC3, 433 ENCODING_E_AC3 434 }) 435 @Retention(RetentionPolicy.SOURCE) 436 public @interface Encoding {} 437 438} 439