Home | History | Annotate | Download | only in media
      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