405 lines
13 KiB
Java
405 lines
13 KiB
Java
![]() |
/*
|
||
|
* 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.compat.annotation.UnsupportedAppUsage;
|
||
|
import android.os.Build;
|
||
|
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;
|
||
|
|
||
|
@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) {
|
||
|
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. X-axis, Y-axis and Z-axis show as the x, y, z values. For mobile devices, the axes
|
||
|
* originate from the bottom-left-back corner of the appliance. In devices with
|
||
|
* {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE}, axes are defined with respect
|
||
|
* to the vehicle body frame, originating from the center of the vehicle's rear axle.
|
||
|
* @see <a href="https://source.android.com/devices/sensors/sensor-types#auto_axes">auto axes</a>
|
||
|
*
|
||
|
* @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;
|
||
|
}
|
||
|
}
|
||
|
}
|