From 7c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Fri, 17 Jun 2011 21:29:58 -0700 Subject: Audio framework: support for audio pre processing Audio effect framework is extended to suport effects on output and input audio path. AudioFlinger: Support for audio effects and effect chains is moved from PlaybackThread class to ThreadBase class so that RecordThread can manage effects. Effects of type pre processing are allowed on record thread only. When a pre processing is enabled, the effect interface handle is passed down to the input stream so that the audio HAL can call the process function. The record thread loop calls the effect chain process function that will only manage the effect state and commands and skip the process function. AudioRecord: The audio session is allocated before calling getInput() into audio policy serice so that the session is known before the input theead is created and pre processings can be created on the correct session. AudioPolicyService: default pre processing for a given input source are loaded from audio_effects.conf file. When an input is created, corresponding effects are created and enabled. Change-Id: Id17119e0979b4dcf189b5c7957fec30dc3478790 --- media/libeffects/data/audio_effects.conf | 69 +++++++++++++++++++++++++++++++ media/libeffects/factory/Android.mk | 3 ++ media/libeffects/factory/EffectsFactory.c | 1 + media/libeffects/factory/EffectsFactory.h | 7 ---- media/libmedia/AudioEffect.cpp | 14 +++---- media/libmedia/AudioRecord.cpp | 21 +++++++--- media/libmedia/AudioSystem.cpp | 13 +++--- media/libmedia/IAudioPolicyService.cpp | 16 ++++--- 8 files changed, 114 insertions(+), 30 deletions(-) (limited to 'media') diff --git a/media/libeffects/data/audio_effects.conf b/media/libeffects/data/audio_effects.conf index e6a7b37..b8fa487 100644 --- a/media/libeffects/data/audio_effects.conf +++ b/media/libeffects/data/audio_effects.conf @@ -1,5 +1,10 @@ # List of effect libraries to load. Each library element must contain a "path" element # giving the full path of the library .so file. +# libraries { +# { +# path +# } +# } libraries { bundle { path /system/lib/soundfx/libbundlewrapper.so @@ -10,6 +15,9 @@ libraries { visualizer { path /system/lib/soundfx/libvisualizer.so } + pre_processing { + path /system/lib/soundfx/libaudiopreprocessing.so + } } # list of effects to load. Each effect element must contain a "library" and a "uuid" element. @@ -17,6 +25,16 @@ libraries { # "libraries" element. # The name of the effect element is indicative, only the value of the "uuid" element # designates the effect. +# The uuid is the implementation specific UUID as specified by the effect vendor. This is not the +# generic effect type UUID. +# effects { +# { +# library +# uuid +# } +# ... +# } + effects { bassboost { library bundle @@ -54,4 +72,55 @@ effects { library visualizer uuid d069d9e0-8329-11df-9168-0002a5d5c51b } + agc { + library pre_processing + uuid aa8130e0-66fc-11e0-bad0-0002a5d5c51b + } + aec { + library pre_processing + uuid bb392ec0-8d4d-11e0-a896-0002a5d5c51b + } + ns { + library pre_processing + uuid c06c8400-8e06-11e0-9cb6-0002a5d5c51b + } } +# Audio preprocessor configurations. +# The pre processor configuration consists in a list of elements each describing +# pre processor settings for a given input source. Valid input source names are: +# "mic", "camcorder", "voice_recognition", "voice_communication" +# Each input source element contains a list of effects elements. The name of the effect +# element must be the name of one of the effects in the "effects" list of the file. +# Each effect element may optionally contain a list of parameters and their +# default value to apply when the pre processor effect is created. +# A parameter is defined by a "param" element and a "value" element. Each of these elements +# consists in one or more elements specifying a type followed by a value. +# The types defined are: "int", "short", "float", "bool" and "string" +# When both "param" and "value" are a single int, a simple form is allowed where just +# the param and value pair is present in the parameter description +# pre_processing { +# { +# { +# { +# param { +# int|short|float|bool|string +# [ int|short|float|bool|string ] +# ... +# } +# value { +# int|short|float|bool|string +# [ int|short|float|bool|string ] +# ... +# } +# } +# { } +# ... +# } +# ... +# } +# ... +# } + +# +# TODO: add default audio pre processor configurations after debug and tuning phase +# diff --git a/media/libeffects/factory/Android.mk b/media/libeffects/factory/Android.mk index 26265ae..2f2b974 100644 --- a/media/libeffects/factory/Android.mk +++ b/media/libeffects/factory/Android.mk @@ -14,4 +14,7 @@ LOCAL_MODULE:= libeffects LOCAL_SHARED_LIBRARIES += libdl +LOCAL_C_INCLUDES := \ + system/media/audio_effects/include + include $(BUILD_SHARED_LIBRARY) diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c index a9689bc..d333510 100644 --- a/media/libeffects/factory/EffectsFactory.c +++ b/media/libeffects/factory/EffectsFactory.c @@ -24,6 +24,7 @@ #include #include +#include static list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects static list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries diff --git a/media/libeffects/factory/EffectsFactory.h b/media/libeffects/factory/EffectsFactory.h index fcc0dba..c1d4319 100644 --- a/media/libeffects/factory/EffectsFactory.h +++ b/media/libeffects/factory/EffectsFactory.h @@ -26,13 +26,6 @@ extern "C" { #endif -#define AUDIO_EFFECT_DEFAULT_CONFIG_FILE "/system/etc/audio_effects.conf" -#define AUDIO_EFFECT_VENDOR_CONFIG_FILE "/vendor/etc/audio_effects.conf" -#define EFFECTS_TAG "effects" -#define LIBRARIES_TAG "libraries" -#define PATH_TAG "path" -#define LIBRARY_TAG "library" -#define UUID_TAG "uuid" typedef struct list_elem_s { void *object; diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp index 8d98900..3919551 100644 --- a/media/libmedia/AudioEffect.cpp +++ b/media/libmedia/AudioEffect.cpp @@ -47,11 +47,11 @@ AudioEffect::AudioEffect(const effect_uuid_t *type, effect_callback_t cbf, void* user, int sessionId, - audio_io_handle_t output + audio_io_handle_t io ) : mStatus(NO_INIT) { - mStatus = set(type, uuid, priority, cbf, user, sessionId, output); + mStatus = set(type, uuid, priority, cbf, user, sessionId, io); } AudioEffect::AudioEffect(const char *typeStr, @@ -60,7 +60,7 @@ AudioEffect::AudioEffect(const char *typeStr, effect_callback_t cbf, void* user, int sessionId, - audio_io_handle_t output + audio_io_handle_t io ) : mStatus(NO_INIT) { @@ -83,7 +83,7 @@ AudioEffect::AudioEffect(const char *typeStr, } } - mStatus = set(pType, pUuid, priority, cbf, user, sessionId, output); + mStatus = set(pType, pUuid, priority, cbf, user, sessionId, io); } status_t AudioEffect::set(const effect_uuid_t *type, @@ -92,13 +92,13 @@ status_t AudioEffect::set(const effect_uuid_t *type, effect_callback_t cbf, void* user, int sessionId, - audio_io_handle_t output) + audio_io_handle_t io) { sp iEffect; sp cblk; int enabled; - LOGV("set %p mUserData: %p", this, user); + LOGV("set %p mUserData: %p uuid: %p timeLow %08x", this, user, type, type ? type->timeLow : 0); if (mIEffect != 0) { LOGW("Effect already in use"); @@ -135,7 +135,7 @@ status_t AudioEffect::set(const effect_uuid_t *type, mIEffectClient = new EffectClient(this); iEffect = audioFlinger->createEffect(getpid(), (effect_descriptor_t *)&mDescriptor, - mIEffectClient, priority, output, mSessionId, &mStatus, &mId, &enabled); + mIEffectClient, priority, io, mSessionId, &mStatus, &mId, &enabled); if (iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) { LOGE("set(): AudioFlinger could not create effect, status: %d", mStatus); diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index 4c4aad0..1ec596e 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -162,8 +162,19 @@ status_t AudioRecord::set( int channelCount = popcount(channelMask); + if (sessionId == 0 ) { + mSessionId = AudioSystem::newAudioSessionId(); + } else { + mSessionId = sessionId; + } + LOGV("set(): mSessionId %d", mSessionId); + audio_io_handle_t input = AudioSystem::getInput(inputSource, - sampleRate, format, channelMask, (audio_in_acoustics_t)flags); + sampleRate, + format, + channelMask, + (audio_in_acoustics_t)flags, + mSessionId); if (input == 0) { LOGE("Could not get audio input for record source %d", inputSource); return BAD_VALUE; @@ -187,8 +198,6 @@ status_t AudioRecord::set( notificationFrames = frameCount/2; } - mSessionId = sessionId; - // create the IAudioRecord status = openRecord_l(sampleRate, format, channelMask, frameCount, flags, input); @@ -589,8 +598,10 @@ audio_io_handle_t AudioRecord::getInput_l() { mInput = AudioSystem::getInput(mInputSource, mCblk->sampleRate, - mFormat, mChannelMask, - (audio_in_acoustics_t)mFlags); + mFormat, + mChannelMask, + (audio_in_acoustics_t)mFlags, + mSessionId); return mInput; } diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index 6cb3847..5009957 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -605,11 +605,12 @@ audio_io_handle_t AudioSystem::getInput(int inputSource, uint32_t samplingRate, uint32_t format, uint32_t channels, - audio_in_acoustics_t acoustics) + audio_in_acoustics_t acoustics, + int sessionId) { const sp& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return 0; - return aps->getInput(inputSource, samplingRate, format, channels, acoustics); + return aps->getInput(inputSource, samplingRate, format, channels, acoustics, sessionId); } status_t AudioSystem::startInput(audio_io_handle_t input) @@ -678,14 +679,14 @@ audio_io_handle_t AudioSystem::getOutputForEffect(effect_descriptor_t *desc) } status_t AudioSystem::registerEffect(effect_descriptor_t *desc, - audio_io_handle_t output, + audio_io_handle_t io, uint32_t strategy, int session, int id) { const sp& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return PERMISSION_DENIED; - return aps->registerEffect(desc, output, strategy, session, id); + return aps->registerEffect(desc, io, strategy, session, id); } status_t AudioSystem::unregisterEffect(int id) @@ -695,9 +696,11 @@ status_t AudioSystem::unregisterEffect(int id) return aps->unregisterEffect(id); } -status_t AudioSystem::isStreamActive(int stream, bool* state, uint32_t inPastMs) { +status_t AudioSystem::isStreamActive(int stream, bool* state, uint32_t inPastMs) +{ const sp& aps = AudioSystem::get_audio_policy_service(); if (aps == 0) return PERMISSION_DENIED; + if (state == NULL) return BAD_VALUE; *state = aps->isStreamActive(stream, inPastMs); return NO_ERROR; } diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp index 9fbcee0..49d410f 100644 --- a/media/libmedia/IAudioPolicyService.cpp +++ b/media/libmedia/IAudioPolicyService.cpp @@ -184,7 +184,8 @@ public: uint32_t samplingRate, uint32_t format, uint32_t channels, - audio_in_acoustics_t acoustics) + audio_in_acoustics_t acoustics, + int audioSession) { Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); @@ -193,6 +194,7 @@ public: data.writeInt32(static_cast (format)); data.writeInt32(channels); data.writeInt32(static_cast (acoustics)); + data.writeInt32(audioSession); remote()->transact(GET_INPUT, data, &reply); return static_cast (reply.readInt32()); } @@ -285,7 +287,7 @@ public: } virtual status_t registerEffect(effect_descriptor_t *desc, - audio_io_handle_t output, + audio_io_handle_t io, uint32_t strategy, int session, int id) @@ -293,7 +295,7 @@ public: Parcel data, reply; data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor()); data.write(desc, sizeof(effect_descriptor_t)); - data.writeInt32(output); + data.writeInt32(io); data.writeInt32(strategy); data.writeInt32(session); data.writeInt32(id); @@ -439,11 +441,13 @@ status_t BnAudioPolicyService::onTransact( uint32_t channels = data.readInt32(); audio_in_acoustics_t acoustics = static_cast (data.readInt32()); + int audioSession = data.readInt32(); audio_io_handle_t input = getInput(inputSource, samplingRate, format, channels, - acoustics); + acoustics, + audioSession); reply->writeInt32(static_cast (input)); return NO_ERROR; } break; @@ -528,12 +532,12 @@ status_t BnAudioPolicyService::onTransact( CHECK_INTERFACE(IAudioPolicyService, data, reply); effect_descriptor_t desc; data.read(&desc, sizeof(effect_descriptor_t)); - audio_io_handle_t output = data.readInt32(); + audio_io_handle_t io = data.readInt32(); uint32_t strategy = data.readInt32(); int session = data.readInt32(); int id = data.readInt32(); reply->writeInt32(static_cast (registerEffect(&desc, - output, + io, strategy, session, id))); -- cgit v1.1