Merge "add audioCapabilities to SoundTrigger properties"

This commit is contained in:
Nicholas Ambur
2020-01-11 16:39:55 +00:00
committed by Android (Google) Code Review
15 changed files with 476 additions and 99 deletions

View File

@@ -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;
}
}

View File

@@ -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) + "]";
}
}

View File

@@ -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);
}