Merge "add audioCapabilities to SoundTrigger properties"
This commit is contained in:
committed by
Android (Google) Code Review
commit
55c162edcd
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
|
||||
import android.hardware.soundtrigger.ModelParams;
|
||||
import android.media.AudioFormat;
|
||||
import android.media.audio.common.AudioConfig;
|
||||
import android.media.soundtrigger_middleware.AudioCapabilities;
|
||||
import android.media.soundtrigger_middleware.ConfidenceLevel;
|
||||
import android.media.soundtrigger_middleware.ModelParameterRange;
|
||||
import android.media.soundtrigger_middleware.Phrase;
|
||||
@@ -56,7 +57,8 @@ class ConversionUtil {
|
||||
properties.maxBufferMs,
|
||||
properties.concurrentCapture,
|
||||
properties.powerConsumptionMw,
|
||||
properties.triggerInEvent
|
||||
properties.triggerInEvent,
|
||||
aidl2apiAudioCapabilities(properties.audioCapabilities)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -145,6 +147,7 @@ class ConversionUtil {
|
||||
apiConfig.keyphrases[i]);
|
||||
}
|
||||
aidlConfig.data = Arrays.copyOf(apiConfig.data, apiConfig.data.length);
|
||||
aidlConfig.audioCapabilities = api2aidlAudioCapabilities(apiConfig.audioCapabilities);
|
||||
return aidlConfig;
|
||||
}
|
||||
|
||||
@@ -326,4 +329,26 @@ class ConversionUtil {
|
||||
}
|
||||
return new SoundTrigger.ModelParamRange(aidlRange.minInclusive, aidlRange.maxInclusive);
|
||||
}
|
||||
|
||||
public static int aidl2apiAudioCapabilities(int aidlCapabilities) {
|
||||
int result = 0;
|
||||
if ((aidlCapabilities & AudioCapabilities.ECHO_CANCELLATION) != 0) {
|
||||
result |= SoundTrigger.ModuleProperties.CAPABILITY_ECHO_CANCELLATION;
|
||||
}
|
||||
if ((aidlCapabilities & AudioCapabilities.NOISE_SUPPRESSION) != 0) {
|
||||
result |= SoundTrigger.ModuleProperties.CAPABILITY_NOISE_SUPPRESSION;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int api2aidlAudioCapabilities(int apiCapabilities) {
|
||||
int result = 0;
|
||||
if ((apiCapabilities & SoundTrigger.ModuleProperties.CAPABILITY_ECHO_CANCELLATION) != 0) {
|
||||
result |= AudioCapabilities.ECHO_CANCELLATION;
|
||||
}
|
||||
if ((apiCapabilities & SoundTrigger.ModuleProperties.CAPABILITY_NOISE_SUPPRESSION) != 0) {
|
||||
result |= AudioCapabilities.NOISE_SUPPRESSION;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import static android.system.OsConstants.EPIPE;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SystemApi;
|
||||
@@ -42,6 +43,8 @@ import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.UUID;
|
||||
@@ -83,6 +86,30 @@ public class SoundTrigger {
|
||||
*
|
||||
****************************************************************************/
|
||||
public static final class ModuleProperties implements Parcelable {
|
||||
|
||||
/**
|
||||
* Bit field values of AudioCapabilities supported by the implemented HAL
|
||||
* driver.
|
||||
* @hide
|
||||
*/
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(flag = true, prefix = { "AUDIO_CAPABILITY_" }, value = {
|
||||
CAPABILITY_ECHO_CANCELLATION,
|
||||
CAPABILITY_NOISE_SUPPRESSION
|
||||
})
|
||||
public @interface AudioCapabilities {}
|
||||
|
||||
/**
|
||||
* If set the underlying module supports AEC.
|
||||
* Describes bit field {@link ModuleProperties#audioCapabilities}
|
||||
*/
|
||||
public static final int CAPABILITY_ECHO_CANCELLATION = 0x1;
|
||||
/**
|
||||
* If set, the underlying module supports noise suppression.
|
||||
* Describes bit field {@link ModuleProperties#audioCapabilities}
|
||||
*/
|
||||
public static final int CAPABILITY_NOISE_SUPPRESSION = 0x2;
|
||||
|
||||
/** Unique module ID provided by the native service */
|
||||
public final int id;
|
||||
|
||||
@@ -137,12 +164,19 @@ public class SoundTrigger {
|
||||
* recognition callback event */
|
||||
public final boolean returnsTriggerInEvent;
|
||||
|
||||
/**
|
||||
* Bit field encoding of the AudioCapabilities
|
||||
* supported by the firmware.
|
||||
*/
|
||||
@AudioCapabilities
|
||||
public final int audioCapabilities;
|
||||
|
||||
ModuleProperties(int id, @NonNull String implementor, @NonNull String description,
|
||||
@NonNull String uuid, int version, @NonNull String supportedModelArch,
|
||||
int maxSoundModels, int maxKeyphrases, int maxUsers, int recognitionModes,
|
||||
boolean supportsCaptureTransition, int maxBufferMs,
|
||||
boolean supportsConcurrentCapture, int powerConsumptionMw,
|
||||
boolean returnsTriggerInEvent) {
|
||||
boolean returnsTriggerInEvent, int audioCapabilities) {
|
||||
this.id = id;
|
||||
this.implementor = requireNonNull(implementor);
|
||||
this.description = requireNonNull(description);
|
||||
@@ -158,6 +192,7 @@ public class SoundTrigger {
|
||||
this.supportsConcurrentCapture = supportsConcurrentCapture;
|
||||
this.powerConsumptionMw = powerConsumptionMw;
|
||||
this.returnsTriggerInEvent = returnsTriggerInEvent;
|
||||
this.audioCapabilities = audioCapabilities;
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<ModuleProperties> CREATOR
|
||||
@@ -187,10 +222,11 @@ public class SoundTrigger {
|
||||
boolean supportsConcurrentCapture = in.readByte() == 1;
|
||||
int powerConsumptionMw = in.readInt();
|
||||
boolean returnsTriggerInEvent = in.readByte() == 1;
|
||||
int audioCapabilities = in.readInt();
|
||||
return new ModuleProperties(id, implementor, description, uuid, version,
|
||||
supportedModelArch, maxSoundModels, maxKeyphrases, maxUsers, recognitionModes,
|
||||
supportsCaptureTransition, maxBufferMs, supportsConcurrentCapture,
|
||||
powerConsumptionMw, returnsTriggerInEvent);
|
||||
powerConsumptionMw, returnsTriggerInEvent, audioCapabilities);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -210,6 +246,7 @@ public class SoundTrigger {
|
||||
dest.writeByte((byte) (supportsConcurrentCapture ? 1 : 0));
|
||||
dest.writeInt(powerConsumptionMw);
|
||||
dest.writeByte((byte) (returnsTriggerInEvent ? 1 : 0));
|
||||
dest.writeInt(audioCapabilities);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -227,7 +264,8 @@ public class SoundTrigger {
|
||||
+ ", supportsCaptureTransition=" + supportsCaptureTransition + ", maxBufferMs="
|
||||
+ maxBufferMs + ", supportsConcurrentCapture=" + supportsConcurrentCapture
|
||||
+ ", powerConsumptionMw=" + powerConsumptionMw
|
||||
+ ", returnsTriggerInEvent=" + returnsTriggerInEvent + "]";
|
||||
+ ", returnsTriggerInEvent=" + returnsTriggerInEvent
|
||||
+ ", audioCapabilities=" + audioCapabilities + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1049,13 +1087,27 @@ public class SoundTrigger {
|
||||
@NonNull
|
||||
public final byte[] data;
|
||||
|
||||
@UnsupportedAppUsage
|
||||
/**
|
||||
* Bit field encoding of the AudioCapabilities
|
||||
* supported by the firmware.
|
||||
*/
|
||||
@ModuleProperties.AudioCapabilities
|
||||
public final int audioCapabilities;
|
||||
|
||||
public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
|
||||
@Nullable KeyphraseRecognitionExtra[] keyphrases, @Nullable byte[] data) {
|
||||
@Nullable KeyphraseRecognitionExtra[] keyphrases, @Nullable byte[] data,
|
||||
int audioCapabilities) {
|
||||
this.captureRequested = captureRequested;
|
||||
this.allowMultipleTriggers = allowMultipleTriggers;
|
||||
this.keyphrases = keyphrases != null ? keyphrases : new KeyphraseRecognitionExtra[0];
|
||||
this.data = data != null ? data : new byte[0];
|
||||
this.audioCapabilities = audioCapabilities;
|
||||
}
|
||||
|
||||
@UnsupportedAppUsage
|
||||
public RecognitionConfig(boolean captureRequested, boolean allowMultipleTriggers,
|
||||
@Nullable KeyphraseRecognitionExtra[] keyphrases, @Nullable byte[] data) {
|
||||
this(captureRequested, allowMultipleTriggers, keyphrases, data, 0);
|
||||
}
|
||||
|
||||
public static final @android.annotation.NonNull Parcelable.Creator<RecognitionConfig> CREATOR
|
||||
@@ -1075,7 +1127,9 @@ public class SoundTrigger {
|
||||
KeyphraseRecognitionExtra[] keyphrases =
|
||||
in.createTypedArray(KeyphraseRecognitionExtra.CREATOR);
|
||||
byte[] data = in.readBlob();
|
||||
return new RecognitionConfig(captureRequested, allowMultipleTriggers, keyphrases, data);
|
||||
int audioCapabilities = in.readInt();
|
||||
return new RecognitionConfig(captureRequested, allowMultipleTriggers, keyphrases, data,
|
||||
audioCapabilities);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1084,6 +1138,7 @@ public class SoundTrigger {
|
||||
dest.writeByte((byte) (allowMultipleTriggers ? 1 : 0));
|
||||
dest.writeTypedArray(keyphrases, flags);
|
||||
dest.writeBlob(data);
|
||||
dest.writeInt(audioCapabilities);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1095,7 +1150,8 @@ public class SoundTrigger {
|
||||
public String toString() {
|
||||
return "RecognitionConfig [captureRequested=" + captureRequested
|
||||
+ ", allowMultipleTriggers=" + allowMultipleTriggers + ", keyphrases="
|
||||
+ Arrays.toString(keyphrases) + ", data=" + Arrays.toString(data) + "]";
|
||||
+ Arrays.toString(keyphrases) + ", data=" + Arrays.toString(data)
|
||||
+ ", audioCapabilities=" + Integer.toHexString(audioCapabilities) + "]";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,9 @@ public class AlwaysOnHotwordDetector {
|
||||
@IntDef(flag = true, prefix = { "RECOGNITION_FLAG_" }, value = {
|
||||
RECOGNITION_FLAG_NONE,
|
||||
RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO,
|
||||
RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS
|
||||
RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS,
|
||||
RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION,
|
||||
RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION,
|
||||
})
|
||||
public @interface RecognitionFlags {}
|
||||
|
||||
@@ -144,6 +146,26 @@ public class AlwaysOnHotwordDetector {
|
||||
*/
|
||||
public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 0x2;
|
||||
|
||||
/**
|
||||
* Audio capabilities flag for {@link #startRecognition(int)} that indicates
|
||||
* if the underlying recognition should use AEC.
|
||||
* This capability may or may not be supported by the system, and support can be queried
|
||||
* by calling {@link #getSupportedAudioCapabilities()}. The corresponding capabilities field for
|
||||
* this flag is {@link #AUDIO_CAPABILITY_ECHO_CANCELLATION}. If this flag is passed without the
|
||||
* audio capability supported, there will be no audio effect applied.
|
||||
*/
|
||||
public static final int RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION = 0x4;
|
||||
|
||||
/**
|
||||
* Audio capabilities flag for {@link #startRecognition(int)} that indicates
|
||||
* if the underlying recognition should use noise suppression.
|
||||
* This capability may or may not be supported by the system, and support can be queried
|
||||
* by calling {@link #getSupportedAudioCapabilities()}. The corresponding capabilities field for
|
||||
* this flag is {@link #AUDIO_CAPABILITY_NOISE_SUPPRESSION}. If this flag is passed without the
|
||||
* audio capability supported, there will be no audio effect applied.
|
||||
*/
|
||||
public static final int RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION = 0x8;
|
||||
|
||||
//---- Recognition mode flags. Return codes for getSupportedRecognitionModes() ----//
|
||||
// Must be kept in sync with the related attribute defined as searchKeyphraseRecognitionFlags.
|
||||
|
||||
@@ -168,6 +190,30 @@ public class AlwaysOnHotwordDetector {
|
||||
public static final int RECOGNITION_MODE_USER_IDENTIFICATION
|
||||
= SoundTrigger.RECOGNITION_MODE_USER_IDENTIFICATION;
|
||||
|
||||
//-- Audio capabilities. Values in returned bit field for getSupportedAudioCapabilities() --//
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(flag = true, prefix = { "AUDIO_CAPABILITY_" }, value = {
|
||||
AUDIO_CAPABILITY_ECHO_CANCELLATION,
|
||||
AUDIO_CAPABILITY_NOISE_SUPPRESSION,
|
||||
})
|
||||
public @interface AudioCapabilities {}
|
||||
|
||||
/**
|
||||
* If set the underlying module supports AEC.
|
||||
* Returned by {@link #getSupportedAudioCapabilities()}
|
||||
*/
|
||||
public static final int AUDIO_CAPABILITY_ECHO_CANCELLATION =
|
||||
SoundTrigger.ModuleProperties.CAPABILITY_ECHO_CANCELLATION;
|
||||
|
||||
/**
|
||||
* If set, the underlying module supports noise suppression.
|
||||
* Returned by {@link #getSupportedAudioCapabilities()}
|
||||
*/
|
||||
public static final int AUDIO_CAPABILITY_NOISE_SUPPRESSION =
|
||||
SoundTrigger.ModuleProperties.CAPABILITY_NOISE_SUPPRESSION;
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef(flag = true, prefix = { "MODEL_PARAM_" }, value = {
|
||||
@@ -447,6 +493,37 @@ public class AlwaysOnHotwordDetector {
|
||||
return mKeyphraseMetadata.recognitionModeFlags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the audio capabilities supported by the platform which can be enabled when
|
||||
* starting a recognition.
|
||||
*
|
||||
* @see #AUDIO_CAPABILITY_ECHO_CANCELLATION
|
||||
* @see #AUDIO_CAPABILITY_NOISE_SUPPRESSION
|
||||
*
|
||||
* @return Bit field encoding of the AudioCapabilities supported.
|
||||
*/
|
||||
@AudioCapabilities
|
||||
public int getSupportedAudioCapabilities() {
|
||||
if (DBG) Slog.d(TAG, "getSupportedAudioCapabilities()");
|
||||
synchronized (mLock) {
|
||||
return getSupportedAudioCapabilitiesLocked();
|
||||
}
|
||||
}
|
||||
|
||||
private int getSupportedAudioCapabilitiesLocked() {
|
||||
try {
|
||||
ModuleProperties properties =
|
||||
mModelManagementService.getDspModuleProperties(mVoiceInteractionService);
|
||||
if (properties != null) {
|
||||
return properties.audioCapabilities;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts recognition for the associated keyphrase.
|
||||
*
|
||||
@@ -711,12 +788,21 @@ public class AlwaysOnHotwordDetector {
|
||||
(recognitionFlags&RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO) != 0;
|
||||
boolean allowMultipleTriggers =
|
||||
(recognitionFlags&RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS) != 0;
|
||||
|
||||
int audioCapabilities = 0;
|
||||
if ((recognitionFlags & RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION) != 0) {
|
||||
audioCapabilities |= AUDIO_CAPABILITY_ECHO_CANCELLATION;
|
||||
}
|
||||
if ((recognitionFlags & RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION) != 0) {
|
||||
audioCapabilities |= AUDIO_CAPABILITY_NOISE_SUPPRESSION;
|
||||
}
|
||||
|
||||
int code = STATUS_ERROR;
|
||||
try {
|
||||
code = mModelManagementService.startRecognition(mVoiceInteractionService,
|
||||
mKeyphraseMetadata.id, mLocale.toLanguageTag(), mInternalCallback,
|
||||
new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
|
||||
recognitionExtra, null /* additional data */));
|
||||
recognitionExtra, null /* additional data */, audioCapabilities));
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "RemoteException in startRecognition!", e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user