Add support for getting all available microphones characteristics.

Add MicrophoneInfo to represent the microphone characteristics which
including location, orientation, frequency response, sensitivity,
channel mapping and other useful information.
Add a new API in AudioManager to query all current available
microphones.

Bug: 64038649
Test: Run test and check the print log.
Change-Id: Ie0dbfeeb84b88db426518b93c7bb83c8913bca85
This commit is contained in:
jiabin
2018-01-05 10:23:50 -08:00
parent 0e694a6383
commit c0f4944038
9 changed files with 693 additions and 2 deletions

View File

@@ -21917,6 +21917,7 @@ package android.media {
method public java.util.List<android.media.AudioPlaybackConfiguration> getActivePlaybackConfigurations();
method public java.util.List<android.media.AudioRecordingConfiguration> getActiveRecordingConfigurations();
method public android.media.AudioDeviceInfo[] getDevices(int);
method public java.util.List<android.media.MicrophoneInfo> getMicrophones() throws java.io.IOException;
method public int getMode();
method public java.lang.String getParameters(java.lang.String);
method public java.lang.String getProperty(java.lang.String);
@@ -24411,6 +24412,41 @@ package android.media {
method public float getMediaClockRate();
}
public final class MicrophoneInfo {
method public java.util.List<android.util.Pair<java.lang.Integer, java.lang.Integer>> getChannelMapping();
method public java.lang.String getDescription();
method public int getDirectionality();
method public java.util.List<android.util.Pair<java.lang.Float, java.lang.Float>> getFrequencyResponse();
method public int getGroup();
method public int getId();
method public int getIndexInTheGroup();
method public int getLocation();
method public float getMaxSpl();
method public float getMinSpl();
method public android.media.MicrophoneInfo.Coordinate3F getOrientation();
method public android.media.MicrophoneInfo.Coordinate3F getPosition();
method public float getSensitivity();
method public int getType();
field public static final int CHANNEL_MAPPING_DIRECT = 1; // 0x1
field public static final int CHANNEL_MAPPING_PROCESSED = 2; // 0x2
field public static final int DIRECTIONALITY_BI_DIRECTIONAL = 2; // 0x2
field public static final int DIRECTIONALITY_CARDIOID = 3; // 0x3
field public static final int DIRECTIONALITY_HYPER_CARDIOID = 4; // 0x4
field public static final int DIRECTIONALITY_OMNI = 1; // 0x1
field public static final int DIRECTIONALITY_SUPER_CARDIOID = 5; // 0x5
field public static final int DIRECTIONALITY_UNKNOW = 0; // 0x0
field public static final int LOCATION_MAINBODY = 1; // 0x1
field public static final int LOCATION_MAINBODY_MOVABLE = 2; // 0x2
field public static final int LOCATION_PERIPHERAL = 3; // 0x3
field public static final int LOCATION_UNKNOWN = 0; // 0x0
}
public class MicrophoneInfo.Coordinate3F {
field public final float x;
field public final float y;
field public final float z;
}
public final class NotProvisionedException extends android.media.MediaDrmException {
ctor public NotProvisionedException(java.lang.String);
}

View File

@@ -164,6 +164,7 @@ cc_library_shared {
"android_media_DeviceCallback.cpp",
"android_media_JetPlayer.cpp",
"android_media_MediaMetricsJNI.cpp",
"android_media_MicrophoneInfo.cpp",
"android_media_RemoteDisplay.cpp",
"android_media_ToneGenerator.cpp",
"android_hardware_Camera.cpp",

View File

@@ -104,6 +104,7 @@ extern int register_android_hardware_location_ActivityRecognitionHardware(JNIEnv
extern int register_android_media_AudioRecord(JNIEnv *env);
extern int register_android_media_AudioSystem(JNIEnv *env);
extern int register_android_media_AudioTrack(JNIEnv *env);
extern int register_android_media_MicrophoneInfo(JNIEnv *env);
extern int register_android_media_JetPlayer(JNIEnv *env);
extern int register_android_media_ToneGenerator(JNIEnv *env);
@@ -1457,6 +1458,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_media_AudioSystem),
REG_JNI(register_android_media_AudioTrack),
REG_JNI(register_android_media_JetPlayer),
REG_JNI(register_android_media_MicrophoneInfo),
REG_JNI(register_android_media_RemoteDisplay),
REG_JNI(register_android_media_ToneGenerator),

View File

@@ -21,17 +21,20 @@
#include <utils/Log.h>
#include <sstream>
#include <vector>
#include <jni.h>
#include <nativehelper/JNIHelp.h>
#include "core_jni_helpers.h"
#include <media/AudioSystem.h>
#include <media/AudioPolicy.h>
#include <media/MicrophoneInfo.h>
#include <nativehelper/ScopedLocalRef.h>
#include <system/audio.h>
#include <system/audio_policy.h>
#include "android_media_AudioFormat.h"
#include "android_media_AudioErrors.h"
#include "android_media_MicrophoneInfo.h"
// ----------------------------------------------------------------------------
@@ -143,7 +146,6 @@ static struct {
jfieldID mSource;
} gAudioAttributesFields;
static const char* const kEventHandlerClassPathName =
"android/media/AudioPortEventHandler";
static struct {
@@ -1158,7 +1160,6 @@ exit:
return jStatus;
}
static jint
android_media_AudioSystem_listAudioPorts(JNIEnv *env, jobject clazz,
jobject jPorts, jintArray jGeneration)
@@ -1789,6 +1790,45 @@ android_media_AudioSystem_isOffloadSupported(JNIEnv *env, jobject thiz,
return AudioSystem::isOffloadSupported(format);
}
static jint
android_media_AudioSystem_getMicrophones(JNIEnv *env, jobject thiz, jobject jMicrophonesInfo)
{
ALOGV("getMicrophones");
if (jMicrophonesInfo == NULL) {
ALOGE("jMicrophonesInfo NULL MicrophoneInfo ArrayList");
return (jint)AUDIO_JAVA_BAD_VALUE;
}
if (!env->IsInstanceOf(jMicrophonesInfo, gArrayListClass)) {
ALOGE("getMicrophones not an arraylist");
return (jint)AUDIO_JAVA_BAD_VALUE;
}
jint jStatus;
std::vector<media::MicrophoneInfo> microphones;
status_t status = AudioSystem::getMicrophones(&microphones);
if (status != NO_ERROR) {
ALOGE_IF(status != NO_ERROR, "AudioSystem::getMicrophones error %d", status);
jStatus = nativeToJavaStatus(status);
return jStatus;
}
if (microphones.size() == 0) {
jStatus = (jint)AUDIO_JAVA_SUCCESS;
return jStatus;
}
for (size_t i = 0; i < microphones.size(); i++) {
jobject jMicrophoneInfo;
jStatus = convertMicrophoneInfoFromNative(env, &jMicrophoneInfo, &microphones[i]);
if (jStatus != AUDIO_JAVA_SUCCESS) {
return jStatus;
}
env->CallBooleanMethod(jMicrophonesInfo, gArrayListMethods.add, jMicrophoneInfo);
env->DeleteLocalRef(jMicrophoneInfo);
}
return jStatus;
}
// ----------------------------------------------------------------------------
static const JNINativeMethod gMethods[] = {
@@ -1843,6 +1883,7 @@ static const JNINativeMethod gMethods[] = {
{"systemReady", "()I", (void *)android_media_AudioSystem_systemReady},
{"getStreamVolumeDB", "(III)F", (void *)android_media_AudioSystem_getStreamVolumeDB},
{"native_is_offload_supported", "(IIII)Z", (void *)android_media_AudioSystem_isOffloadSupported},
{"getMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_AudioSystem_getMicrophones},
};

View File

@@ -0,0 +1,187 @@
/*
* 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.
*/
#include "android_media_MicrophoneInfo.h"
#include "android_media_AudioErrors.h"
#include "core_jni_helpers.h"
using namespace android;
static jclass gArrayListClass;
static jmethodID gArrayListCstor;
static struct {
jmethodID add;
} gArrayListMethods;
static jclass gFloatClass;
static jmethodID gFloatCstor;
static jclass gFloatArrayClass;
static jclass gIntegerClass;
static jmethodID gIntegerCstor;
static jclass gMicrophoneInfoClass;
static jmethodID gMicrophoneInfoCstor;
static jclass gMicrophoneInfoCoordinateClass;
static jmethodID gMicrophoneInfoCoordinateCstor;
static jclass gPairClass;
static jmethodID gPairCstor;
namespace android {
jint convertMicrophoneInfoFromNative(JNIEnv *env, jobject *jMicrophoneInfo,
const media::MicrophoneInfo *microphoneInfo)
{
jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
jstring jDeviceId = NULL;
jstring jAddress = NULL;
jobject jGeometricLocation = NULL;
jobject jOrientation = NULL;
jobject jFrequencyResponses = NULL;
jobject jChannelMappings = NULL;
jDeviceId = env->NewStringUTF(String8(microphoneInfo->getDeviceId()).string());
jAddress = env->NewStringUTF(String8(microphoneInfo->getAddress()).string());
if (microphoneInfo->getGeometricLocation().size() != 3 ||
microphoneInfo->getOrientation().size() != 3) {
jStatus = nativeToJavaStatus(BAD_VALUE);
goto exit;
}
jGeometricLocation = env->NewObject(gMicrophoneInfoCoordinateClass,
gMicrophoneInfoCoordinateCstor,
NULL,
microphoneInfo->getGeometricLocation()[0],
microphoneInfo->getGeometricLocation()[1],
microphoneInfo->getGeometricLocation()[2]);
jOrientation = env->NewObject(gMicrophoneInfoCoordinateClass,
gMicrophoneInfoCoordinateCstor,
NULL,
microphoneInfo->getOrientation()[0],
microphoneInfo->getOrientation()[1],
microphoneInfo->getOrientation()[2]);
// Create a list of Pair for frequency response.
if (microphoneInfo->getFrequencyResponses().size() != 2 ||
microphoneInfo->getFrequencyResponses()[0].size() !=
microphoneInfo->getFrequencyResponses()[1].size()) {
jStatus = nativeToJavaStatus(BAD_VALUE);
goto exit;
}
jFrequencyResponses = env->NewObject(gArrayListClass, gArrayListCstor);
for (size_t i = 0; i < microphoneInfo->getFrequencyResponses()[0].size(); i++) {
jobject jFrequency = env->NewObject(gFloatClass, gFloatCstor,
microphoneInfo->getFrequencyResponses()[0][i]);
jobject jResponse = env->NewObject(gFloatClass, gFloatCstor,
microphoneInfo->getFrequencyResponses()[1][i]);
jobject jFrequencyResponse = env->NewObject(gPairClass, gPairCstor, jFrequency, jResponse);
env->CallBooleanMethod(jFrequencyResponses, gArrayListMethods.add, jFrequencyResponse);
env->DeleteLocalRef(jFrequency);
env->DeleteLocalRef(jResponse);
env->DeleteLocalRef(jFrequencyResponse);
}
// Create a list of Pair for channel mapping.
if (microphoneInfo->getChannelMapping().size() != AUDIO_CHANNEL_COUNT_MAX) {
jStatus = nativeToJavaStatus(BAD_VALUE);
goto exit;
}
jChannelMappings = env->NewObject(gArrayListClass, gArrayListCstor);
for (size_t i = 0; i < microphoneInfo->getChannelMapping().size(); i++) {
int channelMappingType = microphoneInfo->getChannelMapping()[i];
if (channelMappingType != AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED) {
jobject jChannelIndex = env->NewObject(gIntegerClass, gIntegerCstor, i);
jobject jChannelMappingType = env->NewObject(gIntegerClass, gIntegerCstor,
channelMappingType);
jobject jChannelMapping = env->NewObject(gPairClass, gPairCstor,
jChannelIndex, jChannelMappingType);
env->CallBooleanMethod(jChannelMappings, gArrayListMethods.add, jChannelMapping);
env->DeleteLocalRef(jChannelIndex);
env->DeleteLocalRef(jChannelMappingType);
env->DeleteLocalRef(jChannelMapping);
}
}
*jMicrophoneInfo = env->NewObject(gMicrophoneInfoClass, gMicrophoneInfoCstor, jDeviceId,
microphoneInfo->getType(), jAddress,
microphoneInfo->getDeviceLocation(),
microphoneInfo->getDeviceGroup(),
microphoneInfo->getIndexInTheGroup(),
jGeometricLocation, jOrientation,
jFrequencyResponses, jChannelMappings,
microphoneInfo->getSensitivity(),
microphoneInfo->getMaxSpl(),
microphoneInfo->getMinSpl(),
microphoneInfo->getDirectionality());
exit:
if (jDeviceId != NULL) {
env->DeleteLocalRef(jDeviceId);
}
if (jAddress != NULL) {
env->DeleteLocalRef(jAddress);
}
if (jFrequencyResponses != NULL) {
env->DeleteLocalRef(jFrequencyResponses);
}
if (jChannelMappings != NULL) {
env->DeleteLocalRef(jChannelMappings);
}
if (jGeometricLocation != NULL) {
env->DeleteLocalRef(jGeometricLocation);
}
if (jOrientation != NULL) {
env->DeleteLocalRef(jOrientation);
}
return jStatus;
}
}
int register_android_media_MicrophoneInfo(JNIEnv *env)
{
jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
gArrayListCstor = GetMethodIDOrDie(env, arrayListClass, "<init>", "()V");
gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
jclass floatClass = FindClassOrDie(env, "java/lang/Float");
gFloatClass = MakeGlobalRefOrDie(env, floatClass);
gFloatCstor = GetMethodIDOrDie(env, floatClass, "<init>", "(F)V");
jclass floatArrayClass = FindClassOrDie(env, "[F");
gFloatArrayClass = MakeGlobalRefOrDie(env, floatArrayClass);
jclass integerClass = FindClassOrDie(env, "java/lang/Integer");
gIntegerClass = MakeGlobalRefOrDie(env, integerClass);
gIntegerCstor = GetMethodIDOrDie(env, integerClass, "<init>", "(I)V");
jclass microphoneInfoClass = FindClassOrDie(env, "android/media/MicrophoneInfo");
gMicrophoneInfoClass = MakeGlobalRefOrDie(env, microphoneInfoClass);
gMicrophoneInfoCstor = GetMethodIDOrDie(env, microphoneInfoClass, "<init>",
"(Ljava/lang/String;ILjava/lang/String;IIILandroid/media/MicrophoneInfo$Coordinate3F;Landroid/media/MicrophoneInfo$Coordinate3F;Ljava/util/List;Ljava/util/List;FFFI)V");
jclass microphoneInfoCoordinateClass = FindClassOrDie(
env, "android/media/MicrophoneInfo$Coordinate3F");
gMicrophoneInfoCoordinateClass = MakeGlobalRefOrDie(env, microphoneInfoCoordinateClass);
gMicrophoneInfoCoordinateCstor = GetMethodIDOrDie(env, microphoneInfoCoordinateClass, "<init>",
"(Landroid/media/MicrophoneInfo;FFF)V");
jclass pairClass = FindClassOrDie(env, "android/util/Pair");
gPairClass = MakeGlobalRefOrDie(env, pairClass);
gPairCstor = GetMethodIDOrDie(env, pairClass, "<init>", "(Ljava/lang/Object;Ljava/lang/Object;)V");
return 0;
}

View File

@@ -0,0 +1,33 @@
/*
* 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.
*/
#ifndef ANDROID_MEDIA_MICROPHONEINFO_H
#define ANDROID_MEDIA_MICROPHONEINFO_H
#include <system/audio.h>
#include <media/MicrophoneInfo.h>
#include "jni.h"
namespace android {
// Conversion from C++ MicrophoneInfo object to Java MicrophoneInfo object
extern jint convertMicrophoneInfoFromNative(JNIEnv *env, jobject *jMicrophoneInfo,
const media::MicrophoneInfo *microphoneInfo);
} // namespace android
#endif

View File

@@ -48,11 +48,13 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
import android.view.KeyEvent;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -4566,6 +4568,51 @@ public class AudioManager {
}
}
/**
* Set port id for microphones by matching device type and address.
* @hide
*/
public static void setPortIdForMicrophones(ArrayList<MicrophoneInfo> microphones) {
AudioDeviceInfo[] devices = getDevicesStatic(AudioManager.GET_DEVICES_INPUTS);
for (int i = microphones.size() - 1; i >= 0; i--) {
boolean foundPortId = false;
for (AudioDeviceInfo device : devices) {
if (device.getPort().type() == microphones.get(i).getInternalDeviceType()
&& TextUtils.equals(device.getAddress(), microphones.get(i).getAddress())) {
microphones.get(i).setId(device.getId());
foundPortId = true;
break;
}
}
if (!foundPortId) {
Log.i(TAG, "Failed to find port id for device with type:"
+ microphones.get(i).getType() + " address:"
+ microphones.get(i).getAddress());
microphones.remove(i);
}
}
}
/**
* Returns a list of {@link MicrophoneInfo} that corresponds to the characteristics
* of all available microphones. The list is empty when no microphones are available
* on the device. An error during the query will result in an IOException being thrown.
*
* @return a list that contains all microphones' characteristics
* @throws IOException if an error occurs.
*/
public List<MicrophoneInfo> getMicrophones() throws IOException {
ArrayList<MicrophoneInfo> microphones = new ArrayList<MicrophoneInfo>();
int status = AudioSystem.getMicrophones(microphones);
if (status != AudioManager.SUCCESS) {
// fail and bail!
Log.e(TAG, "getMicrophones failed:" + status);
return new ArrayList<MicrophoneInfo>(); // Always return a list.
}
setPortIdForMicrophones(microphones);
return microphones;
}
// Since we need to calculate the changes since THE LAST NOTIFICATION, and not since the
// (unpredictable) last time updateAudioPortCache() was called by someone, keep a list
// of the ports that exist at the time of the last notification.

View File

@@ -827,6 +827,8 @@ public class AudioSystem
private static native boolean native_is_offload_supported(int encoding, int sampleRate,
int channelMask, int channelIndexMask);
public static native int getMicrophones(ArrayList<MicrophoneInfo> microphonesInfo);
// Items shared with audio service
/**

View File

@@ -0,0 +1,342 @@
/*
* 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.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_UNKNOW = 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;
/** @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_UNKNOW,
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);
}
/**
* @hide
* Returns The "address" string of the microphone that corresponds to the
* address returned by {@link AudioDeviceInfo#getAddress()}
* @return the address of the microphone
*/
public 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
*/
public int getGroup() {
return mGroup;
}
/**
* Returns unique index for device within its group.
*
* @return the microphone's index in its group
*/
public int getIndexInTheGroup() {
return mIndexInTheGroup;
}
/**
* Returns A {@link Coordinate3F} object that represents the geometric location of microphone
* in meters, from botton-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
*/
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
*/
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
*/
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
*/
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
*/
public float getMinSpl() {
return mMinSpl;
}
/**
* Returns the directionality of microphone. The return value is one of
* {@link #DIRECTIONALITY_UNKNOW}, {@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;
}
/* A class containing three float value to represent a 3D coordinate */
public 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;
}
}
}