diff options
| author | Paul McLean <pmclean@google.com> | 2014-05-17 01:18:50 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-05-17 01:18:51 +0000 |
| commit | 43bde29538bf33d444d41a0b9cc0d60793fb20fa (patch) | |
| tree | 6e231a6c8f6c35afea525ee6db0f1e86fdaa3a5b /src | |
| parent | 45daca3d034eb05666dfdfb0eca625d1849d05d7 (diff) | |
| parent | f8b3141926967ba37d315cc8d3956d7214958e6b (diff) | |
| download | android_frameworks_wilhelm-43bde29538bf33d444d41a0b9cc0d60793fb20fa.tar.gz android_frameworks_wilhelm-43bde29538bf33d444d41a0b9cc0d60793fb20fa.tar.bz2 android_frameworks_wilhelm-43bde29538bf33d444d41a0b9cc0d60793fb20fa.zip | |
Merge "Initial Implementation of new NDK effect interfaces"
Diffstat (limited to 'src')
| -rw-r--r-- | src/Android.mk | 6 | ||||
| -rw-r--r-- | src/MPH.h | 7 | ||||
| -rw-r--r-- | src/MPH_to.c | 5 | ||||
| -rw-r--r-- | src/OpenSLES_IID.c | 11 | ||||
| -rw-r--r-- | src/android/android_Effect.cpp | 106 | ||||
| -rw-r--r-- | src/autogen/IID_to_MPH.c | 282 | ||||
| -rw-r--r-- | src/autogen/MPH_to_3DGroup.h | 2 | ||||
| -rw-r--r-- | src/autogen/MPH_to_AudioPlayer.h | 2 | ||||
| -rw-r--r-- | src/autogen/MPH_to_AudioRecorder.h | 2 | ||||
| -rw-r--r-- | src/autogen/MPH_to_Engine.h | 2 | ||||
| -rw-r--r-- | src/autogen/MPH_to_LEDDevice.h | 2 | ||||
| -rw-r--r-- | src/autogen/MPH_to_Listener.h | 2 | ||||
| -rw-r--r-- | src/autogen/MPH_to_MediaPlayer.h | 2 | ||||
| -rw-r--r-- | src/autogen/MPH_to_MetadataExtractor.h | 2 | ||||
| -rw-r--r-- | src/autogen/MPH_to_MidiPlayer.h | 2 | ||||
| -rw-r--r-- | src/autogen/MPH_to_OutputMix.h | 2 | ||||
| -rw-r--r-- | src/autogen/MPH_to_Vibra.h | 2 | ||||
| -rw-r--r-- | src/classes.c | 5 | ||||
| -rw-r--r-- | src/classes.h | 5 | ||||
| -rw-r--r-- | src/interfaces.c | 5 | ||||
| -rw-r--r-- | src/itf/IAcousticEchoCancellation.c | 138 | ||||
| -rw-r--r-- | src/itf/IAutomaticGainControl.c | 135 | ||||
| -rw-r--r-- | src/itf/INoiseSuppression.c | 132 | ||||
| -rw-r--r-- | src/itfstruct.h | 24 | ||||
| -rw-r--r-- | src/sl_iid.c | 6 | ||||
| -rw-r--r-- | src/sles.c | 16 | ||||
| -rw-r--r-- | src/ut/OpenSLESUT.c | 5 |
27 files changed, 787 insertions, 123 deletions
diff --git a/src/Android.mk b/src/Android.mk index 7e8ebf2..82fae28 100644 --- a/src/Android.mk +++ b/src/Android.mk @@ -109,6 +109,8 @@ LOCAL_SRC_FILES:= \ itf/IAndroidEffect.cpp \ itf/IAndroidEffectCapabilities.c \ itf/IAndroidEffectSend.c \ + itf/IAcousticEchoCancellation.c \ + itf/IAutomaticGainControl.c \ itf/IBassBoost.c \ itf/IBufferQueue.c \ itf/IDynamicInterfaceManagement.c \ @@ -118,6 +120,7 @@ LOCAL_SRC_FILES:= \ itf/IEnvironmentalReverb.c \ itf/IEqualizer.c \ itf/IMetadataExtraction.c \ + itf/INoiseSuppression.c \ itf/IMuteSolo.c \ itf/IObject.c \ itf/IOutputMix.c \ @@ -185,7 +188,8 @@ LOCAL_SHARED_LIBRARIES := \ libstagefright_http_support \ libcutils \ libgui \ - libdl + libdl \ + libeffects @@ -125,7 +125,12 @@ #define MPH_XAVIDEOPOSTPROCESSING 88 #define MPH_XAVOLUME 89 +// Android API level 20 extended interfaces +#define MPH_ANDROIDACOUSTICECHOCANCELLATION 90 +#define MPH_ANDROIDAUTOMATICGAINCONTROL 91 +#define MPH_ANDROIDNOISESUPPRESSION 92 + // total number of interface IDs -#define MPH_MAX 90 +#define MPH_MAX 93 #endif // !defined(__MPH_H) diff --git a/src/MPH_to.c b/src/MPH_to.c index 638117a..c467ba0 100644 --- a/src/MPH_to.c +++ b/src/MPH_to.c @@ -106,8 +106,11 @@ const signed char MPH_to_AudioRecorder[MPH_MAX] = { [MPH_VOLUME] = 8, #ifdef ANDROID [MPH_ANDROIDSIMPLEBUFFERQUEUE] = 9, // this is not an alias - [MPH_ANDROIDCONFIGURATION] = 10 + [MPH_ANDROIDCONFIGURATION] = 10, #endif + [MPH_ANDROIDACOUSTICECHOCANCELLATION] = 11, + [MPH_ANDROIDAUTOMATICGAINCONTROL] = 12, + [MPH_ANDROIDNOISESUPPRESSION] = 13, #else #include "MPH_to_AudioRecorder.h" #endif diff --git a/src/OpenSLES_IID.c b/src/OpenSLES_IID.c index 95f0599..272ac47 100644 --- a/src/OpenSLES_IID.c +++ b/src/OpenSLES_IID.c @@ -145,7 +145,7 @@ const struct SLInterfaceID_ SL_IID_array[MPH_MAX] = { // Wilhelm desktop extended interfaces - // SL_IID_OUTPUTMIXEXT +// SL_IID_OUTPUTMIXEXT { 0xfe5cce00, 0x57bb, 0x11df, 0x951c, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // Android API level 9 extended interfaces @@ -250,4 +250,13 @@ const struct SLInterfaceID_ SL_IID_array[MPH_MAX] = { { 0x898b6820, 0x7e6e, 0x11dd, 0x8caf, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, // XA_IID_VOLUME { 0x088ba520, 0xf777, 0x11db, 0xa5e3, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, + +// Android API level 20 extended interfaces + + // SL_IID_ANDROIDACOUSTICECHOCANCELLATION + { 0x4786de20, 0xd622, 0x11e3, 0xbd30, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, + // SL_IID_ANDROIDAUTOMATICGAINCONTROL + { 0xadb80fc0, 0xd622, 0x11e3, 0x927e, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, + // SL_IID_ANDROIDNOISESUPPRESSION + { 0xbb85ff40, 0xd622, 0x11e3, 0xb770, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, }; diff --git a/src/android/android_Effect.cpp b/src/android/android_Effect.cpp index a8e69ad..56d98d9 100644 --- a/src/android/android_Effect.cpp +++ b/src/android/android_Effect.cpp @@ -24,6 +24,10 @@ #include <audio_effects/effect_presetreverb.h> #include <audio_effects/effect_virtualizer.h> +#include <audio_effects/effect_aec.h> +#include <audio_effects/effect_agc.h> +#include <audio_effects/effect_ns.h> + #include <system/audio.h> static const int EQUALIZER_PARAM_SIZE_MAX = sizeof(effect_param_t) + 2 * sizeof(int32_t) @@ -857,3 +861,105 @@ SLresult android_genericFx_sendCommand(IAndroidEffect* iae, SLInterfaceID pUuid, bool android_genericFx_hasEffect(IAndroidEffect* iae, SLInterfaceID pUuid) { return( 0 <= iae->mEffects->indexOfKey(KEY_FROM_GUID(pUuid))); } + +//----------------------------------------------------------------------------- +static const int AEC_PARAM_SIZE_MAX = sizeof(effect_param_t) + (2 * sizeof(int32_t)); +/** + * returns the size in bytes of the value of each acoustic echo cancellation parameter + */ +uint32_t aec_valueSize(int32_t param) { + uint32_t size; + switch (param) { + case AEC_PARAM_ECHO_DELAY: + size = sizeof(int32_t); + break; + default: + size = sizeof(int32_t); + SL_LOGE("Trying to access an unknown Acoustic Echo Cancellation parameter %d", param); + break; + } + + return size; +} + +android::status_t android_aec_setParam(android::sp<android::AudioEffect> pFx, + int32_t param, void *pValue) { + return android_fx_setParam(pFx, param, AEC_PARAM_SIZE_MAX, + pValue, aec_valueSize(param)); +} + +android::status_t android_aec_getParam(android::sp<android::AudioEffect> pFx, + int32_t param, void *pValue) { + return android_fx_getParam(pFx, param, AEC_PARAM_SIZE_MAX, + pValue, aec_valueSize(param)); +} + +//----------------------------------------------------------------------------- +static const int AGC_PARAM_SIZE_MAX = sizeof(effect_param_t) + (2 * sizeof(int16_t)) + sizeof(bool); +/** + * returns the size in bytes of the value of each automatic gain control parameter + */ +uint32_t agc_valueSize(int32_t param) { + uint32_t size; + switch (param) { + case AGC_PARAM_TARGET_LEVEL: + case AGC_PARAM_COMP_GAIN: + size = sizeof(int16_t); + break; + case AGC_PARAM_LIMITER_ENA: + size = sizeof(bool); + break; + default: + size = sizeof(int32_t); + SL_LOGE("Trying to access an unknown Automatic Gain Control parameter %d", param); + break; + } + + return size; +} + +android::status_t android_agc_setParam(android::sp<android::AudioEffect> pFx, + int32_t param, void *pValue) { + return android_fx_setParam(pFx, param, AGC_PARAM_SIZE_MAX, + pValue, agc_valueSize(param)); +} + +android::status_t android_agc_getParam(android::sp<android::AudioEffect> pFx, + int32_t param, void *pValue) { + return android_fx_getParam(pFx, param, AGC_PARAM_SIZE_MAX, + pValue, agc_valueSize(param)); +} + +//----------------------------------------------------------------------------- +static const int NS_PARAM_SIZE_MAX = sizeof(effect_param_t) + sizeof(int32_t); +/** + * returns the size in bytes of the value of each noise suppression parameter + */ +uint32_t ns_valueSize(int32_t param) { + uint32_t size; + switch (param) { + case NS_PARAM_LEVEL: + size = sizeof(int32_t); + break; + default: + size = sizeof(int32_t); + SL_LOGE("Trying to access an unknown Noise suppression parameter %d", param); + break; + } + + return size; +} + +android::status_t android_ns_setParam(android::sp<android::AudioEffect> pFx, + int32_t param, void *pValue) +{ + return android_fx_setParam(pFx, param, NS_PARAM_SIZE_MAX, + pValue, ns_valueSize(param)); +} + +android::status_t android_ns_getParam(android::sp<android::AudioEffect> pFx, + int32_t param, void *pValue) +{ + return android_fx_getParam(pFx, param, NS_PARAM_SIZE_MAX, + pValue, ns_valueSize(param)); +} diff --git a/src/autogen/IID_to_MPH.c b/src/autogen/IID_to_MPH.c index c37d07e..3beee9b 100644 --- a/src/autogen/IID_to_MPH.c +++ b/src/autogen/IID_to_MPH.c @@ -29,224 +29,294 @@ extern const struct SLInterfaceID_ SL_IID_array[MPH_MAX]; int IID_to_MPH(const SLInterfaceID iid) { -#define MAX_HASH_VALUE 180 +#define MAX_HASH_VALUE 250 static const unsigned char asso_values[] = { - 35, 20, 54, 84, 181, 181, 59, 181, 181, 181, - 181, 181, 181, 181, 69, 181, 64, 44, 181, 181, - 181, 181, 39, 181, 54, 14, 181, 181, 14, 181, - 181, 125, 5, 181, 181, 181, 181, 181, 181, 181, - 127, 181, 181, 181, 9, 181, 112, 181, 181, 181, - 181, 181, 122, 181, 181, 181, 181, 181, 14, 100, - 181, 9, 24, 181, 50, 181, 181, 181, 181, 117, - 181, 181, 97, 85, 181, 181, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 117, 181, 19, 181, - 181, 181, 9, 181, 181, 181, 25, 181, 14, 102, - 181, 181, 181, 181, 181, 181, 181, 4, 181, 97, - 181, 181, 0, 181, 4, 92, 117, 181, 67, 45, - 181, 181, 110, 181, 181, 181, 72, 181, 40, 181, - 181, 181, 181, 181, 181, 102, 52, 181, 181, 181, - 181, 181, 57, 67, 181, 62, 181, 125, 181, 181, - 181, 181, 181, 82, 181, 181, 72, 181, 181, 65, - 5, 181, 32, 181, 181, 67, 120, 181, 181, 37, - 181, 57, 55, 181, 181, 47, 181, 45, 181, 181, - 181, 181, 7, 181, 17, 30, 181, 181, 181, 181, - 181, 181, 0, 181, 181, 181, 105, 32, 181, 181, - 181, 181, 181, 181, 181, 181, 115, 181, 181, 181, - 95, 32, 181, 181, 181, 22, 181, 181, 2, 181, - 181, 181, 181, 12, 10, 181, 181, 12, 181, 181, - 181, 181, 181, 181, 2, 181, 70, 181, 181, 181, - 10, 2, 181, 181, 70, 181, 120, 115, 181, 181, - 181, 80, 105, 100, 181, 181 + 251, 22, 251, 87, 251, 251, 0, 251, 37, 17, + 251, 12, 4, 251, 251, 95, 251, 251, 251, 251, + 102, 251, 17, 251, 251, 85, 251, 251, 251, 7, + 251, 115, 251, 251, 251, 251, 251, 251, 7, 2, + 251, 251, 15, 2, 87, 122, 15, 251, 251, 122, + 251, 251, 251, 70, 251, 50, 251, 251, 32, 251, + 251, 7, 251, 47, 2, 251, 52, 12, 47, 2, + 251, 25, 251, 67, 251, 85, 32, 25, 251, 251, + 2, 251, 251, 251, 2, 251, 2, 251, 251, 251, + 2, 251, 251, 2, 251, 251, 251, 12, 105, 125, + 251, 125, 251, 251, 2, 251, 12, 120, 251, 10, + 75, 2, 2, 251, 251, 120, 115, 251, 251, 251, + 110, 120, 10, 110, 251, 251, 251, 105, 15, 251, + 5, 50, 251, 251, 251, 251, 251, 100, 251, 251, + 120, 2, 251, 95, 251, 251, 251, 125, 2, 251, + 251, 90, 251, 251, 90, 251, 0, 251, 90, 251, + 251, 251, 251, 75, 100, 2, 251, 100, 80, 251, + 110, 251, 251, 70, 80, 75, 115, 22, 50, 75, + 90, 251, 251, 251, 65, 65, 251, 60, 65, 251, + 251, 251, 60, 5, 55, 55, 105, 5, 50, 45, + 65, 251, 251, 251, 55, 45, 45, 251, 45, 30, + 40, 251, 65, 55, 251, 75, 251, 30, 75, 45, + 251, 80, 25, 251, 251, 20, 251, 20, 2, 251, + 251, 50, 251, 251, 251, 60, 110, 17, 20, 30, + 251, 45, 0, 85, 20, 251, 120, 251, 251, 251, + 251, 251, 251, 35, 40, 60 }; static const signed char hash_to_MPH[] = { - MPH_ANDROIDEFFECTSEND, + MPH_BASSBOOST, -1, - MPH_XADYNAMICINTERFACEMANAGEMENT, + MPH_BUFFERQUEUE, + -1, + MPH_XAVIDEOENCODERCAPABILITIES, + MPH_XAIMAGEENCODERCAPABILITIES, + -1, + MPH_XAOBJECT, + -1, + MPH_VISUALIZATION, + MPH_DYNAMICSOURCE, + -1, + MPH_XAAUDIOIODEVICECAPABILITIES, + -1, + MPH_MIDITIME, + MPH_RECORD, + -1, + MPH_3DLOCATION, + -1, + MPH_VIBRA, + MPH_XAEQUALIZER, + -1, + MPH_ANDROIDEFFECTCAPABILITIES, + -1, + MPH_EQUALIZER, + MPH_XACONFIGEXTENSION, + -1, + MPH_RATEPITCH, -1, MPH_XAAUDIODECODERCAPABILITIES, + MPH_PLAYBACKRATE, + -1, MPH_XALED, -1, - MPH_XATHREADSYNC, + MPH_VOLUME, + MPH_PREFETCHSTATUS, -1, - MPH_XAOUTPUTMIX, - MPH_MIDITIME, + MPH_XAMETADATAEXTRACTION, -1, + MPH_XAVOLUME, MPH_XAIMAGECONTROLS, -1, - MPH_AUDIOIODEVICECAPABILITIES, - MPH_MUTESOLO, + MPH_EFFECTSEND, -1, - MPH_XAVOLUME, + MPH_XACAMERACAPABILITIES, + MPH_DEVICEVOLUME, -1, - MPH_ANDROIDCONFIGURATION, - MPH_XASNAPSHOT, + MPH_XAVIDEOENCODER, -1, - MPH_XAPLAY, -1, - MPH_SEEK, - MPH_3DLOCATION, + MPH_ANDROIDACOUSTICECHOCANCELLATION, -1, - MPH_XACONFIGEXTENSION, + MPH_XAOUTPUTMIX, -1, - MPH_XAIMAGEDECODERCAPABILITIES, - MPH_XACAMERACAPABILITIES, -1, - MPH_3DMACROSCOPIC, + MPH_XASNAPSHOT, -1, - MPH_VIBRA, - MPH_XAIMAGEEFFECTS, + MPH_ENGINE, -1, - MPH_XAMETADATAEXTRACTION, -1, - MPH_PRESETREVERB, - MPH_XAOBJECT, + MPH_PLAY, + -1, + MPH_MUTESOLO, -1, - MPH_RATEPITCH, -1, MPH_PITCH, + -1, + MPH_XADYNAMICSOURCE, + -1, + -1, + MPH_XACAMERA, + -1, MPH_XAVIBRA, -1, - MPH_XARADIO, + -1, + MPH_AUDIOIODEVICECAPABILITIES, + -1, + MPH_XADYNAMICINTERFACEMANAGEMENT, + -1, + -1, + MPH_XAVIDEODECODERCAPABILITIES, + -1, + MPH_3DMACROSCOPIC, + -1, -1, MPH_OUTPUTMIXEXT, + -1, + MPH_XADEVICEVOLUME, + -1, + -1, + MPH_XAIMAGEENCODER, + -1, + MPH_XAMETADATAINSERTION, + -1, + -1, MPH_ENGINECAPABILITIES, -1, + MPH_XAENGINE, + -1, + -1, + MPH_XAAUDIOENCODERCAPABILITIES, + -1, MPH_XAVIDEOPOSTPROCESSING, -1, - MPH_3DCOMMIT, - MPH_XAVIDEODECODERCAPABILITIES, -1, - MPH_METADATATRAVERSAL, + MPH_XAIMAGEDECODERCAPABILITIES, -1, - MPH_XASEEK, - MPH_AUDIODECODERCAPABILITIES, + MPH_3DGROUPING, -1, - MPH_DEVICEVOLUME, -1, - MPH_OBJECT, MPH_ENVIRONMENTALREVERB, -1, + MPH_3DSOURCE, + -1, + -1, + MPH_XAPREFETCHSTATUS, + -1, MPH_XARDS, -1, - MPH_XAVIDEOENCODER, - MPH_OUTPUTMIX, -1, - MPH_XADYNAMICSOURCE, + MPH_ANDROIDNOISESUPPRESSION, + -1, + MPH_AUDIODECODERCAPABILITIES, + -1, + -1, + MPH_XAAUDIOENCODER, -1, - MPH_3DGROUPING, MPH_XASTREAMINFORMATION, -1, - MPH_XAPREFETCHSTATUS, -1, - MPH_XAMETADATATRAVERSAL, + MPH_XAIMAGEEFFECTS, + -1, + MPH_LED, + -1, + -1, + MPH_SEEK, + -1, MPH_VIRTUALIZER, -1, - MPH_BUFFERQUEUE, -1, - MPH_ANDROIDBUFFERQUEUESOURCE, - MPH_PLAY, + MPH_3DCOMMIT, -1, - MPH_XAMETADATAINSERTION, + MPH_XASEEK, -1, - MPH_XADEVICEVOLUME, - MPH_XAVIDEOENCODERCAPABILITIES, -1, - MPH_ENGINE, + MPH_XARADIO, + -1, + MPH_PRESETREVERB, + -1, + -1, + MPH_AUDIOENCODER, + -1, + MPH_ANDROIDSIMPLEBUFFERQUEUE, + -1, + -1, + MPH_ANDROIDEFFECT, + -1, + MPH_XAPLAYBACKRATE, + -1, + -1, + MPH_MIDIMESSAGE, -1, MPH_MIDIMUTESOLO, - MPH_XAEQUALIZER, -1, - MPH_METADATAEXTRACTION, -1, + MPH_ANDROIDAUTOMATICGAINCONTROL, -1, - MPH_XARECORD, -1, - MPH_XAIMAGEENCODER, -1, -1, - MPH_VISUALIZATION, + MPH_AUDIOENCODERCAPABILITIES, -1, - MPH_XACAMERA, -1, -1, - MPH_BASSBOOST, -1, - MPH_LED, + MPH_XATHREADSYNC, -1, -1, - MPH_EFFECTSEND, -1, - MPH_XAENGINE, -1, + MPH_3DDOPPLER, -1, - MPH_RECORD, -1, - MPH_MIDIMESSAGE, -1, -1, - MPH_ANDROIDEFFECTCAPABILITIES, + MPH_OUTPUTMIX, -1, - MPH_3DSOURCE, -1, -1, - MPH_VOLUME, -1, - MPH_XAAUDIOENCODERCAPABILITIES, + MPH_XAPLAY, -1, -1, - MPH_PLAYBACKRATE, -1, - MPH_XAAUDIOIODEVICECAPABILITIES, -1, + MPH_XARECORD, -1, - MPH_NULL, -1, - MPH_ANDROIDEFFECT, -1, -1, - MPH_XAIMAGEENCODERCAPABILITIES, + MPH_ANDROIDCONFIGURATION, -1, - MPH_XAPLAYBACKRATE, -1, -1, - MPH_MIDITEMPO, -1, - MPH_DYNAMICSOURCE, + MPH_ANDROIDBUFFERQUEUESOURCE, -1, -1, - MPH_DYNAMICINTERFACEMANAGEMENT, -1, - MPH_EQUALIZER, -1, + MPH_METADATATRAVERSAL, -1, - MPH_XAAUDIOENCODER, -1, - MPH_THREADSYNC, -1, -1, - MPH_PREFETCHSTATUS, + MPH_ANDROIDEFFECTSEND, -1, - MPH_3DDOPPLER, -1, -1, - MPH_ANDROIDSIMPLEBUFFERQUEUE, -1, + MPH_NULL, -1, -1, -1, - MPH_AUDIOENCODERCAPABILITIES, + -1, + MPH_METADATAEXTRACTION, + -1, + -1, + -1, + -1, + MPH_MIDITEMPO, + -1, + -1, + -1, + -1, + MPH_XAMETADATATRAVERSAL, + -1, + -1, + -1, + -1, + MPH_THREADSYNC, + -1, + -1, + -1, + -1, + MPH_OBJECT, -1, -1, -1, -1, - MPH_AUDIOENCODER + MPH_DYNAMICINTERFACEMANAGEMENT }; if (&SL_IID_array[0] <= iid && &SL_IID_array[MPH_MAX] > iid) return iid - &SL_IID_array[0]; if (NULL != iid) { - unsigned key = asso_values[((unsigned char *)iid)[8]] + - asso_values[((unsigned char *)iid)[0]]; + unsigned key = asso_values[((unsigned char *)iid)[3]] + + asso_values[((unsigned char *)iid)[1]]; if (key <= MAX_HASH_VALUE) { int MPH = hash_to_MPH[key]; if (MPH >= 0) { diff --git a/src/autogen/MPH_to_3DGroup.h b/src/autogen/MPH_to_3DGroup.h index c0ecf01..109ccc0 100644 --- a/src/autogen/MPH_to_3DGroup.h +++ b/src/autogen/MPH_to_3DGroup.h @@ -3,4 +3,4 @@ -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 diff --git a/src/autogen/MPH_to_AudioPlayer.h b/src/autogen/MPH_to_AudioPlayer.h index dbfa871..f7256fa 100644 --- a/src/autogen/MPH_to_AudioPlayer.h +++ b/src/autogen/MPH_to_AudioPlayer.h @@ -3,4 +3,4 @@ -1, 10, 11, -1, -1, -1, -1, 9, -1, 0, -1, 21, 2, 23, 12, 22, 13, -1, 14, -1, -1, 24, 25, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 diff --git a/src/autogen/MPH_to_AudioRecorder.h b/src/autogen/MPH_to_AudioRecorder.h index d4759de..8759114 100644 --- a/src/autogen/MPH_to_AudioRecorder.h +++ b/src/autogen/MPH_to_AudioRecorder.h @@ -3,4 +3,4 @@ -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 12, 13 diff --git a/src/autogen/MPH_to_Engine.h b/src/autogen/MPH_to_Engine.h index c3a9e23..b47d4f2 100644 --- a/src/autogen/MPH_to_Engine.h +++ b/src/autogen/MPH_to_Engine.h @@ -3,4 +3,4 @@ -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 12, -1, -1, -1, -1 + -1, -1, -1, -1, -1, 12, -1, -1, -1, -1, -1, -1, -1 diff --git a/src/autogen/MPH_to_LEDDevice.h b/src/autogen/MPH_to_LEDDevice.h index d315c8f..8fab008 100644 --- a/src/autogen/MPH_to_LEDDevice.h +++ b/src/autogen/MPH_to_LEDDevice.h @@ -3,4 +3,4 @@ 2, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 diff --git a/src/autogen/MPH_to_Listener.h b/src/autogen/MPH_to_Listener.h index fbfc8da..0ccb8d4 100644 --- a/src/autogen/MPH_to_Listener.h +++ b/src/autogen/MPH_to_Listener.h @@ -3,4 +3,4 @@ -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 diff --git a/src/autogen/MPH_to_MediaPlayer.h b/src/autogen/MPH_to_MediaPlayer.h index 4b11c6a..4dbd600 100644 --- a/src/autogen/MPH_to_MediaPlayer.h +++ b/src/autogen/MPH_to_MediaPlayer.h @@ -3,4 +3,4 @@ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 2, -1, 6, -1, -1, -1, - 5, -1, 3, -1, -1, -1, -1, -1, -1, 4 + 5, -1, 3, -1, -1, -1, -1, -1, -1, 4, -1, -1, -1 diff --git a/src/autogen/MPH_to_MetadataExtractor.h b/src/autogen/MPH_to_MetadataExtractor.h index 9db501b..fcf01bb 100644 --- a/src/autogen/MPH_to_MetadataExtractor.h +++ b/src/autogen/MPH_to_MetadataExtractor.h @@ -3,4 +3,4 @@ -1, 3, 4, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 diff --git a/src/autogen/MPH_to_MidiPlayer.h b/src/autogen/MPH_to_MidiPlayer.h index 6d33f3c..7effb5e 100644 --- a/src/autogen/MPH_to_MidiPlayer.h +++ b/src/autogen/MPH_to_MidiPlayer.h @@ -3,4 +3,4 @@ -1, 10, 11, 12, 15, 14, 13, 9, -1, 0, -1, 24, 2, 26, 16, 25, -1, -1, 17, -1, -1, 27, 28, 18, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 diff --git a/src/autogen/MPH_to_OutputMix.h b/src/autogen/MPH_to_OutputMix.h index 5767d66..1624f85 100644 --- a/src/autogen/MPH_to_OutputMix.h +++ b/src/autogen/MPH_to_OutputMix.h @@ -3,4 +3,4 @@ -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 2, -1, -1, -1, -1, 6, -1, -1, -1, -1, -1, 7, 10, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 diff --git a/src/autogen/MPH_to_Vibra.h b/src/autogen/MPH_to_Vibra.h index 269adb8..9947707 100644 --- a/src/autogen/MPH_to_Vibra.h +++ b/src/autogen/MPH_to_Vibra.h @@ -3,4 +3,4 @@ -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 diff --git a/src/classes.c b/src/classes.c index bf707bd..693ed40 100644 --- a/src/classes.c +++ b/src/classes.c @@ -123,6 +123,11 @@ static const struct iid_vtable AudioRecorder_interfaces[INTERFACES_AudioRecorder {MPH_EQUALIZER, INTERFACE_DYNAMIC_OPTIONAL, offsetof(CAudioRecorder, mEqualizer)}, {MPH_VISUALIZATION, INTERFACE_OPTIONAL, offsetof(CAudioRecorder, mVisualization)}, {MPH_VOLUME, INTERFACE_OPTIONAL, offsetof(CAudioRecorder, mVolume)}, + {MPH_ANDROIDACOUSTICECHOCANCELLATION, INTERFACE_OPTIONAL, offsetof(CAudioRecorder, + mAcousticEchoCancellation)}, + {MPH_ANDROIDAUTOMATICGAINCONTROL, INTERFACE_OPTIONAL, offsetof(CAudioRecorder, + mAutomaticGainControl)}, + {MPH_ANDROIDNOISESUPPRESSION, INTERFACE_OPTIONAL, offsetof(CAudioRecorder, mNoiseSuppression)}, #ifdef ANDROID {MPH_ANDROIDSIMPLEBUFFERQUEUE, INTERFACE_EXPLICIT, offsetof(CAudioRecorder, mBufferQueue)}, {MPH_ANDROIDCONFIGURATION, INTERFACE_EXPLICIT_PREREALIZE, diff --git a/src/classes.h b/src/classes.h index 977772d..62bcf5d 100644 --- a/src/classes.h +++ b/src/classes.h @@ -120,7 +120,7 @@ // mandated interfaces IObject mObject; #ifdef ANDROID -#define INTERFACES_AudioRecorder 11 // see MPH_to_AudioRecorder in MPH_to.c for list of interfaces +#define INTERFACES_AudioRecorder 14 // see MPH_to_AudioRecorder in MPH_to.c for list of interfaces #else #define INTERFACES_AudioRecorder 9 // see MPH_to_AudioRecorder in MPH_to.c for list of interfaces #endif @@ -134,6 +134,9 @@ IEqualizer mEqualizer; IVisualization mVisualization; IVolume mVolume; + IAndroidAcousticEchoCancellation mAcousticEchoCancellation; + IAndroidAutomaticGainControl mAutomaticGainControl; + IAndroidNoiseSuppression mNoiseSuppression; #ifdef ANDROID IBufferQueue mBufferQueue; IAndroidConfiguration mAndroidConfiguration; diff --git a/src/interfaces.c b/src/interfaces.c index b0cbd9d..0785d10 100644 --- a/src/interfaces.c +++ b/src/interfaces.c @@ -123,6 +123,11 @@ const char * const interface_names[MPH_MAX] = { "XAVIDEOPOSTPROCESSING", "XAVOLUME", + // Android API level 20 extended interfaces + "ANDROIDACOUSTICECHOCANCELLATION", + "ANDROIDAUTOMATICGAINCONTROL", + "ANDROIDNOISESUPPRESSION", + }; diff --git a/src/itf/IAcousticEchoCancellation.c b/src/itf/IAcousticEchoCancellation.c new file mode 100644 index 0000000..728d776 --- /dev/null +++ b/src/itf/IAcousticEchoCancellation.c @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2014 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. + */ + +/* Acoustic Echo Cancellation implementation */ +#include "sles_allinclusive.h" + +#include <media/EffectsFactoryApi.h> + +#include <audio_effects/effect_aec.h> + +/** + * returns true if this interface is not associated with an initialized AEC effect + */ +static inline bool NO_ECHOCANCEL(IAndroidAcousticEchoCancellation* v) { + return (v->mAECEffect == 0); +} + +static SLresult IAndroidAcousticEchoCancellation_SetEnabled(SLAndroidAcousticEchoCancellationItf self, + SLboolean enabled) +{ + SL_ENTER_INTERFACE + + IAndroidAcousticEchoCancellation *thiz = (IAndroidAcousticEchoCancellation *) self; + interface_lock_exclusive(thiz); + thiz->mEnabled = (SLboolean) enabled; + if (NO_ECHOCANCEL(thiz)) { + result = SL_RESULT_CONTROL_LOST; + } else { + android::status_t status = thiz->mAECEffect->setEnabled((bool) thiz->mEnabled); + result = android_fx_statusToResult(status); + } + interface_unlock_exclusive(thiz); + + SL_LEAVE_INTERFACE +} + +static SLresult IAndroidAcousticEchoCancellation_IsEnabled(SLAndroidAcousticEchoCancellationItf self, + SLboolean *pEnabled) +{ + SL_ENTER_INTERFACE + + if (NULL == pEnabled) { + result = SL_RESULT_PARAMETER_INVALID; + } else { + IAndroidAcousticEchoCancellation *thiz = (IAndroidAcousticEchoCancellation *) self; + interface_lock_exclusive(thiz); + SLboolean enabled = thiz->mEnabled; + if (NO_ECHOCANCEL(thiz)) { + result = SL_RESULT_CONTROL_LOST; + } else { + *pEnabled = (SLboolean) thiz->mAECEffect->getEnabled(); + result = SL_RESULT_SUCCESS; + } + interface_unlock_exclusive(thiz); + } + + SL_LEAVE_INTERFACE +} + +SLresult IAndroidAcousticEchoCancellation_IsAvailable(SLAndroidAcousticEchoCancellationItf self, + SLboolean *pEnabled) +{ + SL_ENTER_INTERFACE + + *pEnabled = false; + + uint32_t numEffects = 0; + int ret = EffectQueryNumberEffects(&numEffects); + if (ret != 0) { + ALOGE("IAndroidAcousticEchoCancellation_IsAvailable() error %d querying number of effects", + ret); + result = SL_RESULT_FEATURE_UNSUPPORTED; + } else { + ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects); + + effect_descriptor_t fxDesc; + for (uint32_t i = 0 ; i < numEffects ; i++) { + if (EffectQueryEffect(i, &fxDesc) == 0) { + ALOGV("effect %d is called %s", i, fxDesc.name); + if (memcmp(&fxDesc.type, SL_IID_ANDROIDACOUSTICECHOCANCELLATION, + sizeof(effect_uuid_t)) == 0) { + ALOGI("found effect \"%s\" from %s", fxDesc.name, fxDesc.implementor); + *pEnabled = true; + break; + } + } + } + result = SL_RESULT_SUCCESS; + } + SL_LEAVE_INTERFACE +} + +static const struct SLAndroidAcousticEchoCancellationItf_ IAndroidAcousticEchoCancellation_Itf = { + IAndroidAcousticEchoCancellation_SetEnabled, + IAndroidAcousticEchoCancellation_IsEnabled, + IAndroidAcousticEchoCancellation_IsAvailable +}; + +void IAndroidAcousticEchoCancellation_init(void *self) +{ + IAndroidAcousticEchoCancellation *thiz = (IAndroidAcousticEchoCancellation *) self; + thiz->mItf = &IAndroidAcousticEchoCancellation_Itf; + thiz->mEnabled = SL_BOOLEAN_FALSE; + memset(&thiz->mAECDescriptor, 0, sizeof(effect_descriptor_t)); + // placement new (explicit constructor) + (void) new (&thiz->mAECEffect) android::sp<android::AudioEffect>(); +} + +void IAndroidAcousticEchoCancellation_deinit(void *self) +{ + IAndroidAcousticEchoCancellation *thiz = (IAndroidAcousticEchoCancellation *) self; + // explicit destructor + thiz->mAECEffect.~sp(); +} + +bool IAndroidAcousticEchoCancellation_Expose(void *self) +{ + IAndroidAcousticEchoCancellation *thiz = (IAndroidAcousticEchoCancellation *) self; + if (!android_fx_initEffectDescriptor(SL_IID_ANDROIDACOUSTICECHOCANCELLATION, + &thiz->mAECDescriptor)) { + SL_LOGE("Acoustic Echo Cancellation initialization failed."); + return false; + } + return true; +} diff --git a/src/itf/IAutomaticGainControl.c b/src/itf/IAutomaticGainControl.c new file mode 100644 index 0000000..8512436 --- /dev/null +++ b/src/itf/IAutomaticGainControl.c @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2014 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. + */ + +/* Automatic Gain Control implementation */ +#include "sles_allinclusive.h" + +#include <media/EffectsFactoryApi.h> + +#include <audio_effects/effect_agc.h> + +/** + * returns true if this interface is not associated with an initialized AGC effect + */ +static inline bool NO_AUTOGAIN(IAndroidAutomaticGainControl* v) { + return (v->mAGCEffect == 0); +} + +SLresult IAndroidAutomaticGainControl_SetEnabled(SLAndroidAutomaticGainControlItf self, SLboolean enabled) +{ + SL_ENTER_INTERFACE + + IAndroidAutomaticGainControl *thiz = (IAndroidAutomaticGainControl *) self; + interface_lock_exclusive(thiz); + thiz->mEnabled = (SLboolean) enabled; + if (NO_AUTOGAIN(thiz)) { + result = SL_RESULT_CONTROL_LOST; + } else { + android::status_t status = thiz->mAGCEffect->setEnabled((bool) thiz->mEnabled); + result = android_fx_statusToResult(status); + } + interface_unlock_exclusive(thiz); + + SL_LEAVE_INTERFACE +} + +SLresult IAndroidAutomaticGainControl_IsEnabled(SLAndroidAutomaticGainControlItf self, SLboolean *pEnabled) +{ + SL_ENTER_INTERFACE + + if (NULL == pEnabled) { + result = SL_RESULT_PARAMETER_INVALID; + } else { + IAndroidAutomaticGainControl *thiz = (IAndroidAutomaticGainControl *) self; + interface_lock_exclusive(thiz); + SLboolean enabled = thiz->mEnabled; + if (NO_AUTOGAIN(thiz)) { + result = SL_RESULT_CONTROL_LOST; + } else { + *pEnabled = (SLboolean) thiz->mAGCEffect->getEnabled(); + result = SL_RESULT_SUCCESS; + } + interface_unlock_exclusive(thiz); + } + SL_LEAVE_INTERFACE +} + +SLresult IAndroidAutomaticGainControl_IsAvailable(SLAndroidAutomaticGainControlItf self, + SLboolean *pEnabled) +{ + SL_ENTER_INTERFACE + + *pEnabled = false; + + uint32_t numEffects = 0; + int ret = EffectQueryNumberEffects(&numEffects); + if (ret != 0) { + ALOGE("IAndroidAutomaticGainControl_IsAvailable() error %d querying number of effects", + ret); + result = SL_RESULT_FEATURE_UNSUPPORTED; + } else { + ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects); + + effect_descriptor_t fxDesc; + for (uint32_t i = 0 ; i < numEffects ; i++) { + if (EffectQueryEffect(i, &fxDesc) == 0) { + ALOGV("effect %d is called %s", i, fxDesc.name); + if (memcmp(&fxDesc.type, SL_IID_ANDROIDAUTOMATICGAINCONTROL, + sizeof(effect_uuid_t)) == 0) { + ALOGI("found effect \"%s\" from %s", fxDesc.name, fxDesc.implementor); + *pEnabled = true; + break; + } + } + } + result = SL_RESULT_SUCCESS; + } + SL_LEAVE_INTERFACE +} + +static const struct SLAndroidAutomaticGainControlItf_ IAndroidAutomaticGainControl_Itf = { + IAndroidAutomaticGainControl_SetEnabled, + IAndroidAutomaticGainControl_IsEnabled, + IAndroidAutomaticGainControl_IsAvailable +}; + +void IAndroidAutomaticGainControl_init(void *self) +{ + IAndroidAutomaticGainControl *thiz = (IAndroidAutomaticGainControl *) self; + thiz->mItf = &IAndroidAutomaticGainControl_Itf; + thiz->mEnabled = SL_BOOLEAN_FALSE; + memset(&thiz->mAGCDescriptor, 0, sizeof(effect_descriptor_t)); + // placement new (explicit constructor) + (void) new (&thiz->mAGCEffect) android::sp<android::AudioEffect>(); +} + +void IAndroidAutomaticGainControl_deinit(void *self) +{ + IAndroidAutomaticGainControl *thiz = (IAndroidAutomaticGainControl *) self; + // explicit destructor + thiz->mAGCEffect.~sp(); +} + +bool IAndroidAutomaticGainControl_Expose(void *self) +{ + IAndroidAutomaticGainControl *thiz = (IAndroidAutomaticGainControl *) self; + if (!android_fx_initEffectDescriptor(SL_IID_ANDROIDAUTOMATICGAINCONTROL, + &thiz->mAGCDescriptor)) { + SL_LOGE("Automatic Gain Control initialization failed."); + return false; + } + return true; +} diff --git a/src/itf/INoiseSuppression.c b/src/itf/INoiseSuppression.c new file mode 100644 index 0000000..d67050f --- /dev/null +++ b/src/itf/INoiseSuppression.c @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2014 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. + */ + +/* Automatic Gain Control implementation */ +#include "sles_allinclusive.h" + +#include <media/EffectsFactoryApi.h> + +#include <audio_effects/effect_ns.h> +/** + * returns true if this interface is not associated with an initialized Noise Suppression effect + */ +static inline bool NO_NOISESUPPRESS(IAndroidNoiseSuppression* v) { + return (v->mNSEffect == 0); +} + +SLresult IAndroidNoiseSuppression_SetEnabled(SLAndroidNoiseSuppressionItf self, SLboolean enabled) +{ + SL_ENTER_INTERFACE + + IAndroidNoiseSuppression *thiz = (IAndroidNoiseSuppression *) self; + interface_lock_exclusive(thiz); + thiz->mEnabled = (SLboolean) enabled; + if (NO_NOISESUPPRESS(thiz)) { + result = SL_RESULT_CONTROL_LOST; + } else { + android::status_t status = thiz->mNSEffect->setEnabled((bool) thiz->mEnabled); + result = android_fx_statusToResult(status); + } + interface_unlock_exclusive(thiz); + + SL_LEAVE_INTERFACE +} + +SLresult IAndroidNoiseSuppression_IsEnabled(SLAndroidNoiseSuppressionItf self, SLboolean *pEnabled) +{ + SL_ENTER_INTERFACE + + if (NULL == pEnabled) { + result = SL_RESULT_PARAMETER_INVALID; + } else { + IAndroidNoiseSuppression *thiz = (IAndroidNoiseSuppression *) self; + interface_lock_exclusive(thiz); + SLboolean enabled = thiz->mEnabled; + if (NO_NOISESUPPRESS(thiz)) { + result = SL_RESULT_CONTROL_LOST; + } else { + *pEnabled = (SLboolean) thiz->mNSEffect->getEnabled(); + result = SL_RESULT_SUCCESS; + } + interface_unlock_exclusive(thiz); + } + SL_LEAVE_INTERFACE +} + +SLresult IAndroidNoiseSuppression_IsAvailable(SLAndroidNoiseSuppressionItf self, + SLboolean *pEnabled) +{ + SL_ENTER_INTERFACE + + *pEnabled = false; + + uint32_t numEffects = 0; + int ret = EffectQueryNumberEffects(&numEffects); + if (ret != 0) { + ALOGE("IAndroidNoiseSuppression_IsAvailable() error %d querying number of effects", ret); + result = SL_RESULT_FEATURE_UNSUPPORTED; + } else { + ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects); + + effect_descriptor_t fxDesc; + for (uint32_t i = 0 ; i < numEffects ; i++) { + if (EffectQueryEffect(i, &fxDesc) == 0) { + ALOGV("effect %d is called %s", i, fxDesc.name); + if (memcmp(&fxDesc.type, SL_IID_ANDROIDNOISESUPPRESSION, + sizeof(effect_uuid_t)) == 0) { + ALOGI("found effect \"%s\" from %s", fxDesc.name, fxDesc.implementor); + *pEnabled = true; + break; + } + } + } + result = SL_RESULT_SUCCESS; + } + SL_LEAVE_INTERFACE +} + +static const struct SLAndroidNoiseSuppressionItf_ IAndroidNoiseSuppression_Itf = { + IAndroidNoiseSuppression_SetEnabled, + IAndroidNoiseSuppression_IsEnabled, + IAndroidNoiseSuppression_IsAvailable +}; + +void IAndroidNoiseSuppression_init(void *self) +{ + IAndroidNoiseSuppression *thiz = (IAndroidNoiseSuppression *) self; + thiz->mItf = &IAndroidNoiseSuppression_Itf; + thiz->mEnabled = SL_BOOLEAN_FALSE; + memset(&thiz->mNSDescriptor, 0, sizeof(effect_descriptor_t)); + // placement new (explicit constructor) + (void) new (&thiz->mNSEffect) android::sp<android::AudioEffect>(); +} + +void IAndroidNoiseSuppression_deinit(void *self) +{ + IAndroidNoiseSuppression *thiz = (IAndroidNoiseSuppression *) self; + // explicit destructor + thiz->mNSEffect.~sp(); +} + +bool IAndroidNoiseSuppression_Expose(void *self) +{ + IAndroidNoiseSuppression *thiz = (IAndroidNoiseSuppression *) self; + if (!android_fx_initEffectDescriptor(SL_IID_ANDROIDNOISESUPPRESSION, &thiz->mNSDescriptor)) { + SL_LOGE("Noise Suppression initialization failed."); + return false; + } + return true; +} diff --git a/src/itfstruct.h b/src/itfstruct.h index 36d7565..1712a87 100644 --- a/src/itfstruct.h +++ b/src/itfstruct.h @@ -675,4 +675,28 @@ typedef struct { bool mEOS; // whether EOS has been enqueued; never reset } IAndroidBufferQueue; +typedef struct { + const struct SLAndroidAcousticEchoCancellationItf_ *mItf; + IObject *mThis; + SLboolean mEnabled; + effect_descriptor_t mAECDescriptor; + android::sp<android::AudioEffect> mAECEffect; +} IAndroidAcousticEchoCancellation; + +typedef struct { + const struct SLAndroidAutomaticGainControlItf_ *mItf; + IObject *mThis; + SLboolean mEnabled; + effect_descriptor_t mAGCDescriptor; + android::sp<android::AudioEffect> mAGCEffect; +} IAndroidAutomaticGainControl; + +typedef struct { + const struct SLAndroidNoiseSuppressionItf_ *mItf; + IObject *mThis; + SLboolean mEnabled; + effect_descriptor_t mNSDescriptor; + android::sp<android::AudioEffect> mNSEffect; +} IAndroidNoiseSuppression; + #endif diff --git a/src/sl_iid.c b/src/sl_iid.c index 0207899..b82a0fe 100644 --- a/src/sl_iid.c +++ b/src/sl_iid.c @@ -82,6 +82,12 @@ const SLInterfaceID SL_IID_ANDROIDSIMPLEBUFFERQUEUE = &SL_IID_array[MPH_ANDROIDS // GUID and MPH are shared by SL and XA const SLInterfaceID SL_IID_ANDROIDBUFFERQUEUESOURCE = &SL_IID_array[MPH_ANDROIDBUFFERQUEUESOURCE]; +const SLInterfaceID SL_IID_ANDROIDACOUSTICECHOCANCELLATION = + &SL_IID_array[MPH_ANDROIDACOUSTICECHOCANCELLATION]; +const SLInterfaceID SL_IID_ANDROIDAUTOMATICGAINCONTROL = + &SL_IID_array[MPH_ANDROIDAUTOMATICGAINCONTROL]; +const SLInterfaceID SL_IID_ANDROIDNOISESUPPRESSION = &SL_IID_array[MPH_ANDROIDNOISESUPPRESSION]; + #ifdef __cplusplus } #endif @@ -237,6 +237,8 @@ extern void I3DLocation_init(void *), I3DMacroscopic_init(void *), I3DSource_init(void *), + IAndroidAcousticEchoCancellation_init(void *), + IAndroidAutomaticGainControl_init(void *), IAndroidConfiguration_init(void *), IAndroidEffect_init(void *), IAndroidEffectCapabilities_init(void *), @@ -264,6 +266,7 @@ extern void IMetadataExtraction_init(void *), IMetadataTraversal_init(void *), IMuteSolo_init(void *), + IAndroidNoiseSuppression_init(void *), IObject_init(void *), IOutputMix_init(void *), IOutputMixExt_init(void *), @@ -283,9 +286,12 @@ extern void extern void I3DGrouping_deinit(void *), + IAndroidAcousticEchoCancellation_deinit(void *), + IAndroidAutomaticGainControl_deinit(void *), IAndroidEffect_deinit(void *), IAndroidEffectCapabilities_deinit(void *), IAndroidBufferQueue_deinit(void *), + IAndroidNoiseSuppression_deinit(void*), IBassBoost_deinit(void *), IBufferQueue_deinit(void *), IEngine_deinit(void *), @@ -297,7 +303,10 @@ extern void IVirtualizer_deinit(void *); extern bool + IAndroidAcousticEchoCancellation_Expose(void *), + IAndroidAutomaticGainControl_Expose(void *), IAndroidEffectCapabilities_Expose(void *), + IAndroidNoiseSuppression_Expose(void *), IBassBoost_Expose(void *), IEnvironmentalReverb_Expose(void *), IEqualizer_Expose(void *), @@ -479,6 +488,13 @@ extern bool { /* MPH_XAVIDEOENCODERCAPABILITIES */ NULL, NULL, NULL, NULL, NULL }, { /* MPH_XAVIDEOPOSTPROCESSING */ NULL, NULL, NULL, NULL, NULL }, { /* MPH_XAVOLUME, */ IVolume_init, NULL, NULL, NULL, NULL }, + { /* MPH_ANDROIDACOUSTICECHOCANCELLATION, */ IAndroidAcousticEchoCancellation_init, NULL, + IAndroidAcousticEchoCancellation_deinit, IAndroidAcousticEchoCancellation_Expose, + NULL }, + { /* MPH_ANDROIDAUTOMATICGAINCONTROL, */ IAndroidAutomaticGainControl_init, NULL, + IAndroidAutomaticGainControl_deinit, IAndroidAutomaticGainControl_Expose, NULL }, + { /* MPH_ANDROIDNOISESUPPRESSION, */ IAndroidNoiseSuppression_init, NULL, + IAndroidNoiseSuppression_deinit, IAndroidNoiseSuppression_Expose, NULL }, }; diff --git a/src/ut/OpenSLESUT.c b/src/ut/OpenSLESUT.c index d6c2114..f7f6353 100644 --- a/src/ut/OpenSLESUT.c +++ b/src/ut/OpenSLESUT.c @@ -93,7 +93,10 @@ static Pair pairs[] = { _(ANDROIDEFFECTCAPABILITIES), _(ANDROIDEFFECTSEND), _(ANDROIDCONFIGURATION), - _(ANDROIDSIMPLEBUFFERQUEUE) + _(ANDROIDSIMPLEBUFFERQUEUE), + _(ANDROIDACOUSTICECHOCANCELLATION), + _(ANDROIDAUTOMATICGAINCONTROL), + _(ANDROIDNOISESUPPRESSION) #endif }; |
