summaryrefslogtreecommitdiff
path: root/android/media/MicrophoneInfo.java
blob: d6399a4163fe9ebeb71770695aefbc58c818c6eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.util.Pair;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;

/**
 * Class providing information on a microphone. It indicates the location and orientation of the
 * microphone on the device as well as useful information like frequency response and sensitivity.
 * It can be used by applications implementing special pre processing effects like noise suppression
 * of beam forming that need to know about precise microphone characteristics in order to adapt
 * their algorithms.
 */
public final class MicrophoneInfo {

    /**
     * A microphone that the location is unknown.
     */
    public static final int LOCATION_UNKNOWN = 0;

    /**
     * A microphone that locate on main body of the device.
     */
    public static final int LOCATION_MAINBODY = 1;

    /**
     * A microphone that locate on a movable main body of the device.
     */
    public static final int LOCATION_MAINBODY_MOVABLE = 2;

    /**
     * A microphone that locate on a peripheral.
     */
    public static final int LOCATION_PERIPHERAL = 3;

    /**
     * Unknown microphone directionality.
     */
    public static final int DIRECTIONALITY_UNKNOWN = 0;

    /**
     * Microphone directionality type: omni.
     */
    public static final int DIRECTIONALITY_OMNI = 1;

    /**
     * Microphone directionality type: bi-directional.
     */
    public static final int DIRECTIONALITY_BI_DIRECTIONAL = 2;

    /**
     * Microphone directionality type: cardioid.
     */
    public static final int DIRECTIONALITY_CARDIOID = 3;

    /**
     * Microphone directionality type: hyper cardioid.
     */
    public static final int DIRECTIONALITY_HYPER_CARDIOID = 4;

    /**
     * Microphone directionality type: super cardioid.
     */
    public static final int DIRECTIONALITY_SUPER_CARDIOID = 5;

    /**
     * The channel contains raw audio from this microphone.
     */
    public static final int CHANNEL_MAPPING_DIRECT = 1;

    /**
     * The channel contains processed audio from this microphone and possibly another microphone.
     */
    public static final int CHANNEL_MAPPING_PROCESSED = 2;

    /**
     * Value used for when the group of the microphone is unknown.
     */
    public static final int GROUP_UNKNOWN = -1;

    /**
     * Value used for when the index in the group of the microphone is unknown.
     */
    public static final int INDEX_IN_THE_GROUP_UNKNOWN = -1;

    /**
     * Value used for when the position of the microphone is unknown.
     */
    public static final Coordinate3F POSITION_UNKNOWN = new Coordinate3F(
            -Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE);

    /**
     * Value used for when the orientation of the microphone is unknown.
     */
    public static final Coordinate3F ORIENTATION_UNKNOWN = new Coordinate3F(0.0f, 0.0f, 0.0f);

    /**
     * Value used for when the sensitivity of the microphone is unknown.
     */
    public static final float SENSITIVITY_UNKNOWN = -Float.MAX_VALUE;

    /**
     * Value used for when the SPL of the microphone is unknown. This value could be used when
     * maximum SPL or minimum SPL is unknown.
     */
    public static final float SPL_UNKNOWN = -Float.MAX_VALUE;

    /** @hide */
    @IntDef(flag = true, prefix = { "LOCATION_" }, value = {
            LOCATION_UNKNOWN,
            LOCATION_MAINBODY,
            LOCATION_MAINBODY_MOVABLE,
            LOCATION_PERIPHERAL,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface MicrophoneLocation {}

    /** @hide */
    @IntDef(flag = true, prefix = { "DIRECTIONALITY_" }, value = {
            DIRECTIONALITY_UNKNOWN,
            DIRECTIONALITY_OMNI,
            DIRECTIONALITY_BI_DIRECTIONAL,
            DIRECTIONALITY_CARDIOID,
            DIRECTIONALITY_HYPER_CARDIOID,
            DIRECTIONALITY_SUPER_CARDIOID,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface MicrophoneDirectionality {}

    private Coordinate3F mPosition;
    private Coordinate3F mOrientation;
    private String mDeviceId;
    private String mAddress;
    private List<Pair<Float, Float>> mFrequencyResponse;
    private List<Pair<Integer, Integer>> mChannelMapping;
    private float mMaxSpl;
    private float mMinSpl;
    private float mSensitivity;
    private int mLocation;
    private int mGroup; /* Usually 0 will be used for main body. */
    private int mIndexInTheGroup;
    private int mPortId; /* mPortId will correspond to the id in AudioPort */
    private int mType;
    private int mDirectionality;

    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) {
        mDeviceId = deviceId;
        mType = type;
        mAddress = address;
        mLocation = location;
        mGroup = group;
        mIndexInTheGroup = indexInTheGroup;
        mPosition = position;
        mOrientation = orientation;
        mFrequencyResponse = frequencyResponse;
        mChannelMapping = channelMapping;
        mSensitivity = sensitivity;
        mMaxSpl = maxSpl;
        mMinSpl = minSpl;
        mDirectionality = directionality;
    }

    /**
     * Returns alphanumeric code that uniquely identifies the device.
     *
     * @return the description of the microphone
     */
    public String getDescription() {
        return mDeviceId;
    }

    /**
     * Returns The system unique device ID that corresponds to the id
     * returned by {@link AudioDeviceInfo#getId()}.
     *
     * @return the microphone's id
     */
    public int getId() {
        return mPortId;
    }

    /**
     * @hide
     * Returns the internal device type (e.g AudioSystem.DEVICE_IN_BUILTIN_MIC).
     * The internal device type could be used when getting microphone's port id
     * by matching type and address.
     *
     * @return the internal device type
     */
    public int getInternalDeviceType() {
        return mType;
    }

    /**
     * Returns the device type identifier of the microphone (e.g AudioDeviceInfo.TYPE_BUILTIN_MIC).
     *
     * @return the device type of the microphone
     */
    public int getType() {
        return AudioDeviceInfo.convertInternalDeviceToDeviceType(mType);
    }

    /**
     * Returns The "address" string of the microphone that corresponds to the
     * address returned by {@link AudioDeviceInfo#getAddress()}
     * @return the address of the microphone
     */
    public @NonNull String getAddress() {
        return mAddress;
    }

    /**
     * Returns the location of the microphone. The return value is
     * one of {@link #LOCATION_UNKNOWN}, {@link #LOCATION_MAINBODY},
     * {@link #LOCATION_MAINBODY_MOVABLE}, or {@link #LOCATION_PERIPHERAL}.
     *
     * @return the location of the microphone
     */
    public @MicrophoneLocation int getLocation() {
        return mLocation;
    }

    /**
     * Returns A device group id that can be used to group together microphones on the same
     * peripheral, attachments or logical groups. Main body is usually group 0.
     *
     * @return the group of the microphone or {@link #GROUP_UNKNOWN} if the group is unknown
     */
    public int getGroup() {
        return mGroup;
    }

    /**
     * Returns unique index for device within its group.
     *
     * @return the microphone's index in its group or {@link #INDEX_IN_THE_GROUP_UNKNOWN} if the
     * index in the group is unknown
     */
    public int getIndexInTheGroup() {
        return mIndexInTheGroup;
    }

    /**
     * Returns A {@link Coordinate3F} object that represents the geometric location of microphone
     * in meters, from bottom-left-back corner of appliance. X-axis, Y-axis and Z-axis show
     * as the x, y, z values.
     *
     * @return the geometric location of the microphone or {@link #POSITION_UNKNOWN} if the
     * geometric location is unknown
     */
    public Coordinate3F getPosition() {
        return mPosition;
    }

    /**
     * Returns A {@link Coordinate3F} object that represents the orientation of microphone.
     * X-axis, Y-axis and Z-axis show as the x, y, z value. The orientation will be normalized
     * such as sqrt(x^2 + y^2 + z^2) equals 1.
     *
     * @return the orientation of the microphone or {@link #ORIENTATION_UNKNOWN} if orientation
     * is unknown
     */
    public Coordinate3F getOrientation() {
        return mOrientation;
    }

    /**
     * Returns a {@link android.util.Pair} list of frequency responses.
     * For every {@link android.util.Pair} in the list, the first value represents frequency in Hz,
     * and the second value represents response in dB.
     *
     * @return the frequency response of the microphone
     */
    public List<Pair<Float, Float>> getFrequencyResponse() {
        return mFrequencyResponse;
    }

    /**
     * Returns a {@link android.util.Pair} list for channel mapping, which indicating how this
     * microphone is used by each channels or a capture stream. For each {@link android.util.Pair},
     * the first value is channel index, the second value is channel mapping type, which could be
     * either {@link #CHANNEL_MAPPING_DIRECT} or {@link #CHANNEL_MAPPING_PROCESSED}.
     * If a channel has contributions from more than one microphone, it is likely the HAL
     * did some extra processing to combine the sources, but this is to be inferred by the user.
     * Empty list when the MicrophoneInfo is returned by AudioManager.getMicrophones().
     * At least one entry when the MicrophoneInfo is returned by AudioRecord.getActiveMicrophones().
     *
     * @return a {@link android.util.Pair} list for channel mapping
     */
    public List<Pair<Integer, Integer>> getChannelMapping() {
        return mChannelMapping;
    }

    /**
     * Returns the level in dBFS produced by a 1000Hz tone at 94 dB SPL.
     *
     * @return the sensitivity of the microphone or {@link #SENSITIVITY_UNKNOWN} if the sensitivity
     * is unknown
     */
    public float getSensitivity() {
        return mSensitivity;
    }

    /**
     * Returns the level in dB of the maximum SPL supported by the device at 1000Hz.
     *
     * @return the maximum level in dB or {@link #SPL_UNKNOWN} if maximum SPL is unknown
     */
    public float getMaxSpl() {
        return mMaxSpl;
    }

    /**
     * Returns the level in dB of the minimum SPL that can be registered by the device at 1000Hz.
     *
     * @return the minimum level in dB or {@link #SPL_UNKNOWN} if minimum SPL is unknown
     */
    public float getMinSpl() {
        return mMinSpl;
    }

    /**
     * Returns the directionality of microphone. The return value is one of
     * {@link #DIRECTIONALITY_UNKNOWN}, {@link #DIRECTIONALITY_OMNI},
     * {@link #DIRECTIONALITY_BI_DIRECTIONAL}, {@link #DIRECTIONALITY_CARDIOID},
     * {@link #DIRECTIONALITY_HYPER_CARDIOID}, or {@link #DIRECTIONALITY_SUPER_CARDIOID}.
     *
     * @return the directionality of microphone
     */
    public @MicrophoneDirectionality int getDirectionality() {
        return mDirectionality;
    }

    /**
     * Set the port id for the device.
     * @hide
     */
    public void setId(int portId) {
        mPortId = portId;
    }

    /**
     * Set the channel mapping for the device.
     * @hide
     */
    public void setChannelMapping(List<Pair<Integer, Integer>> channelMapping) {
        mChannelMapping = channelMapping;
    }

    /* A class containing three float value to represent a 3D coordinate */
    public static final class Coordinate3F {
        public final float x;
        public final float y;
        public final float z;

        Coordinate3F(float x, float y, float z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (!(obj instanceof Coordinate3F)) {
                return false;
            }
            Coordinate3F other = (Coordinate3F) obj;
            return this.x == other.x && this.y == other.y && this.z == other.z;
        }
    }
}