Home | History | Annotate | Download | only in media
      1 /*
      2  * Copyright (C) 2018 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 import android.annotation.NonNull;
     21 import android.util.Pair;
     22 
     23 import java.lang.annotation.Retention;
     24 import java.lang.annotation.RetentionPolicy;
     25 import java.util.List;
     26 
     27 /**
     28  * Class providing information on a microphone. It indicates the location and orientation of the
     29  * microphone on the device as well as useful information like frequency response and sensitivity.
     30  * It can be used by applications implementing special pre processing effects like noise suppression
     31  * of beam forming that need to know about precise microphone characteristics in order to adapt
     32  * their algorithms.
     33  */
     34 public final class MicrophoneInfo {
     35 
     36     /**
     37      * A microphone that the location is unknown.
     38      */
     39     public static final int LOCATION_UNKNOWN = 0;
     40 
     41     /**
     42      * A microphone that locate on main body of the device.
     43      */
     44     public static final int LOCATION_MAINBODY = 1;
     45 
     46     /**
     47      * A microphone that locate on a movable main body of the device.
     48      */
     49     public static final int LOCATION_MAINBODY_MOVABLE = 2;
     50 
     51     /**
     52      * A microphone that locate on a peripheral.
     53      */
     54     public static final int LOCATION_PERIPHERAL = 3;
     55 
     56     /**
     57      * Unknown microphone directionality.
     58      */
     59     public static final int DIRECTIONALITY_UNKNOWN = 0;
     60 
     61     /**
     62      * Microphone directionality type: omni.
     63      */
     64     public static final int DIRECTIONALITY_OMNI = 1;
     65 
     66     /**
     67      * Microphone directionality type: bi-directional.
     68      */
     69     public static final int DIRECTIONALITY_BI_DIRECTIONAL = 2;
     70 
     71     /**
     72      * Microphone directionality type: cardioid.
     73      */
     74     public static final int DIRECTIONALITY_CARDIOID = 3;
     75 
     76     /**
     77      * Microphone directionality type: hyper cardioid.
     78      */
     79     public static final int DIRECTIONALITY_HYPER_CARDIOID = 4;
     80 
     81     /**
     82      * Microphone directionality type: super cardioid.
     83      */
     84     public static final int DIRECTIONALITY_SUPER_CARDIOID = 5;
     85 
     86     /**
     87      * The channel contains raw audio from this microphone.
     88      */
     89     public static final int CHANNEL_MAPPING_DIRECT = 1;
     90 
     91     /**
     92      * The channel contains processed audio from this microphone and possibly another microphone.
     93      */
     94     public static final int CHANNEL_MAPPING_PROCESSED = 2;
     95 
     96     /**
     97      * Value used for when the group of the microphone is unknown.
     98      */
     99     public static final int GROUP_UNKNOWN = -1;
    100 
    101     /**
    102      * Value used for when the index in the group of the microphone is unknown.
    103      */
    104     public static final int INDEX_IN_THE_GROUP_UNKNOWN = -1;
    105 
    106     /**
    107      * Value used for when the position of the microphone is unknown.
    108      */
    109     public static final Coordinate3F POSITION_UNKNOWN = new Coordinate3F(
    110             -Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE);
    111 
    112     /**
    113      * Value used for when the orientation of the microphone is unknown.
    114      */
    115     public static final Coordinate3F ORIENTATION_UNKNOWN = new Coordinate3F(0.0f, 0.0f, 0.0f);
    116 
    117     /**
    118      * Value used for when the sensitivity of the microphone is unknown.
    119      */
    120     public static final float SENSITIVITY_UNKNOWN = -Float.MAX_VALUE;
    121 
    122     /**
    123      * Value used for when the SPL of the microphone is unknown. This value could be used when
    124      * maximum SPL or minimum SPL is unknown.
    125      */
    126     public static final float SPL_UNKNOWN = -Float.MAX_VALUE;
    127 
    128     /** @hide */
    129     @IntDef(flag = true, prefix = { "LOCATION_" }, value = {
    130             LOCATION_UNKNOWN,
    131             LOCATION_MAINBODY,
    132             LOCATION_MAINBODY_MOVABLE,
    133             LOCATION_PERIPHERAL,
    134     })
    135     @Retention(RetentionPolicy.SOURCE)
    136     public @interface MicrophoneLocation {}
    137 
    138     /** @hide */
    139     @IntDef(flag = true, prefix = { "DIRECTIONALITY_" }, value = {
    140             DIRECTIONALITY_UNKNOWN,
    141             DIRECTIONALITY_OMNI,
    142             DIRECTIONALITY_BI_DIRECTIONAL,
    143             DIRECTIONALITY_CARDIOID,
    144             DIRECTIONALITY_HYPER_CARDIOID,
    145             DIRECTIONALITY_SUPER_CARDIOID,
    146     })
    147     @Retention(RetentionPolicy.SOURCE)
    148     public @interface MicrophoneDirectionality {}
    149 
    150     private Coordinate3F mPosition;
    151     private Coordinate3F mOrientation;
    152     private String mDeviceId;
    153     private String mAddress;
    154     private List<Pair<Float, Float>> mFrequencyResponse;
    155     private List<Pair<Integer, Integer>> mChannelMapping;
    156     private float mMaxSpl;
    157     private float mMinSpl;
    158     private float mSensitivity;
    159     private int mLocation;
    160     private int mGroup; /* Usually 0 will be used for main body. */
    161     private int mIndexInTheGroup;
    162     private int mPortId; /* mPortId will correspond to the id in AudioPort */
    163     private int mType;
    164     private int mDirectionality;
    165 
    166     MicrophoneInfo(String deviceId, int type, String address, int location,
    167             int group, int indexInTheGroup, Coordinate3F position,
    168             Coordinate3F orientation, List<Pair<Float, Float>> frequencyResponse,
    169             List<Pair<Integer, Integer>> channelMapping, float sensitivity, float maxSpl,
    170             float minSpl, int directionality) {
    171         mDeviceId = deviceId;
    172         mType = type;
    173         mAddress = address;
    174         mLocation = location;
    175         mGroup = group;
    176         mIndexInTheGroup = indexInTheGroup;
    177         mPosition = position;
    178         mOrientation = orientation;
    179         mFrequencyResponse = frequencyResponse;
    180         mChannelMapping = channelMapping;
    181         mSensitivity = sensitivity;
    182         mMaxSpl = maxSpl;
    183         mMinSpl = minSpl;
    184         mDirectionality = directionality;
    185     }
    186 
    187     /**
    188      * Returns alphanumeric code that uniquely identifies the device.
    189      *
    190      * @return the description of the microphone
    191      */
    192     public String getDescription() {
    193         return mDeviceId;
    194     }
    195 
    196     /**
    197      * Returns The system unique device ID that corresponds to the id
    198      * returned by {@link AudioDeviceInfo#getId()}.
    199      *
    200      * @return the microphone's id
    201      */
    202     public int getId() {
    203         return mPortId;
    204     }
    205 
    206     /**
    207      * @hide
    208      * Returns the internal device type (e.g AudioSystem.DEVICE_IN_BUILTIN_MIC).
    209      * The internal device type could be used when getting microphone's port id
    210      * by matching type and address.
    211      *
    212      * @return the internal device type
    213      */
    214     public int getInternalDeviceType() {
    215         return mType;
    216     }
    217 
    218     /**
    219      * Returns the device type identifier of the microphone (e.g AudioDeviceInfo.TYPE_BUILTIN_MIC).
    220      *
    221      * @return the device type of the microphone
    222      */
    223     public int getType() {
    224         return AudioDeviceInfo.convertInternalDeviceToDeviceType(mType);
    225     }
    226 
    227     /**
    228      * Returns The "address" string of the microphone that corresponds to the
    229      * address returned by {@link AudioDeviceInfo#getAddress()}
    230      * @return the address of the microphone
    231      */
    232     public @NonNull String getAddress() {
    233         return mAddress;
    234     }
    235 
    236     /**
    237      * Returns the location of the microphone. The return value is
    238      * one of {@link #LOCATION_UNKNOWN}, {@link #LOCATION_MAINBODY},
    239      * {@link #LOCATION_MAINBODY_MOVABLE}, or {@link #LOCATION_PERIPHERAL}.
    240      *
    241      * @return the location of the microphone
    242      */
    243     public @MicrophoneLocation int getLocation() {
    244         return mLocation;
    245     }
    246 
    247     /**
    248      * Returns A device group id that can be used to group together microphones on the same
    249      * peripheral, attachments or logical groups. Main body is usually group 0.
    250      *
    251      * @return the group of the microphone or {@link #GROUP_UNKNOWN} if the group is unknown
    252      */
    253     public int getGroup() {
    254         return mGroup;
    255     }
    256 
    257     /**
    258      * Returns unique index for device within its group.
    259      *
    260      * @return the microphone's index in its group or {@link #INDEX_IN_THE_GROUP_UNKNOWN} if the
    261      * index in the group is unknown
    262      */
    263     public int getIndexInTheGroup() {
    264         return mIndexInTheGroup;
    265     }
    266 
    267     /**
    268      * Returns A {@link Coordinate3F} object that represents the geometric location of microphone
    269      * in meters, from bottom-left-back corner of appliance. X-axis, Y-axis and Z-axis show
    270      * as the x, y, z values.
    271      *
    272      * @return the geometric location of the microphone or {@link #POSITION_UNKNOWN} if the
    273      * geometric location is unknown
    274      */
    275     public Coordinate3F getPosition() {
    276         return mPosition;
    277     }
    278 
    279     /**
    280      * Returns A {@link Coordinate3F} object that represents the orientation of microphone.
    281      * X-axis, Y-axis and Z-axis show as the x, y, z value. The orientation will be normalized
    282      * such as sqrt(x^2 + y^2 + z^2) equals 1.
    283      *
    284      * @return the orientation of the microphone or {@link #ORIENTATION_UNKNOWN} if orientation
    285      * is unknown
    286      */
    287     public Coordinate3F getOrientation() {
    288         return mOrientation;
    289     }
    290 
    291     /**
    292      * Returns a {@link android.util.Pair} list of frequency responses.
    293      * For every {@link android.util.Pair} in the list, the first value represents frequency in Hz,
    294      * and the second value represents response in dB.
    295      *
    296      * @return the frequency response of the microphone
    297      */
    298     public List<Pair<Float, Float>> getFrequencyResponse() {
    299         return mFrequencyResponse;
    300     }
    301 
    302     /**
    303      * Returns a {@link android.util.Pair} list for channel mapping, which indicating how this
    304      * microphone is used by each channels or a capture stream. For each {@link android.util.Pair},
    305      * the first value is channel index, the second value is channel mapping type, which could be
    306      * either {@link #CHANNEL_MAPPING_DIRECT} or {@link #CHANNEL_MAPPING_PROCESSED}.
    307      * If a channel has contributions from more than one microphone, it is likely the HAL
    308      * did some extra processing to combine the sources, but this is to be inferred by the user.
    309      * Empty list when the MicrophoneInfo is returned by AudioManager.getMicrophones().
    310      * At least one entry when the MicrophoneInfo is returned by AudioRecord.getActiveMicrophones().
    311      *
    312      * @return a {@link android.util.Pair} list for channel mapping
    313      */
    314     public List<Pair<Integer, Integer>> getChannelMapping() {
    315         return mChannelMapping;
    316     }
    317 
    318     /**
    319      * Returns the level in dBFS produced by a 1000Hz tone at 94 dB SPL.
    320      *
    321      * @return the sensitivity of the microphone or {@link #SENSITIVITY_UNKNOWN} if the sensitivity
    322      * is unknown
    323      */
    324     public float getSensitivity() {
    325         return mSensitivity;
    326     }
    327 
    328     /**
    329      * Returns the level in dB of the maximum SPL supported by the device at 1000Hz.
    330      *
    331      * @return the maximum level in dB or {@link #SPL_UNKNOWN} if maximum SPL is unknown
    332      */
    333     public float getMaxSpl() {
    334         return mMaxSpl;
    335     }
    336 
    337     /**
    338      * Returns the level in dB of the minimum SPL that can be registered by the device at 1000Hz.
    339      *
    340      * @return the minimum level in dB or {@link #SPL_UNKNOWN} if minimum SPL is unknown
    341      */
    342     public float getMinSpl() {
    343         return mMinSpl;
    344     }
    345 
    346     /**
    347      * Returns the directionality of microphone. The return value is one of
    348      * {@link #DIRECTIONALITY_UNKNOWN}, {@link #DIRECTIONALITY_OMNI},
    349      * {@link #DIRECTIONALITY_BI_DIRECTIONAL}, {@link #DIRECTIONALITY_CARDIOID},
    350      * {@link #DIRECTIONALITY_HYPER_CARDIOID}, or {@link #DIRECTIONALITY_SUPER_CARDIOID}.
    351      *
    352      * @return the directionality of microphone
    353      */
    354     public @MicrophoneDirectionality int getDirectionality() {
    355         return mDirectionality;
    356     }
    357 
    358     /**
    359      * Set the port id for the device.
    360      * @hide
    361      */
    362     public void setId(int portId) {
    363         mPortId = portId;
    364     }
    365 
    366     /**
    367      * Set the channel mapping for the device.
    368      * @hide
    369      */
    370     public void setChannelMapping(List<Pair<Integer, Integer>> channelMapping) {
    371         mChannelMapping = channelMapping;
    372     }
    373 
    374     /* A class containing three float value to represent a 3D coordinate */
    375     public static final class Coordinate3F {
    376         public final float x;
    377         public final float y;
    378         public final float z;
    379 
    380         Coordinate3F(float x, float y, float z) {
    381             this.x = x;
    382             this.y = y;
    383             this.z = z;
    384         }
    385 
    386         @Override
    387         public boolean equals(Object obj) {
    388             if (this == obj) {
    389                 return true;
    390             }
    391             if (!(obj instanceof Coordinate3F)) {
    392                 return false;
    393             }
    394             Coordinate3F other = (Coordinate3F) obj;
    395             return this.x == other.x && this.y == other.y && this.z == other.z;
    396         }
    397     }
    398 }
    399