/* * Copyright (C) 2009 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. */ #ifndef ANDROID_AUDIOEFFECT_H #define ANDROID_AUDIOEFFECT_H #include <stdint.h> #include <sys/types.h> #include <media/IAudioFlinger.h> #include <media/IAudioPolicyService.h> #include <media/IEffect.h> #include <media/IEffectClient.h> #include <media/AudioSystem.h> #include <system/audio_effect.h> #include <utils/RefBase.h> #include <utils/Errors.h> #include <binder/IInterface.h> namespace android { // ---------------------------------------------------------------------------- struct effect_param_cblk_t; // ---------------------------------------------------------------------------- class AudioEffect : public RefBase { public: /* * Static methods for effects enumeration. */ /* * Returns the number of effects available. This method together * with queryEffect() is used to enumerate all effects: * The enumeration sequence is: * queryNumberEffects(&num_effects); * for (i = 0; i < num_effects; i++) * queryEffect(i,...); * * Parameters: * numEffects: address where the number of effects should be returned. * * Returned status (from utils/Errors.h) can be: * NO_ERROR successful operation. * PERMISSION_DENIED could not get AudioFlinger interface * NO_INIT effect library failed to initialize * BAD_VALUE invalid numEffects pointer * * Returned value * *numEffects: updated with number of effects available */ static status_t queryNumberEffects(uint32_t *numEffects); /* * Returns an effect descriptor during effect * enumeration. * * Parameters: * index: index of the queried effect. * descriptor: address where the effect descriptor should be returned. * * Returned status (from utils/Errors.h) can be: * NO_ERROR successful operation. * PERMISSION_DENIED could not get AudioFlinger interface * NO_INIT effect library failed to initialize * BAD_VALUE invalid descriptor pointer or index * INVALID_OPERATION effect list has changed since last execution of queryNumberEffects() * * Returned value * *descriptor: updated with effect descriptor */ static status_t queryEffect(uint32_t index, effect_descriptor_t *descriptor); /* * Returns a descriptor for the specified effect uuid or type. * * Lookup an effect by uuid, or if that's unspecified (EFFECT_UUID_NULL), * do so by type and preferred flags instead. * * Parameters: * uuid: pointer to effect uuid. * type: pointer to effect type uuid. * preferredTypeFlags: if multiple effects of the given type exist, * one with a matching type flag will be chosen over one without. * Use EFFECT_FLAG_TYPE_MASK to indicate no preference. * descriptor: address where the effect descriptor should be returned. * * Returned status (from utils/Errors.h) can be: * NO_ERROR successful operation. * PERMISSION_DENIED could not get AudioFlinger interface * NO_INIT effect library failed to initialize * BAD_VALUE invalid type or descriptor pointers * NAME_NOT_FOUND no effect with this uuid found * * Returned value * *descriptor updated with effect descriptor */ static status_t getEffectDescriptor(const effect_uuid_t *uuid, const effect_uuid_t *type, uint32_t preferredTypeFlag, effect_descriptor_t *descriptor); /* * Returns a list of descriptors corresponding to the pre processings enabled by default * on an AudioRecord with the supplied audio session ID. * * Parameters: * audioSession: audio session ID. * descriptors: address where the effect descriptors should be returned. * count: as input, the maximum number of descriptor than should be returned * as output, the number of descriptor returned if status is NO_ERROR or the actual * number of enabled pre processings if status is NO_MEMORY * * Returned status (from utils/Errors.h) can be: * NO_ERROR successful operation. * NO_MEMORY the number of descriptor to return is more than the maximum number * indicated by count. * PERMISSION_DENIED could not get AudioFlinger interface * NO_INIT effect library failed to initialize * BAD_VALUE invalid audio session or descriptor pointers * * Returned value * *descriptor updated with descriptors of pre processings enabled by default * *count number of descriptors returned if returned status is NO_ERROR. * total number of pre processing enabled by default if returned status is * NO_MEMORY. This happens if the count passed as input is less than the number * of descriptors to return. * *count is limited to kMaxPreProcessing on return. */ static status_t queryDefaultPreProcessing(audio_session_t audioSession, effect_descriptor_t *descriptors, uint32_t *count); /* * Gets a new system-wide unique effect id. * * Parameters: * id: The address to return the generated id. * * Returned status (from utils/Errors.h) can be: * NO_ERROR successful operation. * PERMISSION_DENIED could not get AudioFlinger interface * or caller lacks required permissions. * Returned value * *id: The new unique system-wide effect id. */ static status_t newEffectUniqueId(audio_unique_id_t* id); /* * Static methods for adding/removing system-wide effects. */ /* * Adds an effect to the list of default output effects for a given source type. * * If the effect is no longer available when a source of the given type * is created, the system will continue without adding it. * * Parameters: * typeStr: Type uuid of effect to be a default: can be null if uuidStr is specified. * This may correspond to the OpenSL ES interface implemented by this effect, * or could be some vendor-defined type. * opPackageName: The package name used for app op checks. * uuidStr: Uuid of effect to be a default: can be null if type is specified. * This uuid corresponds to a particular implementation of an effect type. * Note if both uuidStr and typeStr are specified, typeStr is ignored. * priority: Requested priority for effect control: the priority level corresponds to the * value of priority parameter: negative values indicate lower priorities, positive * values higher priorities, 0 being the normal priority. * source: The source this effect should be a default for. * id: Address where the system-wide unique id of the default effect should be returned. * * Returned status (from utils/Errors.h) can be: * NO_ERROR successful operation. * PERMISSION_DENIED could not get AudioFlinger interface * or caller lacks required permissions. * NO_INIT effect library failed to initialize. * BAD_VALUE invalid source, type uuid or implementation uuid. * NAME_NOT_FOUND no effect with this uuid or type found. * * Returned value * *id: The system-wide unique id of the added default effect. */ static status_t addSourceDefaultEffect(const char* typeStr, const String16& opPackageName, const char* uuidStr, int32_t priority, audio_source_t source, audio_unique_id_t* id); /* * Adds an effect to the list of default output effects for a given stream type. * * If the effect is no longer available when a stream of the given type * is created, the system will continue without adding it. * * Parameters: * typeStr: Type uuid of effect to be a default: can be null if uuidStr is specified. * This may correspond to the OpenSL ES interface implemented by this effect, * or could be some vendor-defined type. * opPackageName: The package name used for app op checks. * uuidStr: Uuid of effect to be a default: can be null if type is specified. * This uuid corresponds to a particular implementation of an effect type. * Note if both uuidStr and typeStr are specified, typeStr is ignored. * priority: Requested priority for effect control: the priority level corresponds to the * value of priority parameter: negative values indicate lower priorities, positive * values higher priorities, 0 being the normal priority. * usage: The usage this effect should be a default for. Unrecognized values will be * treated as AUDIO_USAGE_UNKNOWN. * id: Address where the system-wide unique id of the default effect should be returned. * * Returned status (from utils/Errors.h) can be: * NO_ERROR successful operation. * PERMISSION_DENIED could not get AudioFlinger interface * or caller lacks required permissions. * NO_INIT effect library failed to initialize. * BAD_VALUE invalid type uuid or implementation uuid. * NAME_NOT_FOUND no effect with this uuid or type found. * * Returned value * *id: The system-wide unique id of the added default effect. */ static status_t addStreamDefaultEffect(const char* typeStr, const String16& opPackageName, const char* uuidStr, int32_t priority, audio_usage_t usage, audio_unique_id_t* id); /* * Removes an effect from the list of default output effects for a given source type. * * Parameters: * id: The system-wide unique id of the effect that should no longer be a default. * * Returned status (from utils/Errors.h) can be: * NO_ERROR successful operation. * PERMISSION_DENIED could not get AudioFlinger interface * or caller lacks required permissions. * NO_INIT effect library failed to initialize. * BAD_VALUE invalid id. */ static status_t removeSourceDefaultEffect(audio_unique_id_t id); /* * Removes an effect from the list of default output effects for a given stream type. * * Parameters: * id: The system-wide unique id of the effect that should no longer be a default. * * Returned status (from utils/Errors.h) can be: * NO_ERROR successful operation. * PERMISSION_DENIED could not get AudioFlinger interface * or caller lacks required permissions. * NO_INIT effect library failed to initialize. * BAD_VALUE invalid id. */ static status_t removeStreamDefaultEffect(audio_unique_id_t id); /* * Events used by callback function (effect_callback_t). */ enum event_type { EVENT_CONTROL_STATUS_CHANGED = 0, EVENT_ENABLE_STATUS_CHANGED = 1, EVENT_PARAMETER_CHANGED = 2, EVENT_ERROR = 3 }; /* Callback function notifying client application of a change in effect engine state or * configuration. * An effect engine can be shared by several applications but only one has the control * of the engine activity and configuration at a time. * The EVENT_CONTROL_STATUS_CHANGED event is received when an application loses or * retrieves the control of the effect engine. Loss of control happens * if another application requests the use of the engine by creating an AudioEffect for * the same effect type but with a higher priority. Control is returned when the * application having the control deletes its AudioEffect object. * The EVENT_ENABLE_STATUS_CHANGED event is received by all applications not having the * control of the effect engine when the effect is enabled or disabled. * The EVENT_PARAMETER_CHANGED event is received by all applications not having the * control of the effect engine when an effect parameter is changed. * The EVENT_ERROR event is received when the media server process dies. * * Parameters: * * event: type of event notified (see enum AudioEffect::event_type). * user: Pointer to context for use by the callback receiver. * info: Pointer to optional parameter according to event type: * - EVENT_CONTROL_STATUS_CHANGED: boolean indicating if control is granted (true) * or stolen (false). * - EVENT_ENABLE_STATUS_CHANGED: boolean indicating if effect is now enabled (true) * or disabled (false). * - EVENT_PARAMETER_CHANGED: pointer to a effect_param_t structure. * - EVENT_ERROR: status_t indicating the error (DEAD_OBJECT when media server dies). */ typedef void (*effect_callback_t)(int32_t event, void* user, void *info); /* Constructor. * AudioEffect is the base class for creating and controlling an effect engine from * the application process. Creating an AudioEffect object will create the effect engine * in the AudioFlinger if no engine of the specified type exists. If one exists, this engine * will be used. The application creating the AudioEffect object (or a derived class like * Reverb for instance) will either receive control of the effect engine or not, depending * on the priority parameter. If priority is higher than the priority used by the current * effect engine owner, the control will be transfered to the new application. Otherwise * control will remain to the previous application. In this case, the new application will be * notified of changes in effect engine state or control ownership by the effect callback. * After creating the AudioEffect, the application must call the initCheck() method and * check the creation status before trying to control the effect engine (see initCheck()). * If the effect is to be applied to an AudioTrack or MediaPlayer only the application * must specify the audio session ID corresponding to this player. */ /* Simple Constructor. * * Parameters: * * opPackageName: The package name used for app op checks. */ AudioEffect(const String16& opPackageName); /* Constructor. * * Parameters: * * type: type of effect created: can be null if uuid is specified. This corresponds to * the OpenSL ES interface implemented by this effect. * opPackageName: The package name used for app op checks. * uuid: Uuid of effect created: can be null if type is specified. This uuid corresponds to * a particular implementation of an effect type. * priority: requested priority for effect control: the priority level corresponds to the * value of priority parameter: negative values indicate lower priorities, positive values * higher priorities, 0 being the normal priority. * cbf: optional callback function (see effect_callback_t) * user: pointer to context for use by the callback receiver. * sessionID: audio session this effect is associated to. * If equal to AUDIO_SESSION_OUTPUT_MIX, the effect will be global to * the output mix. Otherwise, the effect will be applied to all players * (AudioTrack or MediaPLayer) within the same audio session. * io: HAL audio output or input stream to which this effect must be attached. Leave at 0 for * automatic output selection by AudioFlinger. */ AudioEffect(const effect_uuid_t *type, const String16& opPackageName, const effect_uuid_t *uuid = NULL, int32_t priority = 0, effect_callback_t cbf = NULL, void* user = NULL, audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX, audio_io_handle_t io = AUDIO_IO_HANDLE_NONE ); /* Constructor. * Same as above but with type and uuid specified by character strings */ AudioEffect(const char *typeStr, const String16& opPackageName, const char *uuidStr = NULL, int32_t priority = 0, effect_callback_t cbf = NULL, void* user = NULL, audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX, audio_io_handle_t io = AUDIO_IO_HANDLE_NONE ); /* Terminates the AudioEffect and unregisters it from AudioFlinger. * The effect engine is also destroyed if this AudioEffect was the last controlling * the engine. */ ~AudioEffect(); /* Initialize an uninitialized AudioEffect. * Returned status (from utils/Errors.h) can be: * - NO_ERROR or ALREADY_EXISTS: successful initialization * - INVALID_OPERATION: AudioEffect is already initialized * - BAD_VALUE: invalid parameter * - NO_INIT: audio flinger or audio hardware not initialized * */ status_t set(const effect_uuid_t *type, const effect_uuid_t *uuid = NULL, int32_t priority = 0, effect_callback_t cbf = NULL, void* user = NULL, audio_session_t sessionId = AUDIO_SESSION_OUTPUT_MIX, audio_io_handle_t io = AUDIO_IO_HANDLE_NONE ); /* Result of constructing the AudioEffect. This must be checked * before using any AudioEffect API. * initCheck() can return: * - NO_ERROR: the effect engine is successfully created and the application has control. * - ALREADY_EXISTS: the effect engine is successfully created but the application does not * have control. * - NO_INIT: the effect creation failed. * */ status_t initCheck() const; /* Returns the unique effect Id for the controlled effect engine. This ID is unique * system wide and is used for instance in the case of auxiliary effects to attach * the effect to an AudioTrack or MediaPlayer. * */ int32_t id() const { return mId; } /* Returns a descriptor for the effect (see effect_descriptor_t in audio_effect.h). */ effect_descriptor_t descriptor() const; /* Returns effect control priority of this AudioEffect object. */ int32_t priority() const { return mPriority; } /* Enables or disables the effect engine. * * Parameters: * enabled: requested enable state. * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation * - INVALID_OPERATION: the application does not have control of the effect engine or the * effect is already in the requested state. */ virtual status_t setEnabled(bool enabled); bool getEnabled() const; /* Sets a parameter value. * * Parameters: * param: pointer to effect_param_t structure containing the parameter * and its value (See audio_effect.h). * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation. * - INVALID_OPERATION: the application does not have control of the effect engine. * - BAD_VALUE: invalid parameter identifier or value. * - DEAD_OBJECT: the effect engine has been deleted. */ virtual status_t setParameter(effect_param_t *param); /* Prepare a new parameter value that will be set by next call to * setParameterCommit(). This method can be used to set multiple parameters * in a synchronous manner or to avoid multiple binder calls for each * parameter. * * Parameters: * param: pointer to effect_param_t structure containing the parameter * and its value (See audio_effect.h). * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation. * - INVALID_OPERATION: the application does not have control of the effect engine. * - NO_MEMORY: no more space available in shared memory used for deferred parameter * setting. */ virtual status_t setParameterDeferred(effect_param_t *param); /* Commit all parameter values previously prepared by setParameterDeferred(). * * Parameters: * none * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation. * - INVALID_OPERATION: No new parameter values ready for commit. * - BAD_VALUE: invalid parameter identifier or value: there is no indication * as to which of the parameters caused this error. * - DEAD_OBJECT: the effect engine has been deleted. */ virtual status_t setParameterCommit(); /* Gets a parameter value. * * Parameters: * param: pointer to effect_param_t structure containing the parameter * and the returned value (See audio_effect.h). * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation. * - INVALID_OPERATION: the AudioEffect was not successfully initialized. * - BAD_VALUE: invalid parameter identifier. * - DEAD_OBJECT: the effect engine has been deleted. */ virtual status_t getParameter(effect_param_t *param); /* Sends a command and receives a response to/from effect engine. * See audio_effect.h for details on effect command() function, valid command codes * and formats. */ virtual status_t command(uint32_t cmdCode, uint32_t cmdSize, void *cmdData, uint32_t *replySize, void *replyData); /* * Utility functions. */ /* Converts the string passed as first argument to the effect_uuid_t * pointed to by second argument */ static status_t stringToGuid(const char *str, effect_uuid_t *guid); /* Converts the effect_uuid_t pointed to by first argument to the * string passed as second argument */ static status_t guidToString(const effect_uuid_t *guid, char *str, size_t maxLen); // kMaxPreProcessing is a reasonable value for the maximum number of preprocessing effects // that can be applied simultaneously. static const uint32_t kMaxPreProcessing = 10; protected: bool mEnabled; // enable state audio_session_t mSessionId; // audio session ID int32_t mPriority; // priority for effect control status_t mStatus; // effect status effect_callback_t mCbf; // callback function for status, control and // parameter changes notifications void* mUserData; // client context for callback function effect_descriptor_t mDescriptor; // effect descriptor int32_t mId; // system wide unique effect engine instance ID Mutex mLock; // Mutex for mEnabled access Mutex mConstructLock; // Mutex for integrality construction String16 mOpPackageName; // The package name used for app op checks. // IEffectClient virtual void controlStatusChanged(bool controlGranted); virtual void enableStatusChanged(bool enabled); virtual void commandExecuted(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t replySize, void *pReplyData); private: // Implements the IEffectClient interface class EffectClient : public android::BnEffectClient, public android::IBinder::DeathRecipient { public: EffectClient(AudioEffect *effect) : mEffect(effect){} // IEffectClient virtual void controlStatusChanged(bool controlGranted) { sp<AudioEffect> effect = mEffect.promote(); if (effect != 0) { { // Got the mConstructLock means the construction of AudioEffect // has finished, we should release the mConstructLock immediately. AutoMutex lock(effect->mConstructLock); } effect->controlStatusChanged(controlGranted); } } virtual void enableStatusChanged(bool enabled) { sp<AudioEffect> effect = mEffect.promote(); if (effect != 0) { { // Got the mConstructLock means the construction of AudioEffect // has finished, we should release the mConstructLock immediately. AutoMutex lock(effect->mConstructLock); } effect->enableStatusChanged(enabled); } } virtual void commandExecuted(uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t replySize, void *pReplyData) { sp<AudioEffect> effect = mEffect.promote(); if (effect != 0) { { // Got the mConstructLock means the construction of AudioEffect // has finished, we should release the mConstructLock immediately. AutoMutex lock(effect->mConstructLock); } effect->commandExecuted( cmdCode, cmdSize, pCmdData, replySize, pReplyData); } } // IBinder::DeathRecipient virtual void binderDied(const wp<IBinder>& /*who*/) { sp<AudioEffect> effect = mEffect.promote(); if (effect != 0) { { // Got the mConstructLock means the construction of AudioEffect // has finished, we should release the mConstructLock immediately. AutoMutex lock(effect->mConstructLock); } effect->binderDied(); } } private: wp<AudioEffect> mEffect; }; void binderDied(); sp<IEffect> mIEffect; // IEffect binder interface sp<EffectClient> mIEffectClient; // IEffectClient implementation sp<IMemory> mCblkMemory; // shared memory for deferred parameter setting effect_param_cblk_t* mCblk; // control block for deferred parameter setting pid_t mClientPid; }; }; // namespace android #endif // ANDROID_AUDIOEFFECT_H