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