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