mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-02 06:22:53 +00:00
Merge changes from topic "processing_effects" am: a46044e8d3 am: 7633167164
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/2363493 Change-Id: I90e065b3d670df05add0eaabc52bdd78b8d67ff1 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -223,6 +223,8 @@ aidl_interface {
|
||||
"android.hardware.audio_defaults",
|
||||
],
|
||||
srcs: [
|
||||
"android/hardware/audio/effect/AcousticEchoCanceler.aidl",
|
||||
"android/hardware/audio/effect/AutomaticGainControl.aidl",
|
||||
"android/hardware/audio/effect/BassBoost.aidl",
|
||||
"android/hardware/audio/effect/Capability.aidl",
|
||||
"android/hardware/audio/effect/CommandId.aidl",
|
||||
@@ -236,6 +238,7 @@ aidl_interface {
|
||||
"android/hardware/audio/effect/IEffect.aidl",
|
||||
"android/hardware/audio/effect/IFactory.aidl",
|
||||
"android/hardware/audio/effect/LoudnessEnhancer.aidl",
|
||||
"android/hardware/audio/effect/NoiseSuppression.aidl",
|
||||
"android/hardware/audio/effect/Parameter.aidl",
|
||||
"android/hardware/audio/effect/PresetReverb.aidl",
|
||||
"android/hardware/audio/effect/Processing.aidl",
|
||||
|
||||
@@ -23,6 +23,15 @@
|
||||
},
|
||||
{
|
||||
"name": "VtsHalVisualizerTargetTest"
|
||||
},
|
||||
{
|
||||
"name": "VtsHalAECTargetTest"
|
||||
},
|
||||
{
|
||||
"name": "VtsHalAGCTargetTest"
|
||||
},
|
||||
{
|
||||
"name": "VtsHalNSTargetTest"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.audio.effect;
|
||||
@VintfStability
|
||||
union AcousticEchoCanceler {
|
||||
android.hardware.audio.effect.VendorExtension vendor;
|
||||
int echoDelayUs;
|
||||
boolean mobileMode;
|
||||
@VintfStability
|
||||
union Id {
|
||||
int vendorExtensionTag;
|
||||
android.hardware.audio.effect.AcousticEchoCanceler.Tag commonTag;
|
||||
}
|
||||
@VintfStability
|
||||
parcelable Capability {
|
||||
ParcelableHolder extension;
|
||||
int maxEchoDelayUs;
|
||||
boolean supportMobileMode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.audio.effect;
|
||||
@VintfStability
|
||||
union AutomaticGainControl {
|
||||
android.hardware.audio.effect.VendorExtension vendor;
|
||||
int fixedDigitalGainMb;
|
||||
android.hardware.audio.effect.AutomaticGainControl.LevelEstimator levelEstimator;
|
||||
int saturationMarginMb;
|
||||
@VintfStability
|
||||
union Id {
|
||||
int vendorExtensionTag;
|
||||
android.hardware.audio.effect.AutomaticGainControl.Tag commonTag;
|
||||
}
|
||||
@VintfStability
|
||||
parcelable Capability {
|
||||
ParcelableHolder extension;
|
||||
int maxFixedDigitalGainMb;
|
||||
int maxSaturationMarginMb;
|
||||
}
|
||||
@Backing(type="int") @VintfStability
|
||||
enum LevelEstimator {
|
||||
RMS = 0,
|
||||
PEAK = 1,
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,8 @@ package android.hardware.audio.effect;
|
||||
@VintfStability
|
||||
union Capability {
|
||||
android.hardware.audio.effect.VendorExtension vendorExtension;
|
||||
android.hardware.audio.effect.AcousticEchoCanceler.Capability acousticEchoCanceler;
|
||||
android.hardware.audio.effect.AutomaticGainControl.Capability automaticGainControl;
|
||||
android.hardware.audio.effect.BassBoost.Capability bassBoost;
|
||||
android.hardware.audio.effect.Downmix.Capability downmix;
|
||||
android.hardware.audio.effect.DynamicsProcessing.Capability dynamicsProcessing;
|
||||
@@ -42,6 +44,7 @@ union Capability {
|
||||
android.hardware.audio.effect.Equalizer.Capability equalizer;
|
||||
android.hardware.audio.effect.HapticGenerator.Capability hapticGenerator;
|
||||
android.hardware.audio.effect.LoudnessEnhancer.Capability loudnessEnhancer;
|
||||
android.hardware.audio.effect.NoiseSuppression.Capability noiseSuppression;
|
||||
android.hardware.audio.effect.PresetReverb.Capability presetReverb;
|
||||
android.hardware.audio.effect.Virtualizer.Capability virtualizer;
|
||||
android.hardware.audio.effect.Visualizer.Capability visualizer;
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
|
||||
// two cases:
|
||||
// 1). this is a frozen version file - do not edit this in any case.
|
||||
// 2). this is a 'current' file. If you make a backwards compatible change to
|
||||
// the interface (from the latest frozen version), the build system will
|
||||
// prompt you to update this file with `m <name>-update-api`.
|
||||
//
|
||||
// You must not make a backward incompatible change to any AIDL file built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.audio.effect;
|
||||
@VintfStability
|
||||
union NoiseSuppression {
|
||||
android.hardware.audio.effect.VendorExtension vendor;
|
||||
android.hardware.audio.effect.NoiseSuppression.Level level;
|
||||
@VintfStability
|
||||
union Id {
|
||||
int vendorExtensionTag;
|
||||
android.hardware.audio.effect.NoiseSuppression.Tag commonTag;
|
||||
}
|
||||
@VintfStability
|
||||
parcelable Capability {
|
||||
ParcelableHolder extension;
|
||||
}
|
||||
@Backing(type="int") @VintfStability
|
||||
enum Level {
|
||||
LOW = 0,
|
||||
MEDIUM = 1,
|
||||
HIGH = 2,
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,8 @@ union Parameter {
|
||||
@VintfStability
|
||||
union Id {
|
||||
int vendorEffectTag;
|
||||
android.hardware.audio.effect.AcousticEchoCanceler.Id acousticEchoCancelerTag;
|
||||
android.hardware.audio.effect.AutomaticGainControl.Id automaticGainControlTag;
|
||||
android.hardware.audio.effect.BassBoost.Id bassBoostTag;
|
||||
android.hardware.audio.effect.Downmix.Id downmixTag;
|
||||
android.hardware.audio.effect.DynamicsProcessing.Id dynamicsProcessingTag;
|
||||
@@ -50,6 +52,7 @@ union Parameter {
|
||||
android.hardware.audio.effect.Equalizer.Id equalizerTag;
|
||||
android.hardware.audio.effect.HapticGenerator.Id hapticGeneratorTag;
|
||||
android.hardware.audio.effect.LoudnessEnhancer.Id loudnessEnhancerTag;
|
||||
android.hardware.audio.effect.NoiseSuppression.Id noiseSuppressionTag;
|
||||
android.hardware.audio.effect.PresetReverb.Id presetReverbTag;
|
||||
android.hardware.audio.effect.Virtualizer.Id virtualizerTag;
|
||||
android.hardware.audio.effect.Visualizer.Id visualizerTag;
|
||||
@@ -71,6 +74,8 @@ union Parameter {
|
||||
@VintfStability
|
||||
union Specific {
|
||||
android.hardware.audio.effect.VendorExtension vendorEffect;
|
||||
android.hardware.audio.effect.AcousticEchoCanceler acousticEchoCanceler;
|
||||
android.hardware.audio.effect.AutomaticGainControl automaticGainControl;
|
||||
android.hardware.audio.effect.BassBoost bassBoost;
|
||||
android.hardware.audio.effect.Downmix downmix;
|
||||
android.hardware.audio.effect.DynamicsProcessing dynamicsProcessing;
|
||||
@@ -78,6 +83,7 @@ union Parameter {
|
||||
android.hardware.audio.effect.Equalizer equalizer;
|
||||
android.hardware.audio.effect.HapticGenerator hapticGenerator;
|
||||
android.hardware.audio.effect.LoudnessEnhancer loudnessEnhancer;
|
||||
android.hardware.audio.effect.NoiseSuppression noiseSuppression;
|
||||
android.hardware.audio.effect.PresetReverb presetReverb;
|
||||
android.hardware.audio.effect.Virtualizer virtualizer;
|
||||
android.hardware.audio.effect.Visualizer visualizer;
|
||||
|
||||
@@ -35,7 +35,7 @@ package android.hardware.audio.effect;
|
||||
@VintfStability
|
||||
parcelable Processing {
|
||||
android.hardware.audio.effect.Processing.Type type;
|
||||
android.hardware.audio.effect.Descriptor.Identity[] ids;
|
||||
android.hardware.audio.effect.Descriptor[] ids;
|
||||
@VintfStability
|
||||
union Type {
|
||||
android.media.audio.common.AudioStreamType streamType = android.media.audio.common.AudioStreamType.INVALID;
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.hardware.audio.effect;
|
||||
|
||||
import android.hardware.audio.effect.VendorExtension;
|
||||
|
||||
/**
|
||||
* Acoustic Echo Canceler (AEC) is an audio pre-processor which removes the contribution of the
|
||||
* signal received from the remote party from the captured audio signal.
|
||||
*
|
||||
* All parameters defined in union AcousticEchoCanceler must be gettable and settable. The
|
||||
* capabilities defined in AcousticEchoCanceler.Capability can only acquired with
|
||||
* IEffect.getDescriptor() and not settable.
|
||||
*/
|
||||
@VintfStability
|
||||
union AcousticEchoCanceler {
|
||||
/**
|
||||
* Effect parameter tag to identify the parameters for getParameter().
|
||||
*/
|
||||
@VintfStability
|
||||
union Id {
|
||||
int vendorExtensionTag;
|
||||
AcousticEchoCanceler.Tag commonTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vendor AEC implementation definition for additional parameters.
|
||||
*/
|
||||
VendorExtension vendor;
|
||||
|
||||
/**
|
||||
* Capability supported by AEC implementation.
|
||||
*/
|
||||
@VintfStability
|
||||
parcelable Capability {
|
||||
/**
|
||||
* AEC capability extension, vendor can use this extension in case existing capability
|
||||
* definition not enough.
|
||||
*/
|
||||
ParcelableHolder extension;
|
||||
|
||||
/**
|
||||
* Maximum AEC echo delay in microseconds supported.
|
||||
*/
|
||||
int maxEchoDelayUs;
|
||||
/**
|
||||
* If AEC mobile mode was supported by the AEC implementation.
|
||||
*/
|
||||
boolean supportMobileMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* The AEC echo delay in microseconds.
|
||||
* Must never be negative, and not larger than maxEchoDelayUs in capability.
|
||||
*/
|
||||
int echoDelayUs;
|
||||
/**
|
||||
* If AEC mobile mode enabled.
|
||||
* Can only be false if AEC implementation indicate not support mobile mode by set
|
||||
* supportMobileMode to false in capability.
|
||||
*/
|
||||
boolean mobileMode;
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.hardware.audio.effect;
|
||||
|
||||
import android.hardware.audio.effect.VendorExtension;
|
||||
|
||||
/**
|
||||
* Automatic Gain Control (AGC) is an audio pre-processor which automatically normalizes the output
|
||||
* of the captured signal by boosting or lowering input from the microphone to match a preset level
|
||||
* so that the output signal level is virtually constant. AGC can be used by applications where the
|
||||
* input signal dynamic range is not important but where a constant strong capture level is desired.
|
||||
*
|
||||
* All parameters defined in union AutomaticGainControl must be gettable and settable. The
|
||||
* capabilities defined in AutomaticGainControl.Capability can only acquired with
|
||||
* IEffect.getDescriptor() and not settable.
|
||||
*/
|
||||
@VintfStability
|
||||
union AutomaticGainControl {
|
||||
/**
|
||||
* Effect parameter tag to identify the parameters for getParameter().
|
||||
*/
|
||||
@VintfStability
|
||||
union Id {
|
||||
int vendorExtensionTag;
|
||||
AutomaticGainControl.Tag commonTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vendor AutomaticGainControl implementation definition for additional parameters.
|
||||
*/
|
||||
VendorExtension vendor;
|
||||
|
||||
/**
|
||||
* Capability supported by AutomaticGainControl implementation.
|
||||
*/
|
||||
@VintfStability
|
||||
parcelable Capability {
|
||||
/**
|
||||
* AutomaticGainControl capability extension, vendor can use this extension in case existing
|
||||
* capability definition not enough.
|
||||
*/
|
||||
ParcelableHolder extension;
|
||||
/**
|
||||
* Max fixed digital gain supported by AGC implementation in millibel.
|
||||
*/
|
||||
int maxFixedDigitalGainMb;
|
||||
/**
|
||||
* Max fixed saturation margin supported by AGC implementation in millibel.
|
||||
*/
|
||||
int maxSaturationMarginMb;
|
||||
}
|
||||
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum LevelEstimator {
|
||||
/* Use Root Mean Square level estimator*/
|
||||
RMS = 0,
|
||||
/* Use Peak level estimator*/
|
||||
PEAK = 1,
|
||||
}
|
||||
|
||||
/**
|
||||
* The AGC fixed digital gain in millibel.
|
||||
* Must never be negative, and not larger than maxFixedDigitalGainMb in capability.
|
||||
*/
|
||||
int fixedDigitalGainMb;
|
||||
/*
|
||||
* Adaptive digital level estimator.
|
||||
*/
|
||||
LevelEstimator levelEstimator;
|
||||
/**
|
||||
* The AGC saturation margin in millibel.
|
||||
* Must never be negative, and not larger than maxSaturationMarginMb in capability.
|
||||
*/
|
||||
int saturationMarginMb;
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.hardware.audio.effect;
|
||||
|
||||
import android.hardware.audio.effect.AcousticEchoCanceler;
|
||||
import android.hardware.audio.effect.AutomaticGainControl;
|
||||
import android.hardware.audio.effect.BassBoost;
|
||||
import android.hardware.audio.effect.Downmix;
|
||||
import android.hardware.audio.effect.DynamicsProcessing;
|
||||
@@ -23,6 +25,7 @@ import android.hardware.audio.effect.EnvironmentalReverb;
|
||||
import android.hardware.audio.effect.Equalizer;
|
||||
import android.hardware.audio.effect.HapticGenerator;
|
||||
import android.hardware.audio.effect.LoudnessEnhancer;
|
||||
import android.hardware.audio.effect.NoiseSuppression;
|
||||
import android.hardware.audio.effect.PresetReverb;
|
||||
import android.hardware.audio.effect.VendorExtension;
|
||||
import android.hardware.audio.effect.Virtualizer;
|
||||
@@ -49,6 +52,8 @@ union Capability {
|
||||
/**
|
||||
* Effect capabilities.
|
||||
*/
|
||||
AcousticEchoCanceler.Capability acousticEchoCanceler;
|
||||
AutomaticGainControl.Capability automaticGainControl;
|
||||
BassBoost.Capability bassBoost;
|
||||
Downmix.Capability downmix;
|
||||
DynamicsProcessing.Capability dynamicsProcessing;
|
||||
@@ -56,6 +61,7 @@ union Capability {
|
||||
Equalizer.Capability equalizer;
|
||||
HapticGenerator.Capability hapticGenerator;
|
||||
LoudnessEnhancer.Capability loudnessEnhancer;
|
||||
NoiseSuppression.Capability noiseSuppression;
|
||||
PresetReverb.Capability presetReverb;
|
||||
Virtualizer.Capability virtualizer;
|
||||
Visualizer.Capability visualizer;
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.hardware.audio.effect;
|
||||
|
||||
import android.hardware.audio.effect.VendorExtension;
|
||||
|
||||
/**
|
||||
* Noise suppression (NS) is an audio pre-processor which removes background noise from the captured
|
||||
* signal. The component of the signal considered as noise can be either stationary (car/airplane
|
||||
* engine, AC system) or non-stationary (other peoples conversations, car horn) for more advanced
|
||||
* implementations.
|
||||
*
|
||||
* All parameters defined in union NoiseSuppression must be gettable and settable. The capabilities
|
||||
* defined in NoiseSuppression.Capability can only acquired with IEffect.getDescriptor() and not
|
||||
* settable.
|
||||
*/
|
||||
@VintfStability
|
||||
union NoiseSuppression {
|
||||
/**
|
||||
* Effect parameter tag to identify the parameters for getParameter().
|
||||
*/
|
||||
@VintfStability
|
||||
union Id {
|
||||
int vendorExtensionTag;
|
||||
NoiseSuppression.Tag commonTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vendor NoiseSuppression implementation definition for additional parameters.
|
||||
*/
|
||||
VendorExtension vendor;
|
||||
|
||||
/**
|
||||
* Capability supported by NoiseSuppression implementation.
|
||||
*/
|
||||
@VintfStability
|
||||
parcelable Capability {
|
||||
/**
|
||||
* NoiseSuppression capability extension, vendor can use this extension in case existing
|
||||
* capability definition not enough.
|
||||
*/
|
||||
ParcelableHolder extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Different level of Noise Suppression to set.
|
||||
* As an example, webrtc have NsConfig::SuppressionLevel::k6dB applied for LOW level noise
|
||||
* suppression, NsConfig::SuppressionLevel::k12dB for MEDIUM, and
|
||||
* NsConfig::SuppressionLevel::k18dB for HIGH.
|
||||
*/
|
||||
@VintfStability @Backing(type="int") enum Level { LOW, MEDIUM, HIGH }
|
||||
|
||||
/**
|
||||
* The NS level.
|
||||
*/
|
||||
Level level;
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.hardware.audio.effect;
|
||||
|
||||
import android.hardware.audio.effect.AcousticEchoCanceler;
|
||||
import android.hardware.audio.effect.AutomaticGainControl;
|
||||
import android.hardware.audio.effect.BassBoost;
|
||||
import android.hardware.audio.effect.Downmix;
|
||||
import android.hardware.audio.effect.DynamicsProcessing;
|
||||
@@ -23,6 +25,7 @@ import android.hardware.audio.effect.EnvironmentalReverb;
|
||||
import android.hardware.audio.effect.Equalizer;
|
||||
import android.hardware.audio.effect.HapticGenerator;
|
||||
import android.hardware.audio.effect.LoudnessEnhancer;
|
||||
import android.hardware.audio.effect.NoiseSuppression;
|
||||
import android.hardware.audio.effect.PresetReverb;
|
||||
import android.hardware.audio.effect.VendorExtension;
|
||||
import android.hardware.audio.effect.Virtualizer;
|
||||
@@ -71,6 +74,8 @@ union Parameter {
|
||||
* effectInstance.getParameter(id, ¶m);
|
||||
*
|
||||
*/
|
||||
AcousticEchoCanceler.Id acousticEchoCancelerTag;
|
||||
AutomaticGainControl.Id automaticGainControlTag;
|
||||
BassBoost.Id bassBoostTag;
|
||||
Downmix.Id downmixTag;
|
||||
DynamicsProcessing.Id dynamicsProcessingTag;
|
||||
@@ -78,6 +83,7 @@ union Parameter {
|
||||
Equalizer.Id equalizerTag;
|
||||
HapticGenerator.Id hapticGeneratorTag;
|
||||
LoudnessEnhancer.Id loudnessEnhancerTag;
|
||||
NoiseSuppression.Id noiseSuppressionTag;
|
||||
PresetReverb.Id presetReverbTag;
|
||||
Virtualizer.Id virtualizerTag;
|
||||
Visualizer.Id visualizerTag;
|
||||
@@ -149,6 +155,8 @@ union Parameter {
|
||||
@VintfStability
|
||||
union Specific {
|
||||
VendorExtension vendorEffect;
|
||||
AcousticEchoCanceler acousticEchoCanceler;
|
||||
AutomaticGainControl automaticGainControl;
|
||||
BassBoost bassBoost;
|
||||
Downmix downmix;
|
||||
DynamicsProcessing dynamicsProcessing;
|
||||
@@ -156,6 +164,7 @@ union Parameter {
|
||||
Equalizer equalizer;
|
||||
HapticGenerator hapticGenerator;
|
||||
LoudnessEnhancer loudnessEnhancer;
|
||||
NoiseSuppression noiseSuppression;
|
||||
PresetReverb presetReverb;
|
||||
Virtualizer virtualizer;
|
||||
Visualizer visualizer;
|
||||
|
||||
@@ -38,7 +38,7 @@ parcelable Processing {
|
||||
*/
|
||||
Type type;
|
||||
/**
|
||||
* List of effect identities for this processing.
|
||||
* List of effect descriptors for this processing.
|
||||
*/
|
||||
Descriptor.Identity[] ids;
|
||||
Descriptor[] ids;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 <algorithm>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#define LOG_TAG "AHAL_AcousticEchoCancelerSw"
|
||||
#include <Utils.h>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <fmq/AidlMessageQueue.h>
|
||||
|
||||
#include "AcousticEchoCancelerSw.h"
|
||||
|
||||
using aidl::android::hardware::audio::effect::AcousticEchoCancelerSw;
|
||||
using aidl::android::hardware::audio::effect::Descriptor;
|
||||
using aidl::android::hardware::audio::effect::IEffect;
|
||||
using aidl::android::hardware::audio::effect::kAcousticEchoCancelerSwImplUUID;
|
||||
using aidl::android::media::audio::common::AudioUuid;
|
||||
|
||||
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
|
||||
std::shared_ptr<IEffect>* instanceSpp) {
|
||||
if (!in_impl_uuid || *in_impl_uuid != kAcousticEchoCancelerSwImplUUID) {
|
||||
LOG(ERROR) << __func__ << "uuid not supported";
|
||||
return EX_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
if (instanceSpp) {
|
||||
*instanceSpp = ndk::SharedRefBase::make<AcousticEchoCancelerSw>();
|
||||
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
|
||||
return EX_NONE;
|
||||
} else {
|
||||
LOG(ERROR) << __func__ << " invalid input parameter!";
|
||||
return EX_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
|
||||
if (!in_impl_uuid || *in_impl_uuid != kAcousticEchoCancelerSwImplUUID) {
|
||||
LOG(ERROR) << __func__ << "uuid not supported";
|
||||
return EX_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
*_aidl_return = AcousticEchoCancelerSw::kDescriptor;
|
||||
LOG(ERROR) << __func__ << "xxx " << _aidl_return->toString();
|
||||
return EX_NONE;
|
||||
}
|
||||
|
||||
namespace aidl::android::hardware::audio::effect {
|
||||
|
||||
const std::string AcousticEchoCancelerSw::kEffectName = "AcousticEchoCancelerSw";
|
||||
const AcousticEchoCanceler::Capability AcousticEchoCancelerSw::kCapability = {
|
||||
.maxEchoDelayUs = 500, .supportMobileMode = false};
|
||||
const Descriptor AcousticEchoCancelerSw::kDescriptor = {
|
||||
.common = {.id = {.type = kAcousticEchoCancelerTypeUUID,
|
||||
.uuid = kAcousticEchoCancelerSwImplUUID,
|
||||
.proxy = std::nullopt},
|
||||
.flags = {.type = Flags::Type::INSERT,
|
||||
.insert = Flags::Insert::FIRST,
|
||||
.volume = Flags::Volume::CTRL},
|
||||
.name = AcousticEchoCancelerSw::kEffectName,
|
||||
.implementor = "The Android Open Source Project"},
|
||||
.capability = Capability::make<Capability::acousticEchoCanceler>(
|
||||
AcousticEchoCancelerSw::kCapability)};
|
||||
|
||||
ndk::ScopedAStatus AcousticEchoCancelerSw::getDescriptor(Descriptor* _aidl_return) {
|
||||
LOG(DEBUG) << __func__ << kDescriptor.toString();
|
||||
*_aidl_return = kDescriptor;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus AcousticEchoCancelerSw::setParameterSpecific(
|
||||
const Parameter::Specific& specific) {
|
||||
RETURN_IF(Parameter::Specific::acousticEchoCanceler != specific.getTag(), EX_ILLEGAL_ARGUMENT,
|
||||
"EffectNotSupported");
|
||||
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
|
||||
|
||||
auto& param = specific.get<Parameter::Specific::acousticEchoCanceler>();
|
||||
auto tag = param.getTag();
|
||||
|
||||
switch (tag) {
|
||||
case AcousticEchoCanceler::echoDelayUs: {
|
||||
RETURN_IF(mContext->setEchoDelay(param.get<AcousticEchoCanceler::echoDelayUs>()) !=
|
||||
RetCode::SUCCESS,
|
||||
EX_ILLEGAL_ARGUMENT, "echoDelayNotSupported");
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
case AcousticEchoCanceler::mobileMode: {
|
||||
RETURN_IF(true == param.get<AcousticEchoCanceler::mobileMode>(), EX_ILLEGAL_ARGUMENT,
|
||||
"SettingmobileModeSupported");
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
default: {
|
||||
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
|
||||
EX_ILLEGAL_ARGUMENT, "AcousticEchoCancelerTagNotSupported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus AcousticEchoCancelerSw::getParameterSpecific(const Parameter::Id& id,
|
||||
Parameter::Specific* specific) {
|
||||
auto tag = id.getTag();
|
||||
RETURN_IF(Parameter::Id::acousticEchoCancelerTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
|
||||
auto specificId = id.get<Parameter::Id::acousticEchoCancelerTag>();
|
||||
auto specificIdTag = specificId.getTag();
|
||||
switch (specificIdTag) {
|
||||
case AcousticEchoCanceler::Id::commonTag:
|
||||
return getParameterAcousticEchoCanceler(
|
||||
specificId.get<AcousticEchoCanceler::Id::commonTag>(), specific);
|
||||
default:
|
||||
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
|
||||
EX_ILLEGAL_ARGUMENT, "AcousticEchoCancelerTagNotSupported");
|
||||
}
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus AcousticEchoCancelerSw::getParameterAcousticEchoCanceler(
|
||||
const AcousticEchoCanceler::Tag& tag, Parameter::Specific* specific) {
|
||||
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
|
||||
AcousticEchoCanceler param;
|
||||
switch (tag) {
|
||||
case AcousticEchoCanceler::echoDelayUs: {
|
||||
param.set<AcousticEchoCanceler::echoDelayUs>(mContext->getEchoDelay());
|
||||
break;
|
||||
}
|
||||
case AcousticEchoCanceler::mobileMode: {
|
||||
param.set<AcousticEchoCanceler::mobileMode>(false);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
|
||||
EX_ILLEGAL_ARGUMENT, "AcousticEchoCancelerTagNotSupported");
|
||||
}
|
||||
}
|
||||
|
||||
specific->set<Parameter::Specific::acousticEchoCanceler>(param);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
std::shared_ptr<EffectContext> AcousticEchoCancelerSw::createContext(
|
||||
const Parameter::Common& common) {
|
||||
if (mContext) {
|
||||
LOG(DEBUG) << __func__ << " context already exist";
|
||||
} else {
|
||||
mContext = std::make_shared<AcousticEchoCancelerSwContext>(1 /* statusFmqDepth */, common);
|
||||
}
|
||||
return mContext;
|
||||
}
|
||||
|
||||
std::shared_ptr<EffectContext> AcousticEchoCancelerSw::getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
RetCode AcousticEchoCancelerSw::releaseContext() {
|
||||
if (mContext) {
|
||||
mContext.reset();
|
||||
}
|
||||
return RetCode::SUCCESS;
|
||||
}
|
||||
|
||||
// Processing method running in EffectWorker thread.
|
||||
IEffect::Status AcousticEchoCancelerSw::effectProcessImpl(float* in, float* out, int samples) {
|
||||
// TODO: get data buffer and process.
|
||||
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
|
||||
for (int i = 0; i < samples; i++) {
|
||||
*out++ = *in++;
|
||||
}
|
||||
return {STATUS_OK, samples, samples};
|
||||
}
|
||||
|
||||
RetCode AcousticEchoCancelerSwContext::setEchoDelay(int echoDelayUs) {
|
||||
if (echoDelayUs < 0 || echoDelayUs > AcousticEchoCancelerSw::kCapability.maxEchoDelayUs) {
|
||||
LOG(DEBUG) << __func__ << " illegal delay " << echoDelayUs;
|
||||
return RetCode::ERROR_ILLEGAL_PARAMETER;
|
||||
}
|
||||
mEchoDelayUs = echoDelayUs;
|
||||
return RetCode::SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::audio::effect
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/audio/effect/BnEffect.h>
|
||||
#include <fmq/AidlMessageQueue.h>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
|
||||
#include "effect-impl/EffectImpl.h"
|
||||
#include "effect-impl/EffectUUID.h"
|
||||
|
||||
namespace aidl::android::hardware::audio::effect {
|
||||
|
||||
class AcousticEchoCancelerSwContext final : public EffectContext {
|
||||
public:
|
||||
AcousticEchoCancelerSwContext(int statusDepth, const Parameter::Common& common)
|
||||
: EffectContext(statusDepth, common) {
|
||||
LOG(DEBUG) << __func__;
|
||||
}
|
||||
|
||||
RetCode setEchoDelay(int echoDelayUs);
|
||||
int getEchoDelay() const { return mEchoDelayUs; }
|
||||
|
||||
private:
|
||||
int mEchoDelayUs;
|
||||
};
|
||||
|
||||
class AcousticEchoCancelerSw final : public EffectImpl {
|
||||
public:
|
||||
static const std::string kEffectName;
|
||||
static const bool kStrengthSupported;
|
||||
static const AcousticEchoCanceler::Capability kCapability;
|
||||
static const Descriptor kDescriptor;
|
||||
AcousticEchoCancelerSw() { LOG(DEBUG) << __func__; }
|
||||
~AcousticEchoCancelerSw() {
|
||||
cleanUp();
|
||||
LOG(DEBUG) << __func__;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
|
||||
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
|
||||
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
|
||||
Parameter::Specific* specific) override;
|
||||
|
||||
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
|
||||
std::shared_ptr<EffectContext> getContext() override;
|
||||
RetCode releaseContext() override;
|
||||
|
||||
std::string getEffectName() override { return kEffectName; };
|
||||
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<AcousticEchoCancelerSwContext> mContext;
|
||||
ndk::ScopedAStatus getParameterAcousticEchoCanceler(const AcousticEchoCanceler::Tag& tag,
|
||||
Parameter::Specific* specific);
|
||||
};
|
||||
} // namespace aidl::android::hardware::audio::effect
|
||||
40
audio/aidl/default/acousticEchoCanceler/Android.bp
Normal file
40
audio/aidl/default/acousticEchoCanceler/Android.bp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "libaecsw",
|
||||
defaults: [
|
||||
"aidlaudioeffectservice_defaults",
|
||||
"latest_android_media_audio_common_types_ndk_shared",
|
||||
"latest_android_hardware_audio_effect_ndk_shared",
|
||||
],
|
||||
srcs: [
|
||||
"AcousticEchoCancelerSw.cpp",
|
||||
":effectCommonFile",
|
||||
],
|
||||
visibility: [
|
||||
"//hardware/interfaces/audio/aidl/default",
|
||||
],
|
||||
}
|
||||
@@ -28,6 +28,8 @@
|
||||
name of a library .so file on the target device.
|
||||
-->
|
||||
<libraries>
|
||||
<library name="aecsw" path="libaecsw.so"/>
|
||||
<library name="agcsw" path="libagcsw.so"/>
|
||||
<library name="bassboostsw" path="libbassboostsw.so"/>
|
||||
<library name="bundle" path="libbundleaidl.so"/>
|
||||
<library name="downmix" path="libdownmixaidl.so"/>
|
||||
@@ -35,6 +37,7 @@
|
||||
<library name="equalizersw" path="libequalizersw.so"/>
|
||||
<library name="haptic_generatorsw" path="libhapticgeneratorsw.so"/>
|
||||
<library name="loudness_enhancer" path="libloudnessenhanceraidl.so"/>
|
||||
<library name="nssw" path="libnssw.so"/>
|
||||
<library name="env_reverbsw" path="libenvreverbsw.so"/>
|
||||
<library name="preset_reverbsw" path="libpresetreverbsw.so"/>
|
||||
<library name="virtualizersw" path="libvirtualizersw.so"/>
|
||||
@@ -62,6 +65,8 @@
|
||||
-->
|
||||
|
||||
<effects>
|
||||
<effect name="acoustic_echo_canceler" library="aecsw" uuid="bb392ec0-8d4d-11e0-a896-0002a5d5c51b"/>
|
||||
<effect name="automatic_gain_control" library="agcsw" uuid="89f38e65-d4d2-4d64-ad0e-2b3e799ea886"/>
|
||||
<effectProxy name="bassboost" uuid="14804144-a5ee-4d24-aa88-0002a5d5c51b">
|
||||
<libsw library="bassboostsw" uuid="fa8181f2-588b-11ed-9b6a-0242ac120002"/>
|
||||
<libsw library="bundle" uuid="8631f300-72e2-11df-b57e-0002a5d5c51b"/>
|
||||
@@ -71,6 +76,7 @@
|
||||
<effect name="haptic_generator" library="haptic_generatorsw" uuid="fa819110-588b-11ed-9b6a-0242ac120002"/>
|
||||
<effect name="loudness_enhancer" library="loudness_enhancer" uuid="fa415329-2034-4bea-b5dc-5b381c8d1e2c"/>
|
||||
<effect name="env_reverb" library="env_reverbsw" uuid="fa819886-588b-11ed-9b6a-0242ac120002"/>
|
||||
<effect name="noise_suppression" library="nssw" uuid="c06c8400-8e06-11e0-9cb6-0002a5d5c51b"/>
|
||||
<effect name="preset_reverb" library="preset_reverbsw" uuid="fa8199c6-588b-11ed-9b6a-0242ac120002"/>
|
||||
<effect name="virtualizer" library="virtualizersw" uuid="fa819d86-588b-11ed-9b6a-0242ac120002"/>
|
||||
<effect name="visualizer" library="visualizersw" uuid="fa81a0f6-588b-11ed-9b6a-0242ac120002"/>
|
||||
|
||||
40
audio/aidl/default/automaticGainControl/Android.bp
Normal file
40
audio/aidl/default/automaticGainControl/Android.bp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "libagcsw",
|
||||
defaults: [
|
||||
"aidlaudioeffectservice_defaults",
|
||||
"latest_android_media_audio_common_types_ndk_shared",
|
||||
"latest_android_hardware_audio_effect_ndk_shared",
|
||||
],
|
||||
srcs: [
|
||||
"AutomaticGainControlSw.cpp",
|
||||
":effectCommonFile",
|
||||
],
|
||||
visibility: [
|
||||
"//hardware/interfaces/audio/aidl/default",
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 <algorithm>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#define LOG_TAG "AHAL_AutomaticGainControlSw"
|
||||
#include <Utils.h>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <fmq/AidlMessageQueue.h>
|
||||
|
||||
#include "AutomaticGainControlSw.h"
|
||||
|
||||
using aidl::android::hardware::audio::effect::AutomaticGainControlSw;
|
||||
using aidl::android::hardware::audio::effect::Descriptor;
|
||||
using aidl::android::hardware::audio::effect::IEffect;
|
||||
using aidl::android::hardware::audio::effect::kAutomaticGainControlSwImplUUID;
|
||||
using aidl::android::media::audio::common::AudioUuid;
|
||||
|
||||
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
|
||||
std::shared_ptr<IEffect>* instanceSpp) {
|
||||
if (!in_impl_uuid || *in_impl_uuid != kAutomaticGainControlSwImplUUID) {
|
||||
LOG(ERROR) << __func__ << "uuid not supported";
|
||||
return EX_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
if (instanceSpp) {
|
||||
*instanceSpp = ndk::SharedRefBase::make<AutomaticGainControlSw>();
|
||||
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
|
||||
return EX_NONE;
|
||||
} else {
|
||||
LOG(ERROR) << __func__ << " invalid input parameter!";
|
||||
return EX_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
|
||||
if (!in_impl_uuid || *in_impl_uuid != kAutomaticGainControlSwImplUUID) {
|
||||
LOG(ERROR) << __func__ << "uuid not supported";
|
||||
return EX_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
*_aidl_return = AutomaticGainControlSw::kDescriptor;
|
||||
return EX_NONE;
|
||||
}
|
||||
|
||||
namespace aidl::android::hardware::audio::effect {
|
||||
|
||||
const std::string AutomaticGainControlSw::kEffectName = "AutomaticGainControlSw";
|
||||
const AutomaticGainControl::Capability AutomaticGainControlSw::kCapability = {
|
||||
.maxFixedDigitalGainMb = 50000, .maxSaturationMarginMb = 10000};
|
||||
const Descriptor AutomaticGainControlSw::kDescriptor = {
|
||||
.common = {.id = {.type = kAutomaticGainControlTypeUUID,
|
||||
.uuid = kAutomaticGainControlSwImplUUID,
|
||||
.proxy = std::nullopt},
|
||||
.flags = {.type = Flags::Type::INSERT,
|
||||
.insert = Flags::Insert::FIRST,
|
||||
.volume = Flags::Volume::CTRL},
|
||||
.name = AutomaticGainControlSw::kEffectName,
|
||||
.implementor = "The Android Open Source Project"},
|
||||
.capability = Capability::make<Capability::automaticGainControl>(
|
||||
AutomaticGainControlSw::kCapability)};
|
||||
|
||||
ndk::ScopedAStatus AutomaticGainControlSw::getDescriptor(Descriptor* _aidl_return) {
|
||||
LOG(DEBUG) << __func__ << kDescriptor.toString();
|
||||
*_aidl_return = kDescriptor;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus AutomaticGainControlSw::setParameterSpecific(
|
||||
const Parameter::Specific& specific) {
|
||||
RETURN_IF(Parameter::Specific::automaticGainControl != specific.getTag(), EX_ILLEGAL_ARGUMENT,
|
||||
"EffectNotSupported");
|
||||
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
|
||||
|
||||
auto& param = specific.get<Parameter::Specific::automaticGainControl>();
|
||||
auto tag = param.getTag();
|
||||
|
||||
switch (tag) {
|
||||
case AutomaticGainControl::fixedDigitalGainMb: {
|
||||
RETURN_IF(mContext->setDigitalGain(
|
||||
param.get<AutomaticGainControl::fixedDigitalGainMb>()) !=
|
||||
RetCode::SUCCESS,
|
||||
EX_ILLEGAL_ARGUMENT, "digitalGainNotSupported");
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
case AutomaticGainControl::levelEstimator: {
|
||||
RETURN_IF(
|
||||
mContext->setLevelEstimator(
|
||||
param.get<AutomaticGainControl::levelEstimator>()) != RetCode::SUCCESS,
|
||||
EX_ILLEGAL_ARGUMENT, "levelEstimatorNotSupported");
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
case AutomaticGainControl::saturationMarginMb: {
|
||||
RETURN_IF(mContext->setSaturationMargin(
|
||||
param.get<AutomaticGainControl::saturationMarginMb>()) !=
|
||||
RetCode::SUCCESS,
|
||||
EX_ILLEGAL_ARGUMENT, "saturationMarginNotSupported");
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
default: {
|
||||
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
|
||||
EX_ILLEGAL_ARGUMENT, "AutomaticGainControlTagNotSupported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus AutomaticGainControlSw::getParameterSpecific(const Parameter::Id& id,
|
||||
Parameter::Specific* specific) {
|
||||
auto tag = id.getTag();
|
||||
RETURN_IF(Parameter::Id::automaticGainControlTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
|
||||
auto specificId = id.get<Parameter::Id::automaticGainControlTag>();
|
||||
auto specificIdTag = specificId.getTag();
|
||||
switch (specificIdTag) {
|
||||
case AutomaticGainControl::Id::commonTag:
|
||||
return getParameterAutomaticGainControl(
|
||||
specificId.get<AutomaticGainControl::Id::commonTag>(), specific);
|
||||
default:
|
||||
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
|
||||
EX_ILLEGAL_ARGUMENT, "AutomaticGainControlTagNotSupported");
|
||||
}
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus AutomaticGainControlSw::getParameterAutomaticGainControl(
|
||||
const AutomaticGainControl::Tag& tag, Parameter::Specific* specific) {
|
||||
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
|
||||
AutomaticGainControl param;
|
||||
switch (tag) {
|
||||
case AutomaticGainControl::fixedDigitalGainMb: {
|
||||
param.set<AutomaticGainControl::fixedDigitalGainMb>(mContext->getDigitalGain());
|
||||
break;
|
||||
}
|
||||
case AutomaticGainControl::levelEstimator: {
|
||||
param.set<AutomaticGainControl::levelEstimator>(mContext->getLevelEstimator());
|
||||
break;
|
||||
}
|
||||
case AutomaticGainControl::saturationMarginMb: {
|
||||
param.set<AutomaticGainControl::saturationMarginMb>(mContext->getSaturationMargin());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
|
||||
EX_ILLEGAL_ARGUMENT, "AutomaticGainControlTagNotSupported");
|
||||
}
|
||||
}
|
||||
|
||||
specific->set<Parameter::Specific::automaticGainControl>(param);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
std::shared_ptr<EffectContext> AutomaticGainControlSw::createContext(
|
||||
const Parameter::Common& common) {
|
||||
if (mContext) {
|
||||
LOG(DEBUG) << __func__ << " context already exist";
|
||||
} else {
|
||||
mContext = std::make_shared<AutomaticGainControlSwContext>(1 /* statusFmqDepth */, common);
|
||||
}
|
||||
return mContext;
|
||||
}
|
||||
|
||||
std::shared_ptr<EffectContext> AutomaticGainControlSw::getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
RetCode AutomaticGainControlSw::releaseContext() {
|
||||
if (mContext) {
|
||||
mContext.reset();
|
||||
}
|
||||
return RetCode::SUCCESS;
|
||||
}
|
||||
|
||||
// Processing method running in EffectWorker thread.
|
||||
IEffect::Status AutomaticGainControlSw::effectProcessImpl(float* in, float* out, int samples) {
|
||||
// TODO: get data buffer and process.
|
||||
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
|
||||
for (int i = 0; i < samples; i++) {
|
||||
*out++ = *in++;
|
||||
}
|
||||
return {STATUS_OK, samples, samples};
|
||||
}
|
||||
|
||||
RetCode AutomaticGainControlSwContext::setDigitalGain(int gain) {
|
||||
if (gain < 0 || gain > AutomaticGainControlSw::kCapability.maxFixedDigitalGainMb) {
|
||||
LOG(DEBUG) << __func__ << " illegal digital gain " << gain;
|
||||
return RetCode::ERROR_ILLEGAL_PARAMETER;
|
||||
}
|
||||
mDigitalGain = gain;
|
||||
return RetCode::SUCCESS;
|
||||
}
|
||||
|
||||
int AutomaticGainControlSwContext::getDigitalGain() {
|
||||
return mDigitalGain;
|
||||
}
|
||||
|
||||
RetCode AutomaticGainControlSwContext::setLevelEstimator(
|
||||
AutomaticGainControl::LevelEstimator levelEstimator) {
|
||||
mLevelEstimator = levelEstimator;
|
||||
return RetCode::SUCCESS;
|
||||
}
|
||||
|
||||
AutomaticGainControl::LevelEstimator AutomaticGainControlSwContext::getLevelEstimator() {
|
||||
return mLevelEstimator;
|
||||
}
|
||||
|
||||
RetCode AutomaticGainControlSwContext::setSaturationMargin(int margin) {
|
||||
if (margin < 0 || margin > AutomaticGainControlSw::kCapability.maxSaturationMarginMb) {
|
||||
LOG(DEBUG) << __func__ << " illegal saturationMargin " << margin;
|
||||
return RetCode::ERROR_ILLEGAL_PARAMETER;
|
||||
}
|
||||
mSaturationMargin = margin;
|
||||
return RetCode::SUCCESS;
|
||||
}
|
||||
|
||||
int AutomaticGainControlSwContext::getSaturationMargin() {
|
||||
return mSaturationMargin;
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::audio::effect
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/audio/effect/BnEffect.h>
|
||||
#include <fmq/AidlMessageQueue.h>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
|
||||
#include "effect-impl/EffectImpl.h"
|
||||
#include "effect-impl/EffectUUID.h"
|
||||
|
||||
namespace aidl::android::hardware::audio::effect {
|
||||
|
||||
class AutomaticGainControlSwContext final : public EffectContext {
|
||||
public:
|
||||
AutomaticGainControlSwContext(int statusDepth, const Parameter::Common& common)
|
||||
: EffectContext(statusDepth, common) {
|
||||
LOG(DEBUG) << __func__;
|
||||
}
|
||||
|
||||
RetCode setDigitalGain(int gain);
|
||||
int getDigitalGain();
|
||||
RetCode setLevelEstimator(AutomaticGainControl::LevelEstimator levelEstimator);
|
||||
AutomaticGainControl::LevelEstimator getLevelEstimator();
|
||||
RetCode setSaturationMargin(int margin);
|
||||
int getSaturationMargin();
|
||||
|
||||
private:
|
||||
int mDigitalGain;
|
||||
AutomaticGainControl::LevelEstimator mLevelEstimator;
|
||||
int mSaturationMargin;
|
||||
};
|
||||
|
||||
class AutomaticGainControlSw final : public EffectImpl {
|
||||
public:
|
||||
static const std::string kEffectName;
|
||||
static const bool kStrengthSupported;
|
||||
static const AutomaticGainControl::Capability kCapability;
|
||||
static const Descriptor kDescriptor;
|
||||
AutomaticGainControlSw() { LOG(DEBUG) << __func__; }
|
||||
~AutomaticGainControlSw() {
|
||||
cleanUp();
|
||||
LOG(DEBUG) << __func__;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
|
||||
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
|
||||
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
|
||||
Parameter::Specific* specific) override;
|
||||
|
||||
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
|
||||
std::shared_ptr<EffectContext> getContext() override;
|
||||
RetCode releaseContext() override;
|
||||
|
||||
std::string getEffectName() override { return kEffectName; };
|
||||
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<AutomaticGainControlSwContext> mContext;
|
||||
ndk::ScopedAStatus getParameterAutomaticGainControl(const AutomaticGainControl::Tag& tag,
|
||||
Parameter::Specific* specific);
|
||||
};
|
||||
} // namespace aidl::android::hardware::audio::effect
|
||||
@@ -33,6 +33,30 @@ static const AudioUuid kEffectNullUuid = {static_cast<int32_t>(0xec7178ec),
|
||||
static const AudioUuid kEffectZeroUuid = {
|
||||
static_cast<int32_t>(0x0), 0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}};
|
||||
|
||||
// 7b491460-8d4d-11e0-bd61-0002a5d5c51b.
|
||||
static const AudioUuid kAcousticEchoCancelerTypeUUID = {static_cast<int32_t>(0x7b491460),
|
||||
0x8d4d,
|
||||
0x11e0,
|
||||
0xbd61,
|
||||
{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
|
||||
// bb392ec0-8d4d-11e0-a896-0002a5d5c51b
|
||||
static const AudioUuid kAcousticEchoCancelerSwImplUUID = {static_cast<int32_t>(0xbb392ec0),
|
||||
0x8d4d,
|
||||
0x11e0,
|
||||
0xa896,
|
||||
{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
|
||||
// 0xae3c653b-be18-4ab8-8938-418f0a7f06ac
|
||||
static const AudioUuid kAutomaticGainControlTypeUUID = {static_cast<int32_t>(0xae3c653b),
|
||||
0xbe18,
|
||||
0x4ab8,
|
||||
0x8938,
|
||||
{0x41, 0x8f, 0x0a, 0x7f, 0x06, 0xac}};
|
||||
// 89f38e65-d4d2-4d64-ad0e-2b3e799ea886
|
||||
static const AudioUuid kAutomaticGainControlSwImplUUID = {static_cast<int32_t>(0x89f38e65),
|
||||
0xd4d2,
|
||||
0x4d64,
|
||||
0xad0e,
|
||||
{0x2b, 0x3e, 0x79, 0x9e, 0xa8, 0x86}};
|
||||
// 0634f220-ddd4-11db-a0fc-0002a5d5c51b
|
||||
static const AudioUuid kBassBoostTypeUUID = {static_cast<int32_t>(0x0634f220),
|
||||
0xddd4,
|
||||
@@ -153,6 +177,18 @@ static const AudioUuid kEnvReverbSwImplUUID = {static_cast<int32_t>(0xfa819886),
|
||||
0x11ed,
|
||||
0x9b6a,
|
||||
{0x02, 0x42, 0xac, 0x12, 0x00, 0x02}};
|
||||
// 58b4b260-8e06-11e0-aa8e-0002a5d5c51b
|
||||
static const AudioUuid kNoiseSuppressionTypeUUID = {static_cast<int32_t>(0x58b4b260),
|
||||
0x8e06,
|
||||
0x11e0,
|
||||
0xaa8e,
|
||||
{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
|
||||
// c06c8400-8e06-11e0-9cb6-0002a5d5c51b
|
||||
static const AudioUuid kNoiseSuppressionSwImplUUID = {static_cast<int32_t>(0xc06c8400),
|
||||
0x8e06,
|
||||
0x11e0,
|
||||
0x9cb6,
|
||||
{0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}};
|
||||
// 47382d60-ddd8-11db-bf3a-0002a5d5c51b
|
||||
static const AudioUuid kPresetReverbTypeUUID = {static_cast<int32_t>(0x47382d60),
|
||||
0xddd8,
|
||||
@@ -208,6 +244,8 @@ static const AudioUuid kVolumeSwImplUUID = {static_cast<int32_t>(0xfa81a718),
|
||||
* We need this map is because existing audio_effects.xml don't have a type UUID defined.
|
||||
*/
|
||||
static const std::map<const std::string /* effect type */, const AudioUuid&> kUuidNameTypeMap = {
|
||||
{"acoustic_echo_canceler", kAcousticEchoCancelerTypeUUID},
|
||||
{"automatic_gain_control", kAutomaticGainControlTypeUUID},
|
||||
{"bassboost", kBassBoostTypeUUID},
|
||||
{"downmix", kDownmixTypeUUID},
|
||||
{"dynamics_processing", kDynamicsProcessingTypeUUID},
|
||||
@@ -215,6 +253,7 @@ static const std::map<const std::string /* effect type */, const AudioUuid&> kUu
|
||||
{"haptic_generator", kHapticGeneratorTypeUUID},
|
||||
{"loudness_enhancer", kLoudnessEnhancerTypeUUID},
|
||||
{"env_reverb", kEnvReverbTypeUUID},
|
||||
{"noise_suppression", kNoiseSuppressionTypeUUID},
|
||||
{"preset_reverb", kPresetReverbTypeUUID},
|
||||
{"reverb_env_aux", kEnvReverbTypeUUID},
|
||||
{"reverb_env_ins", kEnvReverbTypeUUID},
|
||||
|
||||
40
audio/aidl/default/noiseSuppression/Android.bp
Normal file
40
audio/aidl/default/noiseSuppression/Android.bp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "libnssw",
|
||||
defaults: [
|
||||
"aidlaudioeffectservice_defaults",
|
||||
"latest_android_media_audio_common_types_ndk_shared",
|
||||
"latest_android_hardware_audio_effect_ndk_shared",
|
||||
],
|
||||
srcs: [
|
||||
"NoiseSuppressionSw.cpp",
|
||||
":effectCommonFile",
|
||||
],
|
||||
visibility: [
|
||||
"//hardware/interfaces/audio/aidl/default",
|
||||
],
|
||||
}
|
||||
180
audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
Normal file
180
audio/aidl/default/noiseSuppression/NoiseSuppressionSw.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 <algorithm>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#define LOG_TAG "AHAL_NoiseSuppressionSw"
|
||||
#include <Utils.h>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <fmq/AidlMessageQueue.h>
|
||||
|
||||
#include "NoiseSuppressionSw.h"
|
||||
|
||||
using aidl::android::hardware::audio::effect::Descriptor;
|
||||
using aidl::android::hardware::audio::effect::IEffect;
|
||||
using aidl::android::hardware::audio::effect::kNoiseSuppressionSwImplUUID;
|
||||
using aidl::android::hardware::audio::effect::NoiseSuppressionSw;
|
||||
using aidl::android::media::audio::common::AudioUuid;
|
||||
|
||||
extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
|
||||
std::shared_ptr<IEffect>* instanceSpp) {
|
||||
if (!in_impl_uuid || *in_impl_uuid != kNoiseSuppressionSwImplUUID) {
|
||||
LOG(ERROR) << __func__ << "uuid not supported";
|
||||
return EX_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
if (instanceSpp) {
|
||||
*instanceSpp = ndk::SharedRefBase::make<NoiseSuppressionSw>();
|
||||
LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
|
||||
return EX_NONE;
|
||||
} else {
|
||||
LOG(ERROR) << __func__ << " invalid input parameter!";
|
||||
return EX_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
|
||||
if (!in_impl_uuid || *in_impl_uuid != kNoiseSuppressionSwImplUUID) {
|
||||
LOG(ERROR) << __func__ << "uuid not supported";
|
||||
return EX_ILLEGAL_ARGUMENT;
|
||||
}
|
||||
*_aidl_return = NoiseSuppressionSw::kDescriptor;
|
||||
return EX_NONE;
|
||||
}
|
||||
|
||||
namespace aidl::android::hardware::audio::effect {
|
||||
|
||||
const std::string NoiseSuppressionSw::kEffectName = "NoiseSuppressionSw";
|
||||
const NoiseSuppression::Capability NoiseSuppressionSw::kCapability;
|
||||
const Descriptor NoiseSuppressionSw::kDescriptor = {
|
||||
.common = {.id = {.type = kNoiseSuppressionTypeUUID,
|
||||
.uuid = kNoiseSuppressionSwImplUUID,
|
||||
.proxy = std::nullopt},
|
||||
.flags = {.type = Flags::Type::INSERT,
|
||||
.insert = Flags::Insert::FIRST,
|
||||
.volume = Flags::Volume::CTRL},
|
||||
.name = NoiseSuppressionSw::kEffectName,
|
||||
.implementor = "The Android Open Source Project"},
|
||||
.capability =
|
||||
Capability::make<Capability::noiseSuppression>(NoiseSuppressionSw::kCapability)};
|
||||
|
||||
ndk::ScopedAStatus NoiseSuppressionSw::getDescriptor(Descriptor* _aidl_return) {
|
||||
LOG(DEBUG) << __func__ << kDescriptor.toString();
|
||||
*_aidl_return = kDescriptor;
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus NoiseSuppressionSw::setParameterSpecific(const Parameter::Specific& specific) {
|
||||
RETURN_IF(Parameter::Specific::noiseSuppression != specific.getTag(), EX_ILLEGAL_ARGUMENT,
|
||||
"EffectNotSupported");
|
||||
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
|
||||
|
||||
auto& param = specific.get<Parameter::Specific::noiseSuppression>();
|
||||
auto tag = param.getTag();
|
||||
|
||||
switch (tag) {
|
||||
case NoiseSuppression::level: {
|
||||
RETURN_IF(mContext->setLevel(param.get<NoiseSuppression::level>()) != RetCode::SUCCESS,
|
||||
EX_ILLEGAL_ARGUMENT, "levelSupported");
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
default: {
|
||||
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
|
||||
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus NoiseSuppressionSw::getParameterSpecific(const Parameter::Id& id,
|
||||
Parameter::Specific* specific) {
|
||||
auto tag = id.getTag();
|
||||
RETURN_IF(Parameter::Id::noiseSuppressionTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
|
||||
auto specificId = id.get<Parameter::Id::noiseSuppressionTag>();
|
||||
auto specificIdTag = specificId.getTag();
|
||||
switch (specificIdTag) {
|
||||
case NoiseSuppression::Id::commonTag:
|
||||
return getParameterNoiseSuppression(specificId.get<NoiseSuppression::Id::commonTag>(),
|
||||
specific);
|
||||
default:
|
||||
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
|
||||
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
|
||||
}
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus NoiseSuppressionSw::getParameterNoiseSuppression(
|
||||
const NoiseSuppression::Tag& tag, Parameter::Specific* specific) {
|
||||
RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
|
||||
NoiseSuppression param;
|
||||
switch (tag) {
|
||||
case NoiseSuppression::level: {
|
||||
param.set<NoiseSuppression::level>(mContext->getLevel());
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
|
||||
return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
|
||||
EX_ILLEGAL_ARGUMENT, "NoiseSuppressionTagNotSupported");
|
||||
}
|
||||
}
|
||||
|
||||
specific->set<Parameter::Specific::noiseSuppression>(param);
|
||||
return ndk::ScopedAStatus::ok();
|
||||
}
|
||||
|
||||
std::shared_ptr<EffectContext> NoiseSuppressionSw::createContext(const Parameter::Common& common) {
|
||||
if (mContext) {
|
||||
LOG(DEBUG) << __func__ << " context already exist";
|
||||
} else {
|
||||
mContext = std::make_shared<NoiseSuppressionSwContext>(1 /* statusFmqDepth */, common);
|
||||
}
|
||||
return mContext;
|
||||
}
|
||||
|
||||
std::shared_ptr<EffectContext> NoiseSuppressionSw::getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
RetCode NoiseSuppressionSw::releaseContext() {
|
||||
if (mContext) {
|
||||
mContext.reset();
|
||||
}
|
||||
return RetCode::SUCCESS;
|
||||
}
|
||||
|
||||
// Processing method running in EffectWorker thread.
|
||||
IEffect::Status NoiseSuppressionSw::effectProcessImpl(float* in, float* out, int samples) {
|
||||
// TODO: get data buffer and process.
|
||||
LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
|
||||
for (int i = 0; i < samples; i++) {
|
||||
*out++ = *in++;
|
||||
}
|
||||
return {STATUS_OK, samples, samples};
|
||||
}
|
||||
|
||||
RetCode NoiseSuppressionSwContext::setLevel(NoiseSuppression::Level level) {
|
||||
mLevel = level;
|
||||
return RetCode::SUCCESS;
|
||||
}
|
||||
|
||||
NoiseSuppression::Level NoiseSuppressionSwContext::getLevel() {
|
||||
return mLevel;
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::audio::effect
|
||||
72
audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
Normal file
72
audio/aidl/default/noiseSuppression/NoiseSuppressionSw.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <aidl/android/hardware/audio/effect/BnEffect.h>
|
||||
#include <fmq/AidlMessageQueue.h>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
|
||||
#include "effect-impl/EffectImpl.h"
|
||||
#include "effect-impl/EffectUUID.h"
|
||||
|
||||
namespace aidl::android::hardware::audio::effect {
|
||||
|
||||
class NoiseSuppressionSwContext final : public EffectContext {
|
||||
public:
|
||||
NoiseSuppressionSwContext(int statusDepth, const Parameter::Common& common)
|
||||
: EffectContext(statusDepth, common) {
|
||||
LOG(DEBUG) << __func__;
|
||||
}
|
||||
|
||||
RetCode setLevel(NoiseSuppression::Level level);
|
||||
NoiseSuppression::Level getLevel();
|
||||
|
||||
private:
|
||||
NoiseSuppression::Level mLevel;
|
||||
};
|
||||
|
||||
class NoiseSuppressionSw final : public EffectImpl {
|
||||
public:
|
||||
static const std::string kEffectName;
|
||||
static const bool kStrengthSupported;
|
||||
static const NoiseSuppression::Capability kCapability;
|
||||
static const Descriptor kDescriptor;
|
||||
NoiseSuppressionSw() { LOG(DEBUG) << __func__; }
|
||||
~NoiseSuppressionSw() {
|
||||
cleanUp();
|
||||
LOG(DEBUG) << __func__;
|
||||
}
|
||||
|
||||
ndk::ScopedAStatus getDescriptor(Descriptor* _aidl_return) override;
|
||||
ndk::ScopedAStatus setParameterSpecific(const Parameter::Specific& specific) override;
|
||||
ndk::ScopedAStatus getParameterSpecific(const Parameter::Id& id,
|
||||
Parameter::Specific* specific) override;
|
||||
|
||||
std::shared_ptr<EffectContext> createContext(const Parameter::Common& common) override;
|
||||
std::shared_ptr<EffectContext> getContext() override;
|
||||
RetCode releaseContext() override;
|
||||
|
||||
std::string getEffectName() override { return kEffectName; };
|
||||
IEffect::Status effectProcessImpl(float* in, float* out, int samples) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<NoiseSuppressionSwContext> mContext;
|
||||
ndk::ScopedAStatus getParameterNoiseSuppression(const NoiseSuppression::Tag& tag,
|
||||
Parameter::Specific* specific);
|
||||
};
|
||||
} // namespace aidl::android::hardware::audio::effect
|
||||
@@ -102,3 +102,21 @@ cc_test {
|
||||
defaults: ["VtsHalAudioTargetTestDefaults"],
|
||||
srcs: ["VtsHalVisualizerTargetTest.cpp"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalAECTargetTest",
|
||||
defaults: ["VtsHalAudioTargetTestDefaults"],
|
||||
srcs: ["VtsHalAECTargetTest.cpp"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalAGCTargetTest",
|
||||
defaults: ["VtsHalAudioTargetTestDefaults"],
|
||||
srcs: ["VtsHalAGCTargetTest.cpp"],
|
||||
}
|
||||
|
||||
cc_test {
|
||||
name: "VtsHalNSTargetTest",
|
||||
defaults: ["VtsHalAudioTargetTestDefaults"],
|
||||
srcs: ["VtsHalNSTargetTest.cpp"],
|
||||
}
|
||||
|
||||
@@ -70,7 +70,6 @@ class EffectFactoryHelper {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
219
audio/aidl/vts/VtsHalAECTargetTest.cpp
Normal file
219
audio/aidl/vts/VtsHalAECTargetTest.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 <aidl/Vintf.h>
|
||||
#include <algorithm>
|
||||
|
||||
#define LOG_TAG "VtsHalAECParamTest"
|
||||
|
||||
#include <Utils.h>
|
||||
#include "EffectHelper.h"
|
||||
|
||||
using namespace android;
|
||||
|
||||
using aidl::android::hardware::audio::effect::AcousticEchoCanceler;
|
||||
using aidl::android::hardware::audio::effect::Capability;
|
||||
using aidl::android::hardware::audio::effect::Descriptor;
|
||||
using aidl::android::hardware::audio::effect::IEffect;
|
||||
using aidl::android::hardware::audio::effect::IFactory;
|
||||
using aidl::android::hardware::audio::effect::kAcousticEchoCancelerTypeUUID;
|
||||
using aidl::android::hardware::audio::effect::Parameter;
|
||||
|
||||
enum ParamName { PARAM_INSTANCE_NAME, PARAM_ECHO_DELAY, PARAM_MOBILE_MODE };
|
||||
using AECParamTestParam = std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>,
|
||||
int /* echoDelayUs */, bool /* mobileMode */>;
|
||||
|
||||
class AECParamTest : public ::testing::TestWithParam<AECParamTestParam>, public EffectHelper {
|
||||
public:
|
||||
AECParamTest()
|
||||
: mEchoDelay(std::get<PARAM_ECHO_DELAY>(GetParam())),
|
||||
mMobileMode(std::get<PARAM_MOBILE_MODE>(GetParam())) {
|
||||
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
ASSERT_NE(nullptr, mFactory);
|
||||
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
|
||||
|
||||
Parameter::Specific specific = getDefaultParamSpecific();
|
||||
Parameter::Common common = EffectHelper::createParamCommon(
|
||||
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
|
||||
kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
|
||||
IEffect::OpenEffectReturn ret;
|
||||
ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
|
||||
ASSERT_NE(nullptr, mEffect);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
ASSERT_NO_FATAL_FAILURE(close(mEffect));
|
||||
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
|
||||
}
|
||||
|
||||
Parameter::Specific getDefaultParamSpecific() {
|
||||
AcousticEchoCanceler aec = AcousticEchoCanceler::make<AcousticEchoCanceler::echoDelayUs>(0);
|
||||
Parameter::Specific specific =
|
||||
Parameter::Specific::make<Parameter::Specific::acousticEchoCanceler>(aec);
|
||||
return specific;
|
||||
}
|
||||
|
||||
static const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList;
|
||||
static const std::vector<int> kEchoDelayValues;
|
||||
static const std::vector<bool> kMobileModeValues;
|
||||
|
||||
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
|
||||
std::shared_ptr<IFactory> mFactory;
|
||||
std::shared_ptr<IEffect> mEffect;
|
||||
Descriptor mDescriptor;
|
||||
|
||||
int mEchoDelay;
|
||||
bool mMobileMode;
|
||||
|
||||
void SetAndGetParameters() {
|
||||
for (auto& it : mTags) {
|
||||
auto& tag = it.first;
|
||||
auto& aec = it.second;
|
||||
|
||||
// validate parameter
|
||||
Descriptor desc;
|
||||
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
|
||||
const bool valid = isTagInRange(tag, aec, desc);
|
||||
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
|
||||
|
||||
// set parameter
|
||||
Parameter expectParam;
|
||||
Parameter::Specific specific;
|
||||
specific.set<Parameter::Specific::acousticEchoCanceler>(aec);
|
||||
expectParam.set<Parameter::specific>(specific);
|
||||
EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
|
||||
|
||||
// only get if parameter in range and set success
|
||||
if (expected == EX_NONE) {
|
||||
Parameter getParam;
|
||||
Parameter::Id id;
|
||||
AcousticEchoCanceler::Id specificId;
|
||||
specificId.set<AcousticEchoCanceler::Id::commonTag>(tag);
|
||||
id.set<Parameter::Id::acousticEchoCancelerTag>(specificId);
|
||||
EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
|
||||
|
||||
EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
|
||||
<< "\ngetParam:" << getParam.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addEchoDelayParam(int delay) {
|
||||
AcousticEchoCanceler aec;
|
||||
aec.set<AcousticEchoCanceler::echoDelayUs>(delay);
|
||||
mTags.push_back({AcousticEchoCanceler::echoDelayUs, aec});
|
||||
}
|
||||
|
||||
void addMobileModeParam(bool mode) {
|
||||
AcousticEchoCanceler aec;
|
||||
aec.set<AcousticEchoCanceler::mobileMode>(mode);
|
||||
mTags.push_back({AcousticEchoCanceler::mobileMode, aec});
|
||||
}
|
||||
|
||||
bool isTagInRange(const AcousticEchoCanceler::Tag& tag, const AcousticEchoCanceler& aec,
|
||||
const Descriptor& desc) const {
|
||||
const AcousticEchoCanceler::Capability& aecCap =
|
||||
desc.capability.get<Capability::acousticEchoCanceler>();
|
||||
switch (tag) {
|
||||
case AcousticEchoCanceler::echoDelayUs: {
|
||||
return isEchoDelayInRange(aecCap, aec.get<AcousticEchoCanceler::echoDelayUs>());
|
||||
}
|
||||
case AcousticEchoCanceler::mobileMode: {
|
||||
bool mode = aec.get<AcousticEchoCanceler::mobileMode>();
|
||||
return isMobileModeValid(aecCap, mode);
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isEchoDelayInRange(const AcousticEchoCanceler::Capability& cap, int delay) const {
|
||||
return (delay >= 0 && delay <= cap.maxEchoDelayUs);
|
||||
}
|
||||
|
||||
bool isMobileModeValid(const AcousticEchoCanceler::Capability& cap, bool mode) const {
|
||||
if (cap.supportMobileMode) {
|
||||
return true;
|
||||
} else {
|
||||
return mode == false;
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<int> getEchoDelayTestValues() {
|
||||
const auto max = std::max_element(
|
||||
kFactoryDescList.begin(), kFactoryDescList.end(),
|
||||
[](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
|
||||
const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
|
||||
return a.second.capability.get<Capability::acousticEchoCanceler>()
|
||||
.maxEchoDelayUs <
|
||||
b.second.capability.get<Capability::acousticEchoCanceler>()
|
||||
.maxEchoDelayUs;
|
||||
});
|
||||
if (max == kFactoryDescList.end()) {
|
||||
return {0};
|
||||
}
|
||||
int maxDelay =
|
||||
max->second.capability.get<Capability::acousticEchoCanceler>().maxEchoDelayUs;
|
||||
return {-1, 0, maxDelay - 1, maxDelay, maxDelay + 1};
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::pair<AcousticEchoCanceler::Tag, AcousticEchoCanceler>> mTags;
|
||||
void CleanUp() { mTags.clear(); }
|
||||
};
|
||||
|
||||
const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> AECParamTest::kFactoryDescList =
|
||||
EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
|
||||
kAcousticEchoCancelerTypeUUID);
|
||||
const std::vector<int> AECParamTest::kEchoDelayValues = AECParamTest::getEchoDelayTestValues();
|
||||
const std::vector<bool> AECParamTest::kMobileModeValues = {true, false};
|
||||
|
||||
TEST_P(AECParamTest, SetAndGetEchoDelay) {
|
||||
EXPECT_NO_FATAL_FAILURE(addEchoDelayParam(mEchoDelay));
|
||||
SetAndGetParameters();
|
||||
}
|
||||
|
||||
TEST_P(AECParamTest, SetAndGetMobileMode) {
|
||||
EXPECT_NO_FATAL_FAILURE(addMobileModeParam(mMobileMode));
|
||||
SetAndGetParameters();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(AECParamTest, AECParamTest,
|
||||
::testing::Combine(testing::ValuesIn(AECParamTest::kFactoryDescList),
|
||||
testing::ValuesIn(AECParamTest::kEchoDelayValues),
|
||||
testing::ValuesIn(AECParamTest::kMobileModeValues)),
|
||||
[](const testing::TestParamInfo<AECParamTest::ParamType>& info) {
|
||||
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
|
||||
std::string name = "Implementor_" + descriptor.common.implementor +
|
||||
"_name_" + descriptor.common.name + "_UUID_" +
|
||||
descriptor.common.id.uuid.toString();
|
||||
std::replace_if(
|
||||
name.begin(), name.end(),
|
||||
[](const char c) { return !std::isalnum(c); }, '_');
|
||||
return name;
|
||||
});
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AECParamTest);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(1);
|
||||
ABinderProcess_startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
256
audio/aidl/vts/VtsHalAGCTargetTest.cpp
Normal file
256
audio/aidl/vts/VtsHalAGCTargetTest.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 <aidl/Vintf.h>
|
||||
|
||||
#define LOG_TAG "VtsHalAGCParamTest"
|
||||
|
||||
#include <Utils.h>
|
||||
#include "EffectHelper.h"
|
||||
|
||||
using namespace android;
|
||||
|
||||
using aidl::android::hardware::audio::effect::AutomaticGainControl;
|
||||
using aidl::android::hardware::audio::effect::Capability;
|
||||
using aidl::android::hardware::audio::effect::Descriptor;
|
||||
using aidl::android::hardware::audio::effect::IEffect;
|
||||
using aidl::android::hardware::audio::effect::IFactory;
|
||||
using aidl::android::hardware::audio::effect::kAutomaticGainControlTypeUUID;
|
||||
using aidl::android::hardware::audio::effect::Parameter;
|
||||
|
||||
enum ParamName {
|
||||
PARAM_INSTANCE_NAME,
|
||||
PARAM_DIGITAL_GAIN,
|
||||
PARAM_SATURATION_MARGIN,
|
||||
PARAM_LEVEL_ESTIMATOR
|
||||
};
|
||||
using AGCParamTestParam =
|
||||
std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int /* gain */,
|
||||
int /* margin */, AutomaticGainControl::LevelEstimator>;
|
||||
|
||||
class AGCParamTest : public ::testing::TestWithParam<AGCParamTestParam>, public EffectHelper {
|
||||
public:
|
||||
AGCParamTest()
|
||||
: mGain(std::get<PARAM_DIGITAL_GAIN>(GetParam())),
|
||||
mMargin(std::get<PARAM_SATURATION_MARGIN>(GetParam())),
|
||||
mLevelEstimator(std::get<PARAM_LEVEL_ESTIMATOR>(GetParam())) {
|
||||
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
ASSERT_NE(nullptr, mFactory);
|
||||
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
|
||||
|
||||
Parameter::Specific specific = getDefaultParamSpecific();
|
||||
Parameter::Common common = EffectHelper::createParamCommon(
|
||||
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
|
||||
kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
|
||||
IEffect::OpenEffectReturn ret;
|
||||
ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
|
||||
ASSERT_NE(nullptr, mEffect);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
ASSERT_NO_FATAL_FAILURE(close(mEffect));
|
||||
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
|
||||
}
|
||||
|
||||
Parameter::Specific getDefaultParamSpecific() {
|
||||
AutomaticGainControl AGC =
|
||||
AutomaticGainControl::make<AutomaticGainControl::fixedDigitalGainMb>(0);
|
||||
Parameter::Specific specific =
|
||||
Parameter::Specific::make<Parameter::Specific::automaticGainControl>(AGC);
|
||||
return specific;
|
||||
}
|
||||
|
||||
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
|
||||
static const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList;
|
||||
static const std::vector<int> kDigitalGainValues;
|
||||
static const std::vector<int> kSaturationMarginValues;
|
||||
static const std::vector<AutomaticGainControl::LevelEstimator> kLevelEstimatorValues;
|
||||
|
||||
std::shared_ptr<IFactory> mFactory;
|
||||
std::shared_ptr<IEffect> mEffect;
|
||||
Descriptor mDescriptor;
|
||||
int mGain;
|
||||
int mMargin;
|
||||
AutomaticGainControl::LevelEstimator mLevelEstimator;
|
||||
|
||||
void SetAndGetParameters() {
|
||||
for (auto& it : mTags) {
|
||||
auto& tag = it.first;
|
||||
auto& AGC = it.second;
|
||||
|
||||
// validate parameter
|
||||
Descriptor desc;
|
||||
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
|
||||
const bool valid = isTagInRange(tag, AGC, desc);
|
||||
const binder_exception_t expected = valid ? EX_NONE : EX_ILLEGAL_ARGUMENT;
|
||||
|
||||
// set parameter
|
||||
Parameter expectParam;
|
||||
Parameter::Specific specific;
|
||||
specific.set<Parameter::Specific::automaticGainControl>(AGC);
|
||||
expectParam.set<Parameter::specific>(specific);
|
||||
EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
|
||||
|
||||
// only get if parameter in range and set success
|
||||
if (expected == EX_NONE) {
|
||||
Parameter getParam;
|
||||
Parameter::Id id;
|
||||
AutomaticGainControl::Id specificId;
|
||||
specificId.set<AutomaticGainControl::Id::commonTag>(tag);
|
||||
id.set<Parameter::Id::automaticGainControlTag>(specificId);
|
||||
EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
|
||||
|
||||
EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
|
||||
<< "\ngetParam:" << getParam.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addDigitalGainParam(int gain) {
|
||||
AutomaticGainControl AGC;
|
||||
AGC.set<AutomaticGainControl::fixedDigitalGainMb>(gain);
|
||||
mTags.push_back({AutomaticGainControl::fixedDigitalGainMb, AGC});
|
||||
}
|
||||
void addSaturationMarginParam(int margin) {
|
||||
AutomaticGainControl AGC;
|
||||
AGC.set<AutomaticGainControl::saturationMarginMb>(margin);
|
||||
mTags.push_back({AutomaticGainControl::saturationMarginMb, AGC});
|
||||
}
|
||||
void addLevelEstimatorParam(AutomaticGainControl::LevelEstimator levelEstimator) {
|
||||
AutomaticGainControl AGC;
|
||||
AGC.set<AutomaticGainControl::levelEstimator>(levelEstimator);
|
||||
mTags.push_back({AutomaticGainControl::levelEstimator, AGC});
|
||||
}
|
||||
|
||||
bool isTagInRange(const AutomaticGainControl::Tag& tag, const AutomaticGainControl& AGC,
|
||||
const Descriptor& desc) const {
|
||||
const AutomaticGainControl::Capability& AGCCap =
|
||||
desc.capability.get<Capability::automaticGainControl>();
|
||||
switch (tag) {
|
||||
case AutomaticGainControl::fixedDigitalGainMb: {
|
||||
auto gain = AGC.get<AutomaticGainControl::fixedDigitalGainMb>();
|
||||
return gain >= 0 && gain <= AGCCap.maxFixedDigitalGainMb;
|
||||
}
|
||||
case AutomaticGainControl::levelEstimator: {
|
||||
return true;
|
||||
}
|
||||
case AutomaticGainControl::saturationMarginMb: {
|
||||
auto margin = AGC.get<AutomaticGainControl::saturationMarginMb>();
|
||||
return margin >= 0 && margin <= AGCCap.maxSaturationMarginMb;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
static std::vector<int> getDigitalGainValues() {
|
||||
const auto max = std::max_element(
|
||||
kFactoryDescList.begin(), kFactoryDescList.end(),
|
||||
[](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
|
||||
const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
|
||||
return a.second.capability.get<Capability::automaticGainControl>()
|
||||
.maxFixedDigitalGainMb <
|
||||
b.second.capability.get<Capability::automaticGainControl>()
|
||||
.maxFixedDigitalGainMb;
|
||||
});
|
||||
if (max == kFactoryDescList.end()) {
|
||||
return {0};
|
||||
}
|
||||
int maxGain = max->second.capability.get<Capability::automaticGainControl>()
|
||||
.maxFixedDigitalGainMb;
|
||||
return {-1, 0, maxGain - 1, maxGain, maxGain + 1};
|
||||
}
|
||||
static std::vector<int> getSaturationMarginValues() {
|
||||
const auto max = std::max_element(
|
||||
kFactoryDescList.begin(), kFactoryDescList.end(),
|
||||
[](const std::pair<std::shared_ptr<IFactory>, Descriptor>& a,
|
||||
const std::pair<std::shared_ptr<IFactory>, Descriptor>& b) {
|
||||
return a.second.capability.get<Capability::automaticGainControl>()
|
||||
.maxSaturationMarginMb <
|
||||
b.second.capability.get<Capability::automaticGainControl>()
|
||||
.maxSaturationMarginMb;
|
||||
});
|
||||
if (max == kFactoryDescList.end()) {
|
||||
return {0};
|
||||
}
|
||||
int maxMargin = max->second.capability.get<Capability::automaticGainControl>()
|
||||
.maxSaturationMarginMb;
|
||||
return {-1, 0, maxMargin - 1, maxMargin, maxMargin + 1};
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::pair<AutomaticGainControl::Tag, AutomaticGainControl>> mTags;
|
||||
void CleanUp() { mTags.clear(); }
|
||||
};
|
||||
|
||||
const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> AGCParamTest::kFactoryDescList =
|
||||
EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
|
||||
kAutomaticGainControlTypeUUID);
|
||||
const std::vector<int> AGCParamTest::kDigitalGainValues = AGCParamTest::getDigitalGainValues();
|
||||
const std::vector<int> AGCParamTest::kSaturationMarginValues =
|
||||
AGCParamTest::getSaturationMarginValues();
|
||||
const std::vector<AutomaticGainControl::LevelEstimator> AGCParamTest::kLevelEstimatorValues = {
|
||||
AutomaticGainControl::LevelEstimator::RMS, AutomaticGainControl::LevelEstimator::PEAK};
|
||||
|
||||
TEST_P(AGCParamTest, SetAndGetDigitalGainParam) {
|
||||
EXPECT_NO_FATAL_FAILURE(addDigitalGainParam(mGain));
|
||||
SetAndGetParameters();
|
||||
}
|
||||
|
||||
TEST_P(AGCParamTest, SetAndGetSaturationMargin) {
|
||||
EXPECT_NO_FATAL_FAILURE(addSaturationMarginParam(mMargin));
|
||||
SetAndGetParameters();
|
||||
}
|
||||
|
||||
TEST_P(AGCParamTest, SetAndGetLevelEstimator) {
|
||||
EXPECT_NO_FATAL_FAILURE(addLevelEstimatorParam(mLevelEstimator));
|
||||
SetAndGetParameters();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
AGCParamTest, AGCParamTest,
|
||||
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
|
||||
IFactory::descriptor, kAutomaticGainControlTypeUUID)),
|
||||
testing::ValuesIn(AGCParamTest::kDigitalGainValues),
|
||||
testing::ValuesIn(AGCParamTest::kSaturationMarginValues),
|
||||
testing::ValuesIn(AGCParamTest::kLevelEstimatorValues)),
|
||||
[](const testing::TestParamInfo<AGCParamTest::ParamType>& info) {
|
||||
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
|
||||
std::string gain = std::to_string(std::get<PARAM_DIGITAL_GAIN>(info.param));
|
||||
std::string estimator = aidl::android::hardware::audio::effect::toString(
|
||||
std::get<PARAM_LEVEL_ESTIMATOR>(info.param));
|
||||
std::string margin =
|
||||
std::to_string(static_cast<int>(std::get<PARAM_SATURATION_MARGIN>(info.param)));
|
||||
|
||||
std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
|
||||
descriptor.common.name + "_UUID_" +
|
||||
descriptor.common.id.uuid.toString() + "_digital_gain_" + gain +
|
||||
"_level_estimator_" + estimator + "_margin_" + margin;
|
||||
std::replace_if(
|
||||
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
|
||||
return name;
|
||||
});
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AGCParamTest);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(1);
|
||||
ABinderProcess_startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
158
audio/aidl/vts/VtsHalNSTargetTest.cpp
Normal file
158
audio/aidl/vts/VtsHalNSTargetTest.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 <aidl/Vintf.h>
|
||||
|
||||
#define LOG_TAG "VtsHalNSParamTest"
|
||||
|
||||
#include <Utils.h>
|
||||
#include "EffectHelper.h"
|
||||
|
||||
using namespace android;
|
||||
|
||||
using aidl::android::hardware::audio::effect::Capability;
|
||||
using aidl::android::hardware::audio::effect::Descriptor;
|
||||
using aidl::android::hardware::audio::effect::IEffect;
|
||||
using aidl::android::hardware::audio::effect::IFactory;
|
||||
using aidl::android::hardware::audio::effect::kNoiseSuppressionTypeUUID;
|
||||
using aidl::android::hardware::audio::effect::NoiseSuppression;
|
||||
using aidl::android::hardware::audio::effect::Parameter;
|
||||
|
||||
enum ParamName { PARAM_INSTANCE_NAME, PARAM_LEVEL };
|
||||
using NSParamTestParam =
|
||||
std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, NoiseSuppression::Level>;
|
||||
|
||||
class NSParamTest : public ::testing::TestWithParam<NSParamTestParam>, public EffectHelper {
|
||||
public:
|
||||
NSParamTest() : mLevel(std::get<PARAM_LEVEL>(GetParam())) {
|
||||
std::tie(mFactory, mDescriptor) = std::get<PARAM_INSTANCE_NAME>(GetParam());
|
||||
}
|
||||
|
||||
void SetUp() override {
|
||||
ASSERT_NE(nullptr, mFactory);
|
||||
ASSERT_NO_FATAL_FAILURE(create(mFactory, mEffect, mDescriptor));
|
||||
|
||||
Parameter::Specific specific = getDefaultParamSpecific();
|
||||
Parameter::Common common = EffectHelper::createParamCommon(
|
||||
0 /* session */, 1 /* ioHandle */, 44100 /* iSampleRate */, 44100 /* oSampleRate */,
|
||||
kInputFrameCount /* iFrameCount */, kOutputFrameCount /* oFrameCount */);
|
||||
IEffect::OpenEffectReturn ret;
|
||||
ASSERT_NO_FATAL_FAILURE(open(mEffect, common, specific, &ret, EX_NONE));
|
||||
ASSERT_NE(nullptr, mEffect);
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
ASSERT_NO_FATAL_FAILURE(close(mEffect));
|
||||
ASSERT_NO_FATAL_FAILURE(destroy(mFactory, mEffect));
|
||||
}
|
||||
|
||||
Parameter::Specific getDefaultParamSpecific() {
|
||||
NoiseSuppression ns =
|
||||
NoiseSuppression::make<NoiseSuppression::level>(NoiseSuppression::Level::MEDIUM);
|
||||
Parameter::Specific specific =
|
||||
Parameter::Specific::make<Parameter::Specific::noiseSuppression>(ns);
|
||||
return specific;
|
||||
}
|
||||
|
||||
static const long kInputFrameCount = 0x100, kOutputFrameCount = 0x100;
|
||||
static const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList;
|
||||
static const std::vector<NoiseSuppression::Level> kLevelValues;
|
||||
|
||||
std::shared_ptr<IFactory> mFactory;
|
||||
std::shared_ptr<IEffect> mEffect;
|
||||
Descriptor mDescriptor;
|
||||
NoiseSuppression::Level mLevel;
|
||||
|
||||
void SetAndGetParameters() {
|
||||
for (auto& it : mTags) {
|
||||
auto& tag = it.first;
|
||||
auto& ns = it.second;
|
||||
|
||||
// validate parameter
|
||||
Descriptor desc;
|
||||
ASSERT_STATUS(EX_NONE, mEffect->getDescriptor(&desc));
|
||||
const binder_exception_t expected = EX_NONE;
|
||||
|
||||
// set parameter
|
||||
Parameter expectParam;
|
||||
Parameter::Specific specific;
|
||||
specific.set<Parameter::Specific::noiseSuppression>(ns);
|
||||
expectParam.set<Parameter::specific>(specific);
|
||||
EXPECT_STATUS(expected, mEffect->setParameter(expectParam)) << expectParam.toString();
|
||||
|
||||
// only get if parameter in range and set success
|
||||
if (expected == EX_NONE) {
|
||||
Parameter getParam;
|
||||
Parameter::Id id;
|
||||
NoiseSuppression::Id specificId;
|
||||
specificId.set<NoiseSuppression::Id::commonTag>(tag);
|
||||
id.set<Parameter::Id::noiseSuppressionTag>(specificId);
|
||||
EXPECT_STATUS(EX_NONE, mEffect->getParameter(id, &getParam));
|
||||
|
||||
EXPECT_EQ(expectParam, getParam) << "\nexpect:" << expectParam.toString()
|
||||
<< "\ngetParam:" << getParam.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addLevelParam(NoiseSuppression::Level level) {
|
||||
NoiseSuppression ns;
|
||||
ns.set<NoiseSuppression::level>(level);
|
||||
mTags.push_back({NoiseSuppression::level, ns});
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::pair<NoiseSuppression::Tag, NoiseSuppression>> mTags;
|
||||
void CleanUp() { mTags.clear(); }
|
||||
};
|
||||
|
||||
const std::vector<std::pair<std::shared_ptr<IFactory>, Descriptor>> kFactoryDescList =
|
||||
EffectFactoryHelper::getAllEffectDescriptors(IFactory::descriptor,
|
||||
kNoiseSuppressionTypeUUID);
|
||||
const std::vector<NoiseSuppression::Level> NSParamTest::kLevelValues = {
|
||||
NoiseSuppression::Level::LOW, NoiseSuppression::Level::MEDIUM,
|
||||
NoiseSuppression::Level::HIGH};
|
||||
|
||||
TEST_P(NSParamTest, SetAndGetLevel) {
|
||||
EXPECT_NO_FATAL_FAILURE(addLevelParam(mLevel));
|
||||
SetAndGetParameters();
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
NSParamTest, NSParamTest,
|
||||
::testing::Combine(testing::ValuesIn(EffectFactoryHelper::getAllEffectDescriptors(
|
||||
IFactory::descriptor, kNoiseSuppressionTypeUUID)),
|
||||
testing::ValuesIn(NSParamTest::kLevelValues)),
|
||||
[](const testing::TestParamInfo<NSParamTest::ParamType>& info) {
|
||||
auto descriptor = std::get<PARAM_INSTANCE_NAME>(info.param).second;
|
||||
std::string level = aidl::android::hardware::audio::effect::toString(
|
||||
std::get<PARAM_LEVEL>(info.param));
|
||||
std::string name = "Implementor_" + descriptor.common.implementor + "_name_" +
|
||||
descriptor.common.name + "_UUID_" +
|
||||
descriptor.common.id.uuid.toString() + "_level_" + level;
|
||||
std::replace_if(
|
||||
name.begin(), name.end(), [](const char c) { return !std::isalnum(c); }, '_');
|
||||
return name;
|
||||
});
|
||||
|
||||
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(NSParamTest);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(1);
|
||||
ABinderProcess_startThreadPool();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in New Issue
Block a user