From e1315cf0b63b4c14a77046519e6b01f6f60d74b0 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Tue, 17 May 2011 19:16:02 -0700 Subject: New effect library API Moved and renamed media/EffectApi.h to hardware/audio_effect.h Modified the effect library API to expose a library info structure containing an interface functions table. Also removed enums for audio channels, audio format and devices from effect API and use values from system/audio.h instead. Modified effects factory to support new library interface format and load libraries and efffects listed in audio_effects.conf file. The file audio_effects.conf is first loaded from /vendor/etc and then from /system/etc/audio_effects.conf if not found. Modified existing effect libraries to implement the new library interface. Change-Id: Ie52351e071b6d352fa2fbc06c3846686f8c45df9 --- include/media/AudioEffect.h | 12 +- include/media/EffectApi.h | 796 --------------------- include/media/EffectBassBoostApi.h | 2 +- include/media/EffectEnvironmentalReverbApi.h | 2 +- include/media/EffectEqualizerApi.h | 2 +- include/media/EffectPresetReverbApi.h | 2 +- include/media/EffectVirtualizerApi.h | 2 +- include/media/EffectVisualizerApi.h | 2 +- include/media/EffectsFactoryApi.h | 14 +- include/media/IAudioFlinger.h | 2 +- media/libeffects/data/audio_effects.conf | 57 ++ media/libeffects/factory/EffectsFactory.c | 479 +++++++------ media/libeffects/factory/EffectsFactory.h | 18 +- .../libeffects/lvm/wrapper/Bundle/EffectBundle.cpp | 133 +++- .../libeffects/lvm/wrapper/Reverb/EffectReverb.cpp | 125 +++- media/libeffects/testlibs/Android.mk_ | 4 +- media/libeffects/testlibs/AudioFormatAdapter.h | 8 +- media/libeffects/testlibs/EffectEqualizer.cpp | 117 ++- media/libeffects/testlibs/EffectReverb.c | 122 +++- media/libeffects/testlibs/EffectReverb.h | 15 +- media/libeffects/visualizer/EffectVisualizer.cpp | 113 ++- services/audioflinger/AudioFlinger.cpp | 77 +- services/audioflinger/AudioFlinger.h | 10 +- 23 files changed, 840 insertions(+), 1274 deletions(-) delete mode 100644 include/media/EffectApi.h create mode 100644 media/libeffects/data/audio_effects.conf diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h index cda2be0..401638a 100644 --- a/include/media/AudioEffect.h +++ b/include/media/AudioEffect.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -298,7 +298,7 @@ public: */ int32_t id() const { return mId; } - /* Returns a descriptor for the effect (see effect_descriptor_t in EffectApi.h). + /* Returns a descriptor for the effect (see effect_descriptor_t in audio_effect.h). */ effect_descriptor_t descriptor() const; @@ -324,7 +324,7 @@ public: * * Parameters: * param: pointer to effect_param_t structure containing the parameter - * and its value (See EffectApi.h). + * 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. @@ -340,7 +340,7 @@ public: * * Parameters: * param: pointer to effect_param_t structure containing the parameter - * and its value (See EffectApi.h). + * and its value (See audio_effect.h). * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation. @@ -368,7 +368,7 @@ public: * * Parameters: * param: pointer to effect_param_t structure containing the parameter - * and the returned value (See EffectApi.h). + * and the returned value (See audio_effect.h). * * Returned status (from utils/Errors.h) can be: * - NO_ERROR: successful operation. @@ -379,7 +379,7 @@ public: virtual status_t getParameter(effect_param_t *param); /* Sends a command and receives a response to/from effect engine. - * See EffectApi.h for details on effect command() function, valid command codes + * See audio_effect.h for details on effect command() function, valid command codes * and formats. */ virtual status_t command(uint32_t cmdCode, diff --git a/include/media/EffectApi.h b/include/media/EffectApi.h deleted file mode 100644 index a5ad846..0000000 --- a/include/media/EffectApi.h +++ /dev/null @@ -1,796 +0,0 @@ -/* - * Copyright (C) 2010 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_EFFECTAPI_H_ -#define ANDROID_EFFECTAPI_H_ - -#include -#include -#include - -#if __cplusplus -extern "C" { -#endif - -///////////////////////////////////////////////// -// Effect control interface -///////////////////////////////////////////////// - -// The effect control interface is exposed by each effect engine implementation. It consists of -// a set of functions controlling the configuration, activation and process of the engine. -// The functions are grouped in a structure of type effect_interface_s: -// struct effect_interface_s { -// effect_process_t process; -// effect_command_t command; -// }; - - -// effect_interface_t: Effect control interface handle. -// The effect_interface_t serves two purposes regarding the implementation of the effect engine: -// - 1 it is the address of a pointer to an effect_interface_s structure where the functions -// of the effect control API for a particular effect are located. -// - 2 it is the address of the context of a particular effect instance. -// A typical implementation in the effect library would define a structure as follows: -// struct effect_module_s { -// const struct effect_interface_s *itfe; -// effect_config_t config; -// effect_context_t context; -// } -// The implementation of EffectCreate() function would then allocate a structure of this -// type and return its address as effect_interface_t -typedef struct effect_interface_s **effect_interface_t; - - -// Effect API version 1.0 -#define EFFECT_API_VERSION 0x0100 // Format 0xMMmm MM: Major version, mm: minor version - -// Maximum length of character strings in structures defines by this API. -#define EFFECT_STRING_LEN_MAX 64 - -// -//--- Effect descriptor structure effect_descriptor_t -// - -// Unique effect ID (can be generated from the following site: -// http://www.itu.int/ITU-T/asn1/uuid.html) -// This format is used for both "type" and "uuid" fields of the effect descriptor structure. -// - When used for effect type and the engine is implementing and effect corresponding to a standard -// OpenSL ES interface, this ID must be the one defined in OpenSLES_IID.h for that interface. -// - When used as uuid, it should be a unique UUID for this particular implementation. -typedef struct effect_uuid_s { - uint32_t timeLow; - uint16_t timeMid; - uint16_t timeHiAndVersion; - uint16_t clockSeq; - uint8_t node[6]; -} effect_uuid_t; - -// NULL UUID definition (matches SL_IID_NULL_) -#define EFFECT_UUID_INITIALIZER { 0xec7178ec, 0xe5e1, 0x4432, 0xa3f4, \ - { 0x46, 0x57, 0xe6, 0x79, 0x52, 0x10 } } -static const effect_uuid_t EFFECT_UUID_NULL_ = EFFECT_UUID_INITIALIZER; -const effect_uuid_t * const EFFECT_UUID_NULL = &EFFECT_UUID_NULL_; -const char * const EFFECT_UUID_NULL_STR = "ec7178ec-e5e1-4432-a3f4-4657e6795210"; - -// The effect descriptor contains necessary information to facilitate the enumeration of the effect -// engines present in a library. -typedef struct effect_descriptor_s { - effect_uuid_t type; // UUID of to the OpenSL ES interface implemented by this effect - effect_uuid_t uuid; // UUID for this particular implementation - uint16_t apiVersion; // Version of the effect API implemented: matches EFFECT_API_VERSION - uint32_t flags; // effect engine capabilities/requirements flags (see below) - uint16_t cpuLoad; // CPU load indication (see below) - uint16_t memoryUsage; // Data Memory usage (see below) - char name[EFFECT_STRING_LEN_MAX]; // human readable effect name - char implementor[EFFECT_STRING_LEN_MAX]; // human readable effect implementor name -} effect_descriptor_t; - -// CPU load and memory usage indication: each effect implementation must provide an indication of -// its CPU and memory usage for the audio effect framework to limit the number of effects -// instantiated at a given time on a given platform. -// The CPU load is expressed in 0.1 MIPS units as estimated on an ARM9E core (ARMv5TE) with 0 WS. -// The memory usage is expressed in KB and includes only dynamically allocated memory - -// Definitions for flags field of effect descriptor. -// +---------------------------+-----------+----------------------------------- -// | description | bits | values -// +---------------------------+-----------+----------------------------------- -// | connection mode | 0..1 | 0 insert: after track process -// | | | 1 auxiliary: connect to track auxiliary -// | | | output and use send level -// | | | 2 replace: replaces track process function; -// | | | must implement SRC, volume and mono to stereo. -// | | | 3 reserved -// +---------------------------+-----------+----------------------------------- -// | insertion preference | 2..4 | 0 none -// | | | 1 first of the chain -// | | | 2 last of the chain -// | | | 3 exclusive (only effect in the insert chain) -// | | | 4..7 reserved -// +---------------------------+-----------+----------------------------------- -// | Volume management | 5..6 | 0 none -// | | | 1 implements volume control -// | | | 2 requires volume indication -// | | | 3 reserved -// +---------------------------+-----------+----------------------------------- -// | Device indication | 7..8 | 0 none -// | | | 1 requires device updates -// | | | 2..3 reserved -// +---------------------------+-----------+----------------------------------- -// | Sample input mode | 9..10 | 0 direct: process() function or EFFECT_CMD_CONFIGURE -// | | | command must specify a buffer descriptor -// | | | 1 provider: process() function uses the -// | | | bufferProvider indicated by the -// | | | EFFECT_CMD_CONFIGURE command to request input. -// | | | buffers. -// | | | 2 both: both input modes are supported -// | | | 3 reserved -// +---------------------------+-----------+----------------------------------- -// | Sample output mode | 11..12 | 0 direct: process() function or EFFECT_CMD_CONFIGURE -// | | | command must specify a buffer descriptor -// | | | 1 provider: process() function uses the -// | | | bufferProvider indicated by the -// | | | EFFECT_CMD_CONFIGURE command to request output -// | | | buffers. -// | | | 2 both: both output modes are supported -// | | | 3 reserved -// +---------------------------+-----------+----------------------------------- -// | Hardware acceleration | 13..15 | 0 No hardware acceleration -// | | | 1 non tunneled hw acceleration: the process() function -// | | | reads the samples, send them to HW accelerated -// | | | effect processor, reads back the processed samples -// | | | and returns them to the output buffer. -// | | | 2 tunneled hw acceleration: the process() function is -// | | | transparent. The effect interface is only used to -// | | | control the effect engine. This mode is relevant for -// | | | global effects actually applied by the audio -// | | | hardware on the output stream. -// +---------------------------+-----------+----------------------------------- -// | Audio Mode indication | 16..17 | 0 none -// | | | 1 requires audio mode updates -// | | | 2..3 reserved -// +---------------------------+-----------+----------------------------------- - -// Insert mode -#define EFFECT_FLAG_TYPE_MASK 0x00000003 -#define EFFECT_FLAG_TYPE_INSERT 0x00000000 -#define EFFECT_FLAG_TYPE_AUXILIARY 0x00000001 -#define EFFECT_FLAG_TYPE_REPLACE 0x00000002 - -// Insert preference -#define EFFECT_FLAG_INSERT_MASK 0x0000001C -#define EFFECT_FLAG_INSERT_ANY 0x00000000 -#define EFFECT_FLAG_INSERT_FIRST 0x00000004 -#define EFFECT_FLAG_INSERT_LAST 0x00000008 -#define EFFECT_FLAG_INSERT_EXCLUSIVE 0x0000000C - - -// Volume control -#define EFFECT_FLAG_VOLUME_MASK 0x00000060 -#define EFFECT_FLAG_VOLUME_CTRL 0x00000020 -#define EFFECT_FLAG_VOLUME_IND 0x00000040 -#define EFFECT_FLAG_VOLUME_NONE 0x00000000 - -// Device indication -#define EFFECT_FLAG_DEVICE_MASK 0x00000180 -#define EFFECT_FLAG_DEVICE_IND 0x00000080 -#define EFFECT_FLAG_DEVICE_NONE 0x00000000 - -// Sample input modes -#define EFFECT_FLAG_INPUT_MASK 0x00000600 -#define EFFECT_FLAG_INPUT_DIRECT 0x00000000 -#define EFFECT_FLAG_INPUT_PROVIDER 0x00000200 -#define EFFECT_FLAG_INPUT_BOTH 0x00000400 - -// Sample output modes -#define EFFECT_FLAG_OUTPUT_MASK 0x00001800 -#define EFFECT_FLAG_OUTPUT_DIRECT 0x00000000 -#define EFFECT_FLAG_OUTPUT_PROVIDER 0x00000800 -#define EFFECT_FLAG_OUTPUT_BOTH 0x00001000 - -// Hardware acceleration mode -#define EFFECT_FLAG_HW_ACC_MASK 0x00006000 -#define EFFECT_FLAG_HW_ACC_SIMPLE 0x00002000 -#define EFFECT_FLAG_HW_ACC_TUNNEL 0x00004000 - -// Audio mode indication -#define EFFECT_FLAG_AUDIO_MODE_MASK 0x00018000 -#define EFFECT_FLAG_AUDIO_MODE_IND 0x00008000 -#define EFFECT_FLAG_AUDIO_MODE_NONE 0x00000000 - -// Forward definition of type audio_buffer_t -typedef struct audio_buffer_s audio_buffer_t; - -//////////////////////////////////////////////////////////////////////////////// -// -// Function: process -// -// Description: Effect process function. Takes input samples as specified -// (count and location) in input buffer descriptor and output processed -// samples as specified in output buffer descriptor. If the buffer descriptor -// is not specified the function must use either the buffer or the -// buffer provider function installed by the EFFECT_CMD_CONFIGURE command. -// The effect framework will call the process() function after the EFFECT_CMD_ENABLE -// command is received and until the EFFECT_CMD_DISABLE is received. When the engine -// receives the EFFECT_CMD_DISABLE command it should turn off the effect gracefully -// and when done indicate that it is OK to stop calling the process() function by -// returning the -ENODATA status. -// -// NOTE: the process() function implementation should be "real-time safe" that is -// it should not perform blocking calls: malloc/free, sleep, read/write/open/close, -// pthread_cond_wait/pthread_mutex_lock... -// -// Input: -// effect_interface_t: handle to the effect interface this function -// is called on. -// inBuffer: buffer descriptor indicating where to read samples to process. -// If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command. -// -// inBuffer: buffer descriptor indicating where to write processed samples. -// If NULL, use the configuration passed by EFFECT_CMD_CONFIGURE command. -// -// Output: -// returned value: 0 successful operation -// -ENODATA the engine has finished the disable phase and the framework -// can stop calling process() -// -EINVAL invalid interface handle or -// invalid input/output buffer description -//////////////////////////////////////////////////////////////////////////////// -typedef int32_t (*effect_process_t)(effect_interface_t self, - audio_buffer_t *inBuffer, - audio_buffer_t *outBuffer); - -//////////////////////////////////////////////////////////////////////////////// -// -// Function: command -// -// Description: Send a command and receive a response to/from effect engine. -// -// Input: -// effect_interface_t: handle to the effect interface this function -// is called on. -// cmdCode: command code: the command can be a standardized command defined in -// effect_command_e (see below) or a proprietary command. -// cmdSize: size of command in bytes -// pCmdData: pointer to command data -// pReplyData: pointer to reply data -// -// Input/Output: -// replySize: maximum size of reply data as input -// actual size of reply data as output -// -// Output: -// returned value: 0 successful operation -// -EINVAL invalid interface handle or -// invalid command/reply size or format according to command code -// The return code should be restricted to indicate problems related to the this -// API specification. Status related to the execution of a particular command should be -// indicated as part of the reply field. -// -// *pReplyData updated with command response -// -//////////////////////////////////////////////////////////////////////////////// -typedef int32_t (*effect_command_t)(effect_interface_t self, - uint32_t cmdCode, - uint32_t cmdSize, - void *pCmdData, - uint32_t *replySize, - void *pReplyData); - - -// Effect control interface definition -struct effect_interface_s { - effect_process_t process; - effect_command_t command; -}; - - -// -//--- Standardized command codes for command() function -// -enum effect_command_e { - EFFECT_CMD_INIT, // initialize effect engine - EFFECT_CMD_CONFIGURE, // configure effect engine (see effect_config_t) - EFFECT_CMD_RESET, // reset effect engine - EFFECT_CMD_ENABLE, // enable effect process - EFFECT_CMD_DISABLE, // disable effect process - EFFECT_CMD_SET_PARAM, // set parameter immediately (see effect_param_t) - EFFECT_CMD_SET_PARAM_DEFERRED, // set parameter deferred - EFFECT_CMD_SET_PARAM_COMMIT, // commit previous set parameter deferred - EFFECT_CMD_GET_PARAM, // get parameter - EFFECT_CMD_SET_DEVICE, // set audio device (see audio_device_e) - EFFECT_CMD_SET_VOLUME, // set volume - EFFECT_CMD_SET_AUDIO_MODE, // set the audio mode (normal, ring, ...) - EFFECT_CMD_FIRST_PROPRIETARY = 0x10000 // first proprietary command code -}; - -//================================================================================================== -// command: EFFECT_CMD_INIT -//-------------------------------------------------------------------------------------------------- -// description: -// Initialize effect engine: All configurations return to default -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_CONFIGURE -//-------------------------------------------------------------------------------------------------- -// description: -// Apply new audio parameters configurations for input and output buffers -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(effect_config_t) -// data: effect_config_t -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_RESET -//-------------------------------------------------------------------------------------------------- -// description: -// Reset the effect engine. Keep configuration but resets state and buffer content -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: 0 -// data: N/A -//================================================================================================== -// command: EFFECT_CMD_ENABLE -//-------------------------------------------------------------------------------------------------- -// description: -// Enable the process. Called by the framework before the first call to process() -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_DISABLE -//-------------------------------------------------------------------------------------------------- -// description: -// Disable the process. Called by the framework after the last call to process() -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_SET_PARAM -//-------------------------------------------------------------------------------------------------- -// description: -// Set a parameter and apply it immediately -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(effect_param_t) + size of param and value -// data: effect_param_t + param + value. See effect_param_t definition below for value offset -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_SET_PARAM_DEFERRED -//-------------------------------------------------------------------------------------------------- -// description: -// Set a parameter but apply it only when receiving EFFECT_CMD_SET_PARAM_COMMIT command -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(effect_param_t) + size of param and value -// data: effect_param_t + param + value. See effect_param_t definition below for value offset -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: 0 -// data: N/A -//================================================================================================== -// command: EFFECT_CMD_SET_PARAM_COMMIT -//-------------------------------------------------------------------------------------------------- -// description: -// Apply all previously received EFFECT_CMD_SET_PARAM_DEFERRED commands -//-------------------------------------------------------------------------------------------------- -// command format: -// size: 0 -// data: N/A -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(int) -// data: status -//================================================================================================== -// command: EFFECT_CMD_GET_PARAM -//-------------------------------------------------------------------------------------------------- -// description: -// Get a parameter value -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(effect_param_t) + size of param -// data: effect_param_t + param -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: sizeof(effect_param_t) + size of param and value -// data: effect_param_t + param + value. See effect_param_t definition below for value offset -//================================================================================================== -// command: EFFECT_CMD_SET_DEVICE -//-------------------------------------------------------------------------------------------------- -// description: -// Set the rendering device the audio output path is connected to. See audio_device_e for device -// values. -// The effect implementation must set EFFECT_FLAG_DEVICE_IND flag in its descriptor to receive this -// command when the device changes -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(uint32_t) -// data: audio_device_e -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: 0 -// data: N/A -//================================================================================================== -// command: EFFECT_CMD_SET_VOLUME -//-------------------------------------------------------------------------------------------------- -// description: -// Set and get volume. Used by audio framework to delegate volume control to effect engine. -// The effect implementation must set EFFECT_FLAG_VOLUME_IND or EFFECT_FLAG_VOLUME_CTRL flag in -// its descriptor to receive this command before every call to process() function -// If EFFECT_FLAG_VOLUME_CTRL flag is set in the effect descriptor, the effect engine must return -// the volume that should be applied before the effect is processed. The overall volume (the volume -// actually applied by the effect engine multiplied by the returned value) should match the value -// indicated in the command. -//-------------------------------------------------------------------------------------------------- -// command format: -// size: n * sizeof(uint32_t) -// data: volume for each channel defined in effect_config_t for output buffer expressed in -// 8.24 fixed point format -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: n * sizeof(uint32_t) / 0 -// data: - if EFFECT_FLAG_VOLUME_CTRL is set in effect descriptor: -// volume for each channel defined in effect_config_t for output buffer expressed in -// 8.24 fixed point format -// - if EFFECT_FLAG_VOLUME_CTRL is not set in effect descriptor: -// N/A -// It is legal to receive a null pointer as pReplyData in which case the effect framework has -// delegated volume control to another effect -//================================================================================================== -// command: EFFECT_CMD_SET_AUDIO_MODE -//-------------------------------------------------------------------------------------------------- -// description: -// Set the audio mode. The effect implementation must set EFFECT_FLAG_AUDIO_MODE_IND flag in its -// descriptor to receive this command when the audio mode changes. -//-------------------------------------------------------------------------------------------------- -// command format: -// size: sizeof(uint32_t) -// data: audio_mode_e -//-------------------------------------------------------------------------------------------------- -// reply format: -// size: 0 -// data: N/A -//================================================================================================== -// command: EFFECT_CMD_FIRST_PROPRIETARY -//-------------------------------------------------------------------------------------------------- -// description: -// All proprietary effect commands must use command codes above this value. The size and format of -// command and response fields is free in this case -//================================================================================================== - - -// Audio buffer descriptor used by process(), bufferProvider() functions and buffer_config_t -// structure. Multi-channel audio is always interleaved. The channel order is from LSB to MSB with -// regard to the channel mask definition in audio_channels_e e.g : -// Stereo: left, right -// 5 point 1: front left, front right, front center, low frequency, back left, back right -// The buffer size is expressed in frame count, a frame being composed of samples for all -// channels at a given time. Frame size for unspecified format (AUDIO_FORMAT_OTHER) is 8 bit by -// definition -struct audio_buffer_s { - size_t frameCount; // number of frames in buffer - union { - void* raw; // raw pointer to start of buffer - int32_t* s32; // pointer to signed 32 bit data at start of buffer - int16_t* s16; // pointer to signed 16 bit data at start of buffer - uint8_t* u8; // pointer to unsigned 8 bit data at start of buffer - }; -}; - -// The buffer_provider_s structure contains functions that can be used -// by the effect engine process() function to query and release input -// or output audio buffer. -// The getBuffer() function is called to retrieve a buffer where data -// should read from or written to by process() function. -// The releaseBuffer() function MUST be called when the buffer retrieved -// with getBuffer() is not needed anymore. -// The process function should use the buffer provider mechanism to retrieve -// input or output buffer if the inBuffer or outBuffer passed as argument is NULL -// and the buffer configuration (buffer_config_t) given by the EFFECT_CMD_CONFIGURE -// command did not specify an audio buffer. - -typedef int32_t (* buffer_function_t)(void *cookie, audio_buffer_t *buffer); - -typedef struct buffer_provider_s { - buffer_function_t getBuffer; // retrieve next buffer - buffer_function_t releaseBuffer; // release used buffer - void *cookie; // for use by client of buffer provider functions -} buffer_provider_t; - - -// The buffer_config_s structure specifies the input or output audio format -// to be used by the effect engine. It is part of the effect_config_t -// structure that defines both input and output buffer configurations and is -// passed by the EFFECT_CMD_CONFIGURE command. -typedef struct buffer_config_s { - audio_buffer_t buffer; // buffer for use by process() function if not passed explicitly - uint32_t samplingRate; // sampling rate - uint32_t channels; // channel mask (see audio_channels_e) - buffer_provider_t bufferProvider; // buffer provider - uint8_t format; // Audio format (see audio_format_e) - uint8_t accessMode; // read/write or accumulate in buffer (effect_buffer_access_e) - uint16_t mask; // indicates which of the above fields is valid -} buffer_config_t; - -// Sample format -enum audio_format_e { - SAMPLE_FORMAT_PCM_S15, // PCM signed 16 bits - SAMPLE_FORMAT_PCM_U8, // PCM unsigned 8 bits - SAMPLE_FORMAT_PCM_S7_24, // PCM signed 7.24 fixed point representation - SAMPLE_FORMAT_OTHER // other format (e.g. compressed) -}; - -// Channel mask -enum audio_channels_e { - CHANNEL_FRONT_LEFT = 0x1, // front left channel - CHANNEL_FRONT_RIGHT = 0x2, // front right channel - CHANNEL_FRONT_CENTER = 0x4, // front center channel - CHANNEL_LOW_FREQUENCY = 0x8, // low frequency channel - CHANNEL_BACK_LEFT = 0x10, // back left channel - CHANNEL_BACK_RIGHT = 0x20, // back right channel - CHANNEL_FRONT_LEFT_OF_CENTER = 0x40, // front left of center channel - CHANNEL_FRONT_RIGHT_OF_CENTER = 0x80, // front right of center channel - CHANNEL_BACK_CENTER = 0x100, // back center channel - CHANNEL_MONO = CHANNEL_FRONT_LEFT, - CHANNEL_STEREO = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT), - CHANNEL_QUAD = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | - CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT), - CHANNEL_SURROUND = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | - CHANNEL_FRONT_CENTER | CHANNEL_BACK_CENTER), - CHANNEL_5POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | - CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT), - CHANNEL_7POINT1 = (CHANNEL_FRONT_LEFT | CHANNEL_FRONT_RIGHT | - CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY | CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT | - CHANNEL_FRONT_LEFT_OF_CENTER | CHANNEL_FRONT_RIGHT_OF_CENTER), -}; - -// Render device -enum audio_device_e { - DEVICE_EARPIECE = 0x1, // earpiece - DEVICE_SPEAKER = 0x2, // speaker - DEVICE_WIRED_HEADSET = 0x4, // wired headset, with microphone - DEVICE_WIRED_HEADPHONE = 0x8, // wired headphone, without microphone - DEVICE_BLUETOOTH_SCO = 0x10, // generic bluetooth SCO - DEVICE_BLUETOOTH_SCO_HEADSET = 0x20, // bluetooth SCO headset - DEVICE_BLUETOOTH_SCO_CARKIT = 0x40, // bluetooth SCO car kit - DEVICE_BLUETOOTH_A2DP = 0x80, // generic bluetooth A2DP - DEVICE_BLUETOOTH_A2DP_HEADPHONES = 0x100, // bluetooth A2DP headphones - DEVICE_BLUETOOTH_A2DP_SPEAKER = 0x200, // bluetooth A2DP speakers - DEVICE_AUX_DIGITAL = 0x400, // digital output - DEVICE_EXTERNAL_SPEAKER = 0x800 // external speaker (stereo and High quality) -}; - -// Audio mode -enum audio_mode_e { - AUDIO_EFFECT_MODE_NORMAL, // device idle - AUDIO_EFFECT_MODE_RINGTONE, // device ringing - AUDIO_EFFECT_MODE_IN_CALL, // audio call connected (VoIP or telephony) -}; - -// Values for "accessMode" field of buffer_config_t: -// overwrite, read only, accumulate (read/modify/write) -enum effect_buffer_access_e { - EFFECT_BUFFER_ACCESS_WRITE, - EFFECT_BUFFER_ACCESS_READ, - EFFECT_BUFFER_ACCESS_ACCUMULATE - -}; - -// Values for bit field "mask" in buffer_config_t. If a bit is set, the corresponding field -// in buffer_config_t must be taken into account when executing the EFFECT_CMD_CONFIGURE command -#define EFFECT_CONFIG_BUFFER 0x0001 // buffer field must be taken into account -#define EFFECT_CONFIG_SMP_RATE 0x0002 // samplingRate field must be taken into account -#define EFFECT_CONFIG_CHANNELS 0x0004 // channels field must be taken into account -#define EFFECT_CONFIG_FORMAT 0x0008 // format field must be taken into account -#define EFFECT_CONFIG_ACC_MODE 0x0010 // accessMode field must be taken into account -#define EFFECT_CONFIG_PROVIDER 0x0020 // bufferProvider field must be taken into account -#define EFFECT_CONFIG_ALL (EFFECT_CONFIG_BUFFER | EFFECT_CONFIG_SMP_RATE | \ - EFFECT_CONFIG_CHANNELS | EFFECT_CONFIG_FORMAT | \ - EFFECT_CONFIG_ACC_MODE | EFFECT_CONFIG_PROVIDER) - - -// effect_config_s structure describes the format of the pCmdData argument of EFFECT_CMD_CONFIGURE -// command to configure audio parameters and buffers for effect engine input and output. -typedef struct effect_config_s { - buffer_config_t inputCfg; - buffer_config_t outputCfg;; -} effect_config_t; - - -// effect_param_s structure describes the format of the pCmdData argument of EFFECT_CMD_SET_PARAM -// command and pCmdData and pReplyData of EFFECT_CMD_GET_PARAM command. -// psize and vsize represent the actual size of parameter and value. -// -// NOTE: the start of value field inside the data field is always on a 32 bit boundary: -// -// +-----------+ -// | status | sizeof(int) -// +-----------+ -// | psize | sizeof(int) -// +-----------+ -// | vsize | sizeof(int) -// +-----------+ -// | | | | -// ~ parameter ~ > psize | -// | | | > ((psize - 1)/sizeof(int) + 1) * sizeof(int) -// +-----------+ | -// | padding | | -// +-----------+ -// | | | -// ~ value ~ > vsize -// | | | -// +-----------+ - -typedef struct effect_param_s { - int32_t status; // Transaction status (unused for command, used for reply) - uint32_t psize; // Parameter size - uint32_t vsize; // Value size - char data[]; // Start of Parameter + Value data -} effect_param_t; - - -///////////////////////////////////////////////// -// Effect library interface -///////////////////////////////////////////////// - -// An effect library is required to implement and expose the following functions -// to enable effect enumeration and instantiation. The name of these functions must be as -// specified here as the effect framework will get the function address with dlsym(): -// -// - effect_QueryNumberEffects_t EffectQueryNumberEffects; -// - effect_QueryEffect_t EffectQueryEffect; -// - effect_CreateEffect_t EffectCreate; -// - effect_ReleaseEffect_t EffectRelease; - - -//////////////////////////////////////////////////////////////////////////////// -// -// Function: EffectQueryNumberEffects -// -// Description: Returns the number of different effects exposed by the -// library. Each effect must have a unique effect uuid (see -// effect_descriptor_t). This function together with EffectQueryEffect() -// is used to enumerate all effects present in the library. -// -// Input/Output: -// pNumEffects: address where the number of effects should be returned. -// -// Output: -// returned value: 0 successful operation. -// -ENODEV library failed to initialize -// -EINVAL invalid pNumEffects -// *pNumEffects: updated with number of effects in library -// -//////////////////////////////////////////////////////////////////////////////// -typedef int32_t (*effect_QueryNumberEffects_t)(uint32_t *pNumEffects); - -//////////////////////////////////////////////////////////////////////////////// -// -// Function: EffectQueryEffect -// -// Description: Returns the descriptor of the effect engine which index is -// given as first argument. -// See effect_descriptor_t for details on effect descriptors. -// This function together with EffectQueryNumberEffects() is used to enumerate all -// effects present in the library. The enumeration sequence is: -// EffectQueryNumberEffects(&num_effects); -// for (i = 0; i < num_effects; i++) -// EffectQueryEffect(i,...); -// -// Input/Output: -// index: index of the effect -// pDescriptor: address where to return the effect descriptor. -// -// Output: -// returned value: 0 successful operation. -// -ENODEV library failed to initialize -// -EINVAL invalid pDescriptor or index -// -ENOSYS effect list has changed since last execution of -// EffectQueryNumberEffects() -// -ENOENT no more effect available -// *pDescriptor: updated with the effect descriptor. -// -//////////////////////////////////////////////////////////////////////////////// -typedef int32_t (*effect_QueryEffect_t)(uint32_t index, - effect_descriptor_t *pDescriptor); - -//////////////////////////////////////////////////////////////////////////////// -// -// Function: EffectCreate -// -// Description: Creates an effect engine of the specified type and returns an -// effect control interface on this engine. The function will allocate the -// resources for an instance of the requested effect engine and return -// a handle on the effect control interface. -// -// Input: -// uuid: pointer to the effect uuid. -// sessionId: audio session to which this effect instance will be attached. All effects -// created with the same session ID are connected in series and process the same signal -// stream. Knowing that two effects are part of the same effect chain can help the -// library implement some kind of optimizations. -// ioId: identifies the output or input stream this effect is directed to at audio HAL. -// For future use especially with tunneled HW accelerated effects -// -// Input/Output: -// pInterface: address where to return the effect interface. -// -// Output: -// returned value: 0 successful operation. -// -ENODEV library failed to initialize -// -EINVAL invalid pEffectUuid or pInterface -// -ENOENT no effect with this uuid found -// *pInterface: updated with the effect interface handle. -// -//////////////////////////////////////////////////////////////////////////////// -typedef int32_t (*effect_CreateEffect_t)(effect_uuid_t *uuid, - int32_t sessionId, - int32_t ioId, - effect_interface_t *pInterface); - -//////////////////////////////////////////////////////////////////////////////// -// -// Function: EffectRelease -// -// Description: Releases the effect engine whose handle is given as argument. -// All resources allocated to this particular instance of the effect are -// released. -// -// Input: -// interface: handle on the effect interface to be released. -// -// Output: -// returned value: 0 successful operation. -// -ENODEV library failed to initialize -// -EINVAL invalid interface handle -// -//////////////////////////////////////////////////////////////////////////////// -typedef int32_t (*effect_ReleaseEffect_t)(effect_interface_t interface); - - -#if __cplusplus -} // extern "C" -#endif - - -#endif /*ANDROID_EFFECTAPI_H_*/ diff --git a/include/media/EffectBassBoostApi.h b/include/media/EffectBassBoostApi.h index 75f8d78..56119eb 100644 --- a/include/media/EffectBassBoostApi.h +++ b/include/media/EffectBassBoostApi.h @@ -17,7 +17,7 @@ #ifndef ANDROID_EFFECTBASSBOOSTAPI_H_ #define ANDROID_EFFECTBASSBOOSTAPI_H_ -#include +#include #if __cplusplus extern "C" { diff --git a/include/media/EffectEnvironmentalReverbApi.h b/include/media/EffectEnvironmentalReverbApi.h index 36accd8..f11c5ec 100644 --- a/include/media/EffectEnvironmentalReverbApi.h +++ b/include/media/EffectEnvironmentalReverbApi.h @@ -17,7 +17,7 @@ #ifndef ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_ #define ANDROID_EFFECTENVIRONMENTALREVERBAPI_H_ -#include +#include #if __cplusplus extern "C" { diff --git a/include/media/EffectEqualizerApi.h b/include/media/EffectEqualizerApi.h index 0492ea0..950d138 100644 --- a/include/media/EffectEqualizerApi.h +++ b/include/media/EffectEqualizerApi.h @@ -17,7 +17,7 @@ #ifndef ANDROID_EFFECTEQUALIZERAPI_H_ #define ANDROID_EFFECTEQUALIZERAPI_H_ -#include +#include #ifndef OPENSL_ES_H_ static const effect_uuid_t SL_IID_EQUALIZER_ = { 0x0bed4300, 0xddd6, 0x11db, 0x8f34, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }; diff --git a/include/media/EffectPresetReverbApi.h b/include/media/EffectPresetReverbApi.h index a3f094c..e5b168a 100644 --- a/include/media/EffectPresetReverbApi.h +++ b/include/media/EffectPresetReverbApi.h @@ -17,7 +17,7 @@ #ifndef ANDROID_EFFECTPRESETREVERBAPI_H_ #define ANDROID_EFFECTPRESETREVERBAPI_H_ -#include +#include #if __cplusplus extern "C" { diff --git a/include/media/EffectVirtualizerApi.h b/include/media/EffectVirtualizerApi.h index c3d5131..2e216e2 100644 --- a/include/media/EffectVirtualizerApi.h +++ b/include/media/EffectVirtualizerApi.h @@ -17,7 +17,7 @@ #ifndef ANDROID_EFFECTVIRTUALIZERAPI_H_ #define ANDROID_EFFECTVIRTUALIZERAPI_H_ -#include +#include #if __cplusplus extern "C" { diff --git a/include/media/EffectVisualizerApi.h b/include/media/EffectVisualizerApi.h index bef1a4f..e0fa328 100644 --- a/include/media/EffectVisualizerApi.h +++ b/include/media/EffectVisualizerApi.h @@ -17,7 +17,7 @@ #ifndef ANDROID_EFFECTVISUALIZERAPI_H_ #define ANDROID_EFFECTVISUALIZERAPI_H_ -#include +#include #if __cplusplus extern "C" { diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h index 0ed1a14..b63fac6 100644 --- a/include/media/EffectsFactoryApi.h +++ b/include/media/EffectsFactoryApi.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include #if __cplusplus extern "C" { @@ -99,17 +99,17 @@ int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor); // use especially with tunneled HW accelerated effects // // Input/Output: -// pInterface: address where to return the effect interface. +// pHandle: address where to return the effect handle. // // Output: // returned value: 0 successful operation. // -ENODEV factory failed to initialize -// -EINVAL invalid pEffectUuid or pInterface +// -EINVAL invalid pEffectUuid or pHandle // -ENOENT no effect with this uuid found -// *pInterface: updated with the effect interface. +// *pHandle: updated with the effect handle. // //////////////////////////////////////////////////////////////////////////////// -int EffectCreate(effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_interface_t *pInterface); +int EffectCreate(effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle); //////////////////////////////////////////////////////////////////////////////// // @@ -120,7 +120,7 @@ int EffectCreate(effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, ef // released. // // Input: -// interface: handler on the effect interface to be released. +// handle: handler on the effect interface to be released. // // Output: // returned value: 0 successful operation. @@ -128,7 +128,7 @@ int EffectCreate(effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t ioId, ef // -EINVAL invalid interface handler // //////////////////////////////////////////////////////////////////////////////// -int EffectRelease(effect_interface_t interface); +int EffectRelease(effect_handle_t handle); //////////////////////////////////////////////////////////////////////////////// // diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h index 589f7cd..75f3e71 100644 --- a/include/media/IAudioFlinger.h +++ b/include/media/IAudioFlinger.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/media/libeffects/data/audio_effects.conf b/media/libeffects/data/audio_effects.conf new file mode 100644 index 0000000..e6a7b37 --- /dev/null +++ b/media/libeffects/data/audio_effects.conf @@ -0,0 +1,57 @@ +# List of effect libraries to load. Each library element must contain a "path" element +# giving the full path of the library .so file. +libraries { + bundle { + path /system/lib/soundfx/libbundlewrapper.so + } + reverb { + path /system/lib/soundfx/libreverbwrapper.so + } + visualizer { + path /system/lib/soundfx/libvisualizer.so + } +} + +# list of effects to load. Each effect element must contain a "library" and a "uuid" element. +# The value of the "library" element must correspond to the name of one library element in the +# "libraries" element. +# The name of the effect element is indicative, only the value of the "uuid" element +# designates the effect. +effects { + bassboost { + library bundle + uuid 8631f300-72e2-11df-b57e-0002a5d5c51b + } + virtualizer { + library bundle + uuid 1d4033c0-8557-11df-9f2d-0002a5d5c51b + } + equalizer { + library bundle + uuid ce772f20-847d-11df-bb17-0002a5d5c51b + } + volume { + library bundle + uuid 119341a0-8469-11df-81f9- 0002a5d5c51b + } + reverb_env_aux { + library reverb + uuid 4a387fc0-8ab3-11df-8bad- 0002a5d5c51b + } + reverb_env_ins { + library reverb + uuid c7a511a0-a3bb-11df-860e-0002a5d5c51b + } + reverb_pre_aux { + library reverb + uuid f29a1400-a3bb-11df-8ddc-0002a5d5c51b + } + reverb_pre_ins { + library reverb + uuid 172cdf00-a3bc-11df-a72f-0002a5d5c51b + } + visualizer { + library visualizer + uuid d069d9e0-8329-11df-9168-0002a5d5c51b + } +} diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c index c19a505..b541be5 100644 --- a/media/libeffects/factory/EffectsFactory.c +++ b/media/libeffects/factory/EffectsFactory.c @@ -22,6 +22,8 @@ #include #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 @@ -30,30 +32,39 @@ static uint32_t gNumEffects; // total number number of effects static list_elem_t *gCurLib; // current library in enumeration process static list_elem_t *gCurEffect; // current effect in enumeration process static uint32_t gCurEffectIdx; // current effect index in enumeration process +static lib_entry_t *gCachedLibrary; // last library accessed by getLibrary() -const char * const gEffectLibPath = "/system/lib/soundfx"; // path to built-in effect libraries static int gInitDone; // true is global initialization has been preformed -static int gNextLibId; // used by loadLibrary() to allocate unique library handles static int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects // was not modified since last call to EffectQueryNumberEffects() + ///////////////////////////////////////////////// // Local functions prototypes ///////////////////////////////////////////////// static int init(); -static int loadLibrary(const char *libPath, int *handle); -static int unloadLibrary(int handle); +static int loadEffectConfigFile(const char *path); +static int loadLibraries(cnode *root); +static int loadLibrary(cnode *root, const char *name); +static int loadEffects(cnode *root); +static int loadEffect(cnode *node); +static lib_entry_t *getLibrary(const char *path); static void resetEffectEnumeration(); static uint32_t updateNumEffects(); -static int findEffect(effect_uuid_t *uuid, lib_entry_t **lib, effect_descriptor_t **desc); +static int findEffect(effect_uuid_t *type, + effect_uuid_t *uuid, + lib_entry_t **lib, + effect_descriptor_t **desc); static void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len); +static int stringToUuid(const char *str, effect_uuid_t *uuid); +static int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen); ///////////////////////////////////////////////// // Effect Control Interface functions ///////////////////////////////////////////////// -int Effect_Process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) +int Effect_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) { int ret = init(); if (ret < 0) { @@ -73,7 +84,7 @@ int Effect_Process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buff return ret; } -int Effect_Command(effect_interface_t self, +int Effect_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, @@ -98,9 +109,31 @@ int Effect_Command(effect_interface_t self, return ret; } +int Effect_GetDescriptor(effect_handle_t self, + effect_descriptor_t *desc) +{ + int ret = init(); + if (ret < 0) { + return ret; + } + effect_entry_t *fx = (effect_entry_t *)self; + pthread_mutex_lock(&gLibLock); + if (fx->lib == NULL) { + pthread_mutex_unlock(&gLibLock); + return -EPIPE; + } + pthread_mutex_lock(&fx->lib->lock); + pthread_mutex_unlock(&gLibLock); + + ret = (*fx->subItfe)->get_descriptor(fx->subItfe, desc); + pthread_mutex_unlock(&fx->lib->lock); + return ret; +} + const struct effect_interface_s gInterface = { Effect_Process, - Effect_Command + Effect_Command, + Effect_GetDescriptor }; ///////////////////////////////////////////////// @@ -182,7 +215,7 @@ int EffectGetDescriptor(effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) return -EINVAL; } pthread_mutex_lock(&gLibLock); - ret = findEffect(uuid, &l, &d); + ret = findEffect(NULL, uuid, &l, &d); if (ret == 0) { memcpy(pDescriptor, d, sizeof(effect_descriptor_t)); } @@ -190,17 +223,17 @@ int EffectGetDescriptor(effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) return ret; } -int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_interface_t *pInterface) +int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle) { list_elem_t *e = gLibraryList; lib_entry_t *l = NULL; effect_descriptor_t *d = NULL; - effect_interface_t itfe; + effect_handle_t itfe; effect_entry_t *fx; int found = 0; int ret; - if (uuid == NULL || pInterface == NULL) { + if (uuid == NULL || pHandle == NULL) { return -EINVAL; } @@ -218,15 +251,15 @@ int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_in pthread_mutex_lock(&gLibLock); - ret = findEffect(uuid, &l, &d); + ret = findEffect(NULL, uuid, &l, &d); if (ret < 0){ goto exit; } // create effect in library - ret = l->createFx(uuid, sessionId, ioId, &itfe); + l->desc->create_effect(uuid, sessionId, ioId, &itfe); if (ret != 0) { - LOGW("EffectCreate() library %s: could not create fx %s, error %d", l->path, d->name, ret); + LOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret); goto exit; } @@ -241,16 +274,16 @@ int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_in e->next = gEffectList; gEffectList = e; - *pInterface = (effect_interface_t)fx; + *pHandle = (effect_handle_t)fx; - LOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pInterface, itfe, l->path); + LOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pHandle, itfe, l->name); exit: pthread_mutex_unlock(&gLibLock); return ret; } -int EffectRelease(effect_interface_t interface) +int EffectRelease(effect_handle_t handle) { effect_entry_t *fx; list_elem_t *e1; @@ -266,7 +299,7 @@ int EffectRelease(effect_interface_t interface) e1 = gEffectList; e2 = NULL; while (e1) { - if (e1->object == interface) { + if (e1->object == handle) { if (e2) { e2->next = e1->next; } else { @@ -286,10 +319,10 @@ int EffectRelease(effect_interface_t interface) // release effect in library if (fx->lib == NULL) { - LOGW("EffectRelease() fx %p library already unloaded", interface); + LOGW("EffectRelease() fx %p library already unloaded", handle); } else { pthread_mutex_lock(&fx->lib->lock); - fx->lib->releaseFx(fx->subItfe); + fx->lib->desc->release_effect(fx->subItfe); pthread_mutex_unlock(&fx->lib->lock); } free(fx); @@ -301,29 +334,14 @@ exit: int EffectLoadLibrary(const char *libPath, int *handle) { - int ret = init(); - if (ret < 0) { - return ret; - } - if (libPath == NULL) { - return -EINVAL; - } - - ret = loadLibrary(libPath, handle); - updateNumEffects(); - return ret; + // TODO: see if this interface still makes sense with the use of config files + return -ENOSYS; } int EffectUnloadLibrary(int handle) { - int ret = init(); - if (ret < 0) { - return ret; - } - - ret = unloadLibrary(handle); - updateNumEffects(); - return ret; + // TODO: see if this interface still makes sense with the use of config files + return -ENOSYS; } int EffectIsNullUuid(effect_uuid_t *uuid) @@ -339,9 +357,6 @@ int EffectIsNullUuid(effect_uuid_t *uuid) ///////////////////////////////////////////////// int init() { - struct dirent *ent; - DIR *dir = NULL; - char libpath[PATH_MAX]; int hdl; if (gInitDone) { @@ -350,214 +365,210 @@ int init() { pthread_mutex_init(&gLibLock, NULL); - // load built-in libraries - dir = opendir(gEffectLibPath); - if (dir == NULL) { - return -ENODEV; + if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) { + loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE); + } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) { + loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE); } - while ((ent = readdir(dir)) != NULL) { - LOGV("init() reading file %s", ent->d_name); - if ((strlen(ent->d_name) < 3) || - strncmp(ent->d_name, "lib", 3) != 0 || - strncmp(ent->d_name + strlen(ent->d_name) - 3, ".so", 3) != 0) { - continue; - } - strcpy(libpath, gEffectLibPath); - strcat(libpath, "/"); - strcat(libpath, ent->d_name); - if (loadLibrary(libpath, &hdl) < 0) { - LOGW("init() failed to load library %s",libpath); - } - } - closedir(dir); + updateNumEffects(); gInitDone = 1; LOGV("init() done"); return 0; } - -int loadLibrary(const char *libPath, int *handle) +int loadEffectConfigFile(const char *path) { - void *hdl; - effect_QueryNumberEffects_t queryNumFx; - effect_QueryEffect_t queryFx; - effect_CreateEffect_t createFx; - effect_ReleaseEffect_t releaseFx; - uint32_t numFx; - uint32_t fx; - int ret; - list_elem_t *e, *descHead = NULL; - lib_entry_t *l; + cnode *root; + char *data; - if (handle == NULL) { - return -EINVAL; + data = load_file(path, NULL); + if (data == NULL) { + return -ENODEV; } + root = config_node("", ""); + config_load(root, data); + loadLibraries(root); + loadEffects(root); + config_free(root); + free(root); + free(data); - *handle = 0; + return 0; +} - hdl = dlopen(libPath, RTLD_NOW); - if (hdl == 0) { - LOGW("could open lib %s", libPath); - return -ENODEV; - } +int loadLibraries(cnode *root) +{ + cnode *node; - // Check functions availability - queryNumFx = (effect_QueryNumberEffects_t)dlsym(hdl, "EffectQueryNumberEffects"); - if (queryNumFx == NULL) { - LOGW("could not get EffectQueryNumberEffects from lib %s", libPath); - ret = -ENODEV; - goto error; + node = config_find(root, LIBRARIES_TAG); + if (node == NULL) { + return -ENOENT; } - queryFx = (effect_QueryEffect_t)dlsym(hdl, "EffectQueryEffect"); - if (queryFx == NULL) { - LOGW("could not get EffectQueryEffect from lib %s", libPath); - ret = -ENODEV; - goto error; + node = node->first_child; + while (node) { + loadLibrary(node, node->name); + node = node->next; } - createFx = (effect_CreateEffect_t)dlsym(hdl, "EffectCreate"); - if (createFx == NULL) { - LOGW("could not get EffectCreate from lib %s", libPath); - ret = -ENODEV; - goto error; + return 0; +} + +int loadLibrary(cnode *root, const char *name) +{ + cnode *node; + void *hdl; + audio_effect_library_t *desc; + list_elem_t *e; + lib_entry_t *l; + + node = config_find(root, PATH_TAG); + if (node == NULL) { + return -EINVAL; } - releaseFx = (effect_ReleaseEffect_t)dlsym(hdl, "EffectRelease"); - if (releaseFx == NULL) { - LOGW("could not get EffectRelease from lib %s", libPath); - ret = -ENODEV; + + hdl = dlopen(node->value, RTLD_NOW); + if (hdl == NULL) { + LOGW("loadLibrary() failed to open %s", node->value); goto error; } - // load effect descriptors - ret = queryNumFx(&numFx); - if (ret) { + desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR); + if (desc == NULL) { + LOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR); goto error; } - for (fx = 0; fx < numFx; fx++) { - effect_descriptor_t *d = malloc(sizeof(effect_descriptor_t)); - if (d == NULL) { - ret = -ENOMEM; - goto error; - } - ret = queryFx(fx, d); - if (ret == 0) { -#if (LOG_NDEBUG==0) - char s[256]; - dumpEffectDescriptor(d, s, 256); - LOGV("loadLibrary() read descriptor %p:%s",d, s); -#endif - if (d->apiVersion != EFFECT_API_VERSION) { - LOGW("Bad API version %04x on lib %s", d->apiVersion, libPath); - free(d); - continue; - } - e = malloc(sizeof(list_elem_t)); - if (e == NULL) { - free(d); - ret = -ENOMEM; - goto error; - } - e->object = d; - e->next = descHead; - descHead = e; - } else { - LOGW("Error querying effect # %d on lib %s", fx, libPath); - } + if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) { + LOGW("getLibrary() bad tag %08x in lib info struct", desc->tag); + goto error; } - pthread_mutex_lock(&gLibLock); + if (EFFECT_API_VERSION_MAJOR(desc->version) != + EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) { + LOGW("loadLibrary() bad lib version %08x", desc->version); + goto error; + } // add entry for library in gLibraryList l = malloc(sizeof(lib_entry_t)); - l->id = ++gNextLibId; + l->name = strndup(name, PATH_MAX); + l->path = strndup(node->value, PATH_MAX); l->handle = hdl; - strncpy(l->path, libPath, PATH_MAX); - l->createFx = createFx; - l->releaseFx = releaseFx; - l->effects = descHead; + l->desc = desc; + l->effects = NULL; pthread_mutex_init(&l->lock, NULL); e = malloc(sizeof(list_elem_t)); - e->next = gLibraryList; e->object = l; + pthread_mutex_lock(&gLibLock); + e->next = gLibraryList; gLibraryList = e; pthread_mutex_unlock(&gLibLock); - LOGV("loadLibrary() linked library %p", l); - - *handle = l->id; + LOGV("getLibrary() linked library %p for path %s", l, node->value); return 0; error: - LOGW("loadLibrary() error: %d on lib: %s", ret, libPath); - while (descHead) { - free(descHead->object); - e = descHead->next; - free(descHead); - descHead = e;; - } - dlclose(hdl); - return ret; + if (hdl != NULL) { + dlclose(hdl); + } + return -EINVAL; } -int unloadLibrary(int handle) +int loadEffects(cnode *root) { - void *hdl; - int ret; - list_elem_t *el1, *el2; + cnode *node; + + node = config_find(root, EFFECTS_TAG); + if (node == NULL) { + return -ENOENT; + } + node = node->first_child; + while (node) { + loadEffect(node); + node = node->next; + } + return 0; +} + +int loadEffect(cnode *root) +{ + cnode *node; + effect_uuid_t uuid; lib_entry_t *l; - effect_entry_t *fx; + effect_descriptor_t *d; + list_elem_t *e; - pthread_mutex_lock(&gLibLock); - el1 = gLibraryList; - el2 = NULL; - while (el1) { - l = (lib_entry_t *)el1->object; - if (handle == l->id) { - if (el2) { - el2->next = el1->next; - } else { - gLibraryList = el1->next; - } - free(el1); - break; - } - el2 = el1; - el1 = el1->next; + node = config_find(root, LIBRARY_TAG); + if (node == NULL) { + return -EINVAL; } - pthread_mutex_unlock(&gLibLock); - if (el1 == NULL) { - return -ENOENT; + + l = getLibrary(node->value); + if (l == NULL) { + LOGW("loadEffect() could not get library %s", node->value); + return -EINVAL; } - // clear effect descriptor list - el1 = l->effects; - while (el1) { - free(el1->object); - el2 = el1->next; - free(el1); - el1 = el2; + node = config_find(root, UUID_TAG); + if (node == NULL) { + return -EINVAL; + } + if (stringToUuid(node->value, &uuid) != 0) { + LOGW("loadEffect() invalid uuid %s", node->value); + return -EINVAL; + } + + d = malloc(sizeof(effect_descriptor_t)); + if (l->desc->get_descriptor(&uuid, d) != 0) { + char s[40]; + uuidToString(&uuid, s, 40); + LOGW("Error querying effect %s on lib %s", s, l->name); + free(d); + return -EINVAL; + } +#if (LOG_NDEBUG==0) + char s[256]; + dumpEffectDescriptor(d, s, 256); + LOGV("loadEffect() read descriptor %p:%s",d, s); +#endif + if (EFFECT_API_VERSION_MAJOR(d->apiVersion) != + EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) { + LOGW("Bad API version %08x on lib %s", d->apiVersion, l->name); + free(d); + return -EINVAL; } + e = malloc(sizeof(list_elem_t)); + e->object = d; + e->next = l->effects; + l->effects = e; + + return 0; +} - // disable all effects from this library - pthread_mutex_lock(&l->lock); +lib_entry_t *getLibrary(const char *name) +{ + list_elem_t *e; - el1 = gEffectList; - while (el1) { - fx = (effect_entry_t *)el1->object; - if (fx->lib == l) { - fx->lib = NULL; + if (gCachedLibrary && + !strncmp(gCachedLibrary->name, name, PATH_MAX)) { + return gCachedLibrary; + } + + e = gLibraryList; + while (e) { + lib_entry_t *l = (lib_entry_t *)e->object; + if (!strcmp(l->name, name)) { + gCachedLibrary = l; + return l; } - el1 = el1->next; + e = e->next; } - pthread_mutex_unlock(&l->lock); - dlclose(l->handle); - free(l); - return 0; + return NULL; } + void resetEffectEnumeration() { gCurLib = gLibraryList; @@ -589,7 +600,10 @@ uint32_t updateNumEffects() { return cnt; } -int findEffect(effect_uuid_t *uuid, lib_entry_t **lib, effect_descriptor_t **desc) +int findEffect(effect_uuid_t *type, + effect_uuid_t *uuid, + lib_entry_t **lib, + effect_descriptor_t **desc) { list_elem_t *e = gLibraryList; lib_entry_t *l = NULL; @@ -602,7 +616,11 @@ int findEffect(effect_uuid_t *uuid, lib_entry_t **lib, effect_descriptor_t **des list_elem_t *efx = l->effects; while (efx) { d = (effect_descriptor_t *)efx->object; - if (memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) { + if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) { + found = 1; + break; + } + if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) { found = 1; break; } @@ -614,9 +632,11 @@ int findEffect(effect_uuid_t *uuid, lib_entry_t **lib, effect_descriptor_t **des LOGV("findEffect() effect not found"); ret = -ENOENT; } else { - LOGV("findEffect() found effect: %s in lib %s", d->name, l->path); + LOGV("findEffect() found effect: %s in lib %s", d->name, l->name); *lib = l; - *desc = d; + if (desc) { + *desc = d; + } } return ret; @@ -626,17 +646,12 @@ void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len) { char s[256]; snprintf(str, len, "\nEffect Descriptor %p:\n", desc); - sprintf(s, "- UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n", - desc->uuid.timeLow, desc->uuid.timeMid, desc->uuid.timeHiAndVersion, - desc->uuid.clockSeq, desc->uuid.node[0], desc->uuid.node[1],desc->uuid.node[2], - desc->uuid.node[3],desc->uuid.node[4],desc->uuid.node[5]); - strncat(str, s, len); - sprintf(s, "- TYPE: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n", - desc->type.timeLow, desc->type.timeMid, desc->type.timeHiAndVersion, - desc->type.clockSeq, desc->type.node[0], desc->type.node[1],desc->type.node[2], - desc->type.node[3],desc->type.node[4],desc->type.node[5]); - strncat(str, s, len); - sprintf(s, "- apiVersion: %04X\n- flags: %08X\n", + strncat(str, "- TYPE: ", len); + uuidToString(&desc->uuid, s, 256); + snprintf(str, len, "- UUID: %s\n", s); + uuidToString(&desc->type, s, 256); + snprintf(str, len, "- TYPE: %s\n", s); + sprintf(s, "- apiVersion: %08X\n- flags: %08X\n", desc->apiVersion, desc->flags); strncat(str, s, len); sprintf(s, "- name: %s\n", desc->name); @@ -645,3 +660,43 @@ void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len) { strncat(str, s, len); } +int stringToUuid(const char *str, effect_uuid_t *uuid) +{ + int tmp[10]; + + if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", + tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) { + return -EINVAL; + } + uuid->timeLow = (uint32_t)tmp[0]; + uuid->timeMid = (uint16_t)tmp[1]; + uuid->timeHiAndVersion = (uint16_t)tmp[2]; + uuid->clockSeq = (uint16_t)tmp[3]; + uuid->node[0] = (uint8_t)tmp[4]; + uuid->node[1] = (uint8_t)tmp[5]; + uuid->node[2] = (uint8_t)tmp[6]; + uuid->node[3] = (uint8_t)tmp[7]; + uuid->node[4] = (uint8_t)tmp[8]; + uuid->node[5] = (uint8_t)tmp[9]; + + return 0; +} + +int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen) +{ + + snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", + uuid->timeLow, + uuid->timeMid, + uuid->timeHiAndVersion, + uuid->clockSeq, + uuid->node[0], + uuid->node[1], + uuid->node[2], + uuid->node[3], + uuid->node[4], + uuid->node[5]); + + return 0; +} + diff --git a/media/libeffects/factory/EffectsFactory.h b/media/libeffects/factory/EffectsFactory.h index 8f543ca..fcc0dba 100644 --- a/media/libeffects/factory/EffectsFactory.h +++ b/media/libeffects/factory/EffectsFactory.h @@ -22,29 +22,35 @@ #include #include - #if __cplusplus 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; struct list_elem_s *next; } list_elem_t; typedef struct lib_entry_s { - char path[PATH_MAX]; + audio_effect_library_t *desc; + char *name; + char *path; void *handle; - int id; - effect_CreateEffect_t createFx; - effect_ReleaseEffect_t releaseFx; list_elem_t *effects; //list of effect_descriptor_t pthread_mutex_t lock; } lib_entry_t; typedef struct effect_entry_s { struct effect_interface_s *itfe; - effect_interface_t subItfe; + effect_handle_t subItfe; lib_entry_t *lib; } effect_entry_t; diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp index 0b061db..21c451f 100644 --- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp +++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp @@ -27,7 +27,7 @@ #include -// effect_interface_t interface implementation for bass boost +// effect_handle_t interface implementation for bass boost extern "C" const struct effect_interface_s gLvmEffectInterface; #define LVM_ERROR_CHECK(LvmStatus, callingFunc, calledFunc){\ @@ -71,7 +71,7 @@ int SessionIndex[LVM_MAX_SESSIONS]; const effect_descriptor_t gBassBoostDescriptor = { {0x0634f220, 0xddd4, 0x11db, 0xa0fc, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }}, {0x8631f300, 0x72e2, 0x11df, 0xb57e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_DEVICE_IND | EFFECT_FLAG_VOLUME_CTRL), BASS_BOOST_CUP_LOAD_ARM9E, @@ -84,7 +84,7 @@ const effect_descriptor_t gBassBoostDescriptor = { const effect_descriptor_t gVirtualizerDescriptor = { {0x37cc2c00, 0xdddd, 0x11db, 0x8577, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, {0x1d4033c0, 0x8557, 0x11df, 0x9f2d, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_DEVICE_IND | EFFECT_FLAG_VOLUME_CTRL), VIRTUALIZER_CUP_LOAD_ARM9E, @@ -97,7 +97,7 @@ const effect_descriptor_t gVirtualizerDescriptor = { const effect_descriptor_t gEqualizerDescriptor = { {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type {0xce772f20, 0x847d, 0x11df, 0xbb17, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid Eq NXP - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL), EQUALIZER_CUP_LOAD_ARM9E, BUNDLE_MEM_USAGE, @@ -109,7 +109,7 @@ const effect_descriptor_t gEqualizerDescriptor = { const effect_descriptor_t gVolumeDescriptor = { {0x09e8ede0, 0xddde, 0x11db, 0xb4f6, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }}, {0x119341a0, 0x8469, 0x11df, 0x81f9, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b }}, //uuid VOL NXP - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL), VOLUME_CUP_LOAD_ARM9E, BUNDLE_MEM_USAGE, @@ -187,7 +187,7 @@ extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescripto extern "C" int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, - effect_interface_t *pInterface){ + effect_handle_t *pHandle){ int ret = 0; int sessionNo; int i; @@ -197,7 +197,7 @@ extern "C" int EffectCreate(effect_uuid_t *uuid, LOGV("\n\tEffectCreate start session %d", sessionId); - if (pInterface == NULL || uuid == NULL){ + if (pHandle == NULL || uuid == NULL){ LOGV("\tLVM_ERROR : EffectCreate() called with NULL pointer"); ret = -EINVAL; goto exit; @@ -355,19 +355,19 @@ exit: } delete pContext; } - *pInterface = (effect_interface_t)NULL; + *pHandle = (effect_handle_t)NULL; } else { - *pInterface = (effect_interface_t)pContext; + *pHandle = (effect_handle_t)pContext; } LOGV("\tEffectCreate end..\n\n"); return ret; } /* end EffectCreate */ -extern "C" int EffectRelease(effect_interface_t interface){ - LOGV("\n\tEffectRelease start %p", interface); - EffectContext * pContext = (EffectContext *)interface; +extern "C" int EffectRelease(effect_handle_t handle){ + LOGV("\n\tEffectRelease start %p", handle); + EffectContext * pContext = (EffectContext *)handle; - LOGV("\tEffectRelease start interface: %p, context %p", interface, pContext->pBundledContext); + LOGV("\tEffectRelease start handle: %p, context %p", handle, pContext->pBundledContext); if (pContext == NULL){ LOGV("\tLVM_ERROR : EffectRelease called with NULL pointer"); return -EINVAL; @@ -460,6 +460,34 @@ extern "C" int EffectRelease(effect_interface_t interface){ } /* end EffectRelease */ +extern "C" int EffectGetDescriptor(effect_uuid_t *uuid, + effect_descriptor_t *pDescriptor) { + const effect_descriptor_t *desc = NULL; + + if (pDescriptor == NULL || uuid == NULL){ + LOGV("EffectGetDescriptor() called with NULL pointer"); + return -EINVAL; + } + + if (memcmp(uuid, &gBassBoostDescriptor.uuid, sizeof(effect_uuid_t)) == 0) { + desc = &gBassBoostDescriptor; + } else if (memcmp(uuid, &gVirtualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) { + desc = &gVirtualizerDescriptor; + } else if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) { + desc = &gEqualizerDescriptor; + } else if (memcmp(uuid, &gVolumeDescriptor.uuid, sizeof(effect_uuid_t)) == 0) { + desc = &gVolumeDescriptor; + } + + if (desc == NULL) { + return -EINVAL; + } + + memcpy(pDescriptor, desc, sizeof(effect_descriptor_t)); + + return 0; +} /* end EffectGetDescriptor */ + void LvmGlobalBundle_init(){ LOGV("\tLvmGlobalBundle_init start"); for(int i=0; iconfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; - pContext->config.inputCfg.channels = CHANNEL_STEREO; - pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15; + pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; + pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; pContext->config.inputCfg.samplingRate = 44100; pContext->config.inputCfg.bufferProvider.getBuffer = NULL; pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL; pContext->config.inputCfg.bufferProvider.cookie = NULL; pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL; pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE; - pContext->config.outputCfg.channels = CHANNEL_STEREO; - pContext->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15; + pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; + pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; pContext->config.outputCfg.samplingRate = 44100; pContext->config.outputCfg.bufferProvider.getBuffer = NULL; pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL; @@ -928,10 +956,10 @@ int Effect_configure(EffectContext *pContext, effect_config_t *pConfig){ CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate); CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels); CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format); - CHECK_ARG(pConfig->inputCfg.channels == CHANNEL_STEREO); + CHECK_ARG(pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO); CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE); - CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15); + CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT); memcpy(&pContext->config, pConfig, sizeof(effect_config_t)); @@ -2545,8 +2573,9 @@ int16_t LVC_Convert_VolToDb(uint32_t vol){ } // namespace } // namespace +extern "C" { /* Effect Control Interface Implementation: Process */ -extern "C" int Effect_process(effect_interface_t self, +int Effect_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer){ EffectContext * pContext = (EffectContext *) self; @@ -2666,7 +2695,7 @@ extern "C" int Effect_process(effect_interface_t self, } /* end Effect_process */ /* Effect Control Interface Implementation: Command */ -extern "C" int Effect_command(effect_interface_t self, +int Effect_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, @@ -3016,11 +3045,11 @@ extern "C" int Effect_command(effect_interface_t self, case EFFECT_CMD_SET_DEVICE: { LOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_DEVICE start"); - audio_device_e device = *(audio_device_e *)pCmdData; + uint32_t device = *(uint32_t *)pCmdData; if(pContext->EffectType == LVM_BASS_BOOST){ - if((device == DEVICE_SPEAKER)||(device == DEVICE_BLUETOOTH_SCO_CARKIT)|| - (device == DEVICE_BLUETOOTH_A2DP_SPEAKER)){ + if((device == AUDIO_DEVICE_OUT_SPEAKER)||(device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)|| + (device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)){ LOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_BASS_BOOST %d", *(int32_t *)pCmdData); LOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_BAS_BOOST"); @@ -3051,8 +3080,8 @@ extern "C" int Effect_command(effect_interface_t self, } } if(pContext->EffectType == LVM_VIRTUALIZER){ - if((device == DEVICE_SPEAKER)||(device == DEVICE_BLUETOOTH_SCO_CARKIT)|| - (device == DEVICE_BLUETOOTH_A2DP_SPEAKER)){ + if((device == AUDIO_DEVICE_OUT_SPEAKER)||(device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT)|| + (device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)){ LOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_VIRTUALIZER %d", *(int32_t *)pCmdData); LOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_VIRTUALIZER"); @@ -3164,9 +3193,57 @@ extern "C" int Effect_command(effect_interface_t self, return 0; } /* end Effect_command */ -// effect_interface_t interface implementation for effect +/* Effect Control Interface Implementation: get_descriptor */ +int Effect_getDescriptor(effect_handle_t self, + effect_descriptor_t *pDescriptor) +{ + EffectContext * pContext = (EffectContext *) self; + const effect_descriptor_t *desc; + + if (pContext == NULL || pDescriptor == NULL) { + LOGV("Effect_getDescriptor() invalid param"); + return -EINVAL; + } + + switch(pContext->EffectType) { + case LVM_BASS_BOOST: + desc = &android::gBassBoostDescriptor; + break; + case LVM_VIRTUALIZER: + desc = &android::gVirtualizerDescriptor; + break; + case LVM_EQUALIZER: + desc = &android::gEqualizerDescriptor; + break; + case LVM_VOLUME: + desc = &android::gVolumeDescriptor; + break; + default: + return -EINVAL; + } + + memcpy(pDescriptor, desc, sizeof(effect_descriptor_t)); + + return 0; +} /* end Effect_getDescriptor */ + +// effect_handle_t interface implementation for effect const struct effect_interface_s gLvmEffectInterface = { Effect_process, - Effect_command + Effect_command, + Effect_getDescriptor }; /* end gLvmEffectInterface */ +audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { + tag : AUDIO_EFFECT_LIBRARY_TAG, + version : EFFECT_LIBRARY_API_VERSION, + name : "Effect Bundle Library", + implementor : "NXP Software Ltd.", + query_num_effects : android::EffectQueryNumberEffects, + query_effect : android::EffectQueryEffect, + create_effect : android::EffectCreate, + release_effect : android::EffectRelease, + get_descriptor : android::EffectGetDescriptor, +}; + +} diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp index 9097e20..2727375 100755 --- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp +++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp @@ -27,7 +27,7 @@ #include #include -// effect_interface_t interface implementation for reverb +// effect_handle_t interface implementation for reverb extern "C" const struct effect_interface_s gReverbInterface; #define LVM_ERROR_CHECK(LvmStatus, callingFunc, calledFunc){\ @@ -77,7 +77,7 @@ const static t_reverb_settings sReverbPresets[] = { const effect_descriptor_t gAuxEnvReverbDescriptor = { { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e } }, { 0x4a387fc0, 0x8ab3, 0x11df, 0x8bad, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }, - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, EFFECT_FLAG_TYPE_AUXILIARY, LVREV_CUP_LOAD_ARM9E, LVREV_MEM_USAGE, @@ -89,7 +89,7 @@ const effect_descriptor_t gAuxEnvReverbDescriptor = { static const effect_descriptor_t gInsertEnvReverbDescriptor = { {0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}}, {0xc7a511a0, 0xa3bb, 0x11df, 0x860e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL, LVREV_CUP_LOAD_ARM9E, LVREV_MEM_USAGE, @@ -101,7 +101,7 @@ static const effect_descriptor_t gInsertEnvReverbDescriptor = { static const effect_descriptor_t gAuxPresetReverbDescriptor = { {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, {0xf29a1400, 0xa3bb, 0x11df, 0x8ddc, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, EFFECT_FLAG_TYPE_AUXILIARY, LVREV_CUP_LOAD_ARM9E, LVREV_MEM_USAGE, @@ -113,7 +113,7 @@ static const effect_descriptor_t gAuxPresetReverbDescriptor = { static const effect_descriptor_t gInsertPresetReverbDescriptor = { {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, {0x172cdf00, 0xa3bc, 0x11df, 0xa72f, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL, LVREV_CUP_LOAD_ARM9E, LVREV_MEM_USAGE, @@ -192,7 +192,8 @@ extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects){ return 0; } /* end EffectQueryNumberEffects */ -extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor){ +extern "C" int EffectQueryEffect(uint32_t index, + effect_descriptor_t *pDescriptor){ LOGV("\n\tEffectQueryEffect start"); LOGV("\tEffectQueryEffect processing index %d", index); if (pDescriptor == NULL){ @@ -211,7 +212,7 @@ extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescripto extern "C" int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, - effect_interface_t *pInterface){ + effect_handle_t *pHandle){ int ret; int i; int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *); @@ -219,7 +220,7 @@ extern "C" int EffectCreate(effect_uuid_t *uuid, LOGV("\t\nEffectCreate start"); - if (pInterface == NULL || uuid == NULL){ + if (pHandle == NULL || uuid == NULL){ LOGV("\tLVM_ERROR : EffectCreate() called with NULL pointer"); return -EINVAL; } @@ -270,7 +271,7 @@ extern "C" int EffectCreate(effect_uuid_t *uuid, return ret; } - *pInterface = (effect_interface_t)pContext; + *pHandle = (effect_handle_t)pContext; #ifdef LVM_PCM pContext->PcmInPtr = NULL; @@ -295,10 +296,10 @@ extern "C" int EffectCreate(effect_uuid_t *uuid, return 0; } /* end EffectCreate */ -extern "C" int EffectRelease(effect_interface_t interface){ - ReverbContext * pContext = (ReverbContext *)interface; +extern "C" int EffectRelease(effect_handle_t handle){ + ReverbContext * pContext = (ReverbContext *)handle; - LOGV("\tEffectRelease %p", interface); + LOGV("\tEffectRelease %p", handle); if (pContext == NULL){ LOGV("\tLVM_ERROR : EffectRelease called with NULL pointer"); return -EINVAL; @@ -315,6 +316,28 @@ extern "C" int EffectRelease(effect_interface_t interface){ return 0; } /* end EffectRelease */ +extern "C" int EffectGetDescriptor(effect_uuid_t *uuid, + effect_descriptor_t *pDescriptor) { + int i; + int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *); + + if (pDescriptor == NULL || uuid == NULL){ + LOGV("EffectGetDescriptor() called with NULL pointer"); + return -EINVAL; + } + + for (i = 0; i < length; i++) { + if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) { + memcpy(pDescriptor, gDescriptors[i], sizeof(effect_descriptor_t)); + LOGV("EffectGetDescriptor - UUID matched Reverb type %d, UUID = %x", + i, gDescriptors[i]->uuid.timeLow); + return 0; + } + } + + return -EINVAL; +} /* end EffectGetDescriptor */ + /* local functions */ #define CHECK_ARG(cond) { \ if (!(cond)) { \ @@ -418,9 +441,9 @@ int process( LVM_INT16 *pIn, // Check that the input is either mono or stereo - if (pContext->config.inputCfg.channels == CHANNEL_STEREO) { + if (pContext->config.inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO) { samplesPerFrame = 2; - } else if (pContext->config.inputCfg.channels != CHANNEL_MONO) { + } else if (pContext->config.inputCfg.channels != AUDIO_CHANNEL_OUT_MONO) { LOGV("\tLVREV_ERROR : process invalid PCM format"); return -EINVAL; } @@ -608,12 +631,12 @@ int Reverb_configure(ReverbContext *pContext, effect_config_t *pConfig){ CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate); CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format); - CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == CHANNEL_MONO) || - ((!pContext->auxiliary) && pConfig->inputCfg.channels == CHANNEL_STEREO)); - CHECK_ARG(pConfig->outputCfg.channels == CHANNEL_STEREO); + CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) || + ((!pContext->auxiliary) && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO)); + CHECK_ARG(pConfig->outputCfg.channels == AUDIO_CHANNEL_OUT_STEREO); CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE); - CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15); + CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT); if(pConfig->inputCfg.samplingRate != 44100){ return -EINVAL; @@ -700,20 +723,20 @@ int Reverb_init(ReverbContext *pContext){ pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; if (pContext->auxiliary) { - pContext->config.inputCfg.channels = CHANNEL_MONO; + pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO; } else { - pContext->config.inputCfg.channels = CHANNEL_STEREO; + pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; } - pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15; + pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; pContext->config.inputCfg.samplingRate = 44100; pContext->config.inputCfg.bufferProvider.getBuffer = NULL; pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL; pContext->config.inputCfg.bufferProvider.cookie = NULL; pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL; pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE; - pContext->config.outputCfg.channels = CHANNEL_STEREO; - pContext->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15; + pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; + pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; pContext->config.outputCfg.samplingRate = 44100; pContext->config.outputCfg.bufferProvider.getBuffer = NULL; pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL; @@ -800,7 +823,7 @@ int Reverb_init(ReverbContext *pContext){ params.OperatingMode = LVM_MODE_ON; params.SampleRate = LVM_FS_44100; - if(pContext->config.inputCfg.channels == CHANNEL_MONO){ + if(pContext->config.inputCfg.channels == AUDIO_CHANNEL_OUT_MONO){ params.SourceFormat = LVM_MONO; } else { params.SourceFormat = LVM_STEREO; @@ -1832,8 +1855,9 @@ int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue){ } // namespace } // namespace +extern "C" { /* Effect Control Interface Implementation: Process */ -extern "C" int Reverb_process(effect_interface_t self, +int Reverb_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer){ android::ReverbContext * pContext = (android::ReverbContext *) self; @@ -1868,7 +1892,7 @@ extern "C" int Reverb_process(effect_interface_t self, } /* end Reverb_process */ /* Effect Control Interface Implementation: Command */ -extern "C" int Reverb_command(effect_interface_t self, +int Reverb_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, @@ -2075,9 +2099,54 @@ extern "C" int Reverb_command(effect_interface_t self, return 0; } /* end Reverb_command */ -// effect_interface_t interface implementation for Reverb effect +/* Effect Control Interface Implementation: get_descriptor */ +int Reverb_getDescriptor(effect_handle_t self, + effect_descriptor_t *pDescriptor) +{ + android::ReverbContext * pContext = (android::ReverbContext *)self; + const effect_descriptor_t *desc; + + if (pContext == NULL || pDescriptor == NULL) { + LOGV("Reverb_getDescriptor() invalid param"); + return -EINVAL; + } + + if (pContext->auxiliary) { + if (pContext->preset) { + desc = &android::gAuxPresetReverbDescriptor; + } else { + desc = &android::gAuxEnvReverbDescriptor; + } + } else { + if (pContext->preset) { + desc = &android::gInsertPresetReverbDescriptor; + } else { + desc = &android::gInsertEnvReverbDescriptor; + } + } + + memcpy(pDescriptor, desc, sizeof(effect_descriptor_t)); + + return 0; +} /* end Reverb_getDescriptor */ + +// effect_handle_t interface implementation for Reverb effect const struct effect_interface_s gReverbInterface = { Reverb_process, - Reverb_command + Reverb_command, + Reverb_getDescriptor }; /* end gReverbInterface */ +audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { + tag : AUDIO_EFFECT_LIBRARY_TAG, + version : EFFECT_LIBRARY_API_VERSION, + name : "Reverb Library", + implementor : "NXP Software Ltd.", + query_num_effects : android::EffectQueryNumberEffects, + query_effect : android::EffectQueryEffect, + create_effect : android::EffectCreate, + release_effect : android::EffectRelease, + get_descriptor : android::EffectGetDescriptor, +}; + +} diff --git a/media/libeffects/testlibs/Android.mk_ b/media/libeffects/testlibs/Android.mk_ index 9ba71ed..98d477b 100644 --- a/media/libeffects/testlibs/Android.mk_ +++ b/media/libeffects/testlibs/Android.mk_ @@ -25,7 +25,7 @@ endif LOCAL_C_INCLUDES := \ $(call include-path-for, graphics corecg) -LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) @@ -60,7 +60,7 @@ endif LOCAL_C_INCLUDES := \ $(call include-path-for, graphics corecg) -LOCAL_PRELINK_MODULE := false +LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY) diff --git a/media/libeffects/testlibs/AudioFormatAdapter.h b/media/libeffects/testlibs/AudioFormatAdapter.h index d93ebe9..41f1810 100644 --- a/media/libeffects/testlibs/AudioFormatAdapter.h +++ b/media/libeffects/testlibs/AudioFormatAdapter.h @@ -18,7 +18,7 @@ #ifndef AUDIOFORMATADAPTER_H_ #define AUDIOFORMATADAPTER_H_ -#include +#include #define min(x,y) (((x) < (y)) ? (x) : (y)) @@ -75,7 +75,7 @@ public: while (numSamples > 0) { uint32_t numSamplesIter = min(numSamples, mMaxSamplesPerCall); uint32_t nSamplesChannels = numSamplesIter * mNumChannels; - if (mPcmFormat == SAMPLE_FORMAT_PCM_S7_24) { + if (mPcmFormat == AUDIO_FORMAT_PCM_8_24_BIT) { if (mBehavior == EFFECT_BUFFER_ACCESS_WRITE) { mpProcessor->process( reinterpret_cast (pIn), @@ -125,7 +125,7 @@ private: // sample. // numSamples The number of single-channel samples to process. void ConvertInput(const void *& pIn, uint32_t numSamples) { - if (mPcmFormat == SAMPLE_FORMAT_PCM_S15) { + if (mPcmFormat == AUDIO_FORMAT_PCM_16_BIT) { const int16_t * pIn16 = reinterpret_cast(pIn); audio_sample_t * pOut = mBuffer; while (numSamples-- > 0) { @@ -143,7 +143,7 @@ private: // When function exist will point to the next output sample. // numSamples The number of single-channel samples to process. void ConvertOutput(void *& pOut, uint32_t numSamples) { - if (mPcmFormat == SAMPLE_FORMAT_PCM_S15) { + if (mPcmFormat == AUDIO_FORMAT_PCM_16_BIT) { const audio_sample_t * pIn = mBuffer; int16_t * pOut16 = reinterpret_cast(pOut); if (mBehavior == EFFECT_BUFFER_ACCESS_WRITE) { diff --git a/media/libeffects/testlibs/EffectEqualizer.cpp b/media/libeffects/testlibs/EffectEqualizer.cpp index f8e4357..43dfa82 100644 --- a/media/libeffects/testlibs/EffectEqualizer.cpp +++ b/media/libeffects/testlibs/EffectEqualizer.cpp @@ -28,7 +28,7 @@ #include "AudioFormatAdapter.h" #include -// effect_interface_t interface implementation for equalizer effect +// effect_handle_t interface implementation for equalizer effect extern "C" const struct effect_interface_s gEqualizerInterface; enum equalizer_state_e { @@ -44,12 +44,12 @@ namespace { const effect_descriptor_t gEqualizerDescriptor = { {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type {0xe25aa840, 0x543b, 0x11df, 0x98a5, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST), 0, // TODO 1, "Graphic Equalizer", - "Google Inc.", + "The Android Open Source Project", }; /////////////////// BEGIN EQ PRESETS /////////////////////////////////////////// @@ -127,7 +127,8 @@ extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) { return 0; } /* end EffectQueryNumberEffects */ -extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) { +extern "C" int EffectQueryEffect(uint32_t index, + effect_descriptor_t *pDescriptor) { if (pDescriptor == NULL) { return -EINVAL; } @@ -139,15 +140,15 @@ extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescripto } /* end EffectQueryNext */ extern "C" int EffectCreate(effect_uuid_t *uuid, - int32_t sessionId, - int32_t ioId, - effect_interface_t *pInterface) { + int32_t sessionId, + int32_t ioId, + effect_handle_t *pHandle) { int ret; int i; LOGV("EffectLibCreateEffect start"); - if (pInterface == NULL || uuid == NULL) { + if (pHandle == NULL || uuid == NULL) { return -EINVAL; } @@ -168,19 +169,20 @@ extern "C" int EffectCreate(effect_uuid_t *uuid, return ret; } - *pInterface = (effect_interface_t)pContext; + *pHandle = (effect_handle_t)pContext; pContext->state = EQUALIZER_STATE_INITIALIZED; - LOGV("EffectLibCreateEffect %p, size %d", pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext)); + LOGV("EffectLibCreateEffect %p, size %d", + pContext, AudioEqualizer::GetInstanceSize(kNumBands)+sizeof(EqualizerContext)); return 0; } /* end EffectCreate */ -extern "C" int EffectRelease(effect_interface_t interface) { - EqualizerContext * pContext = (EqualizerContext *)interface; +extern "C" int EffectRelease(effect_handle_t handle) { + EqualizerContext * pContext = (EqualizerContext *)handle; - LOGV("EffectLibReleaseEffect %p", interface); + LOGV("EffectLibReleaseEffect %p", handle); if (pContext == NULL) { return -EINVAL; } @@ -192,6 +194,22 @@ extern "C" int EffectRelease(effect_interface_t interface) { return 0; } /* end EffectRelease */ +extern "C" int EffectGetDescriptor(effect_uuid_t *uuid, + effect_descriptor_t *pDescriptor) { + + if (pDescriptor == NULL || uuid == NULL){ + LOGV("EffectGetDescriptor() called with NULL pointer"); + return -EINVAL; + } + + if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) { + memcpy(pDescriptor, &gEqualizerDescriptor, sizeof(effect_descriptor_t)); + return 0; + } + + return -EINVAL; +} /* end EffectGetDescriptor */ + // //--- local functions @@ -228,14 +246,15 @@ int Equalizer_configure(EqualizerContext *pContext, effect_config_t *pConfig) CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate); CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels); CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format); - CHECK_ARG((pConfig->inputCfg.channels == CHANNEL_MONO) || (pConfig->inputCfg.channels == CHANNEL_STEREO)); + CHECK_ARG((pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) || + (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO)); CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE); - CHECK_ARG(pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S7_24 - || pConfig->inputCfg.format == SAMPLE_FORMAT_PCM_S15); + CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_8_24_BIT + || pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT); int channelCount; - if (pConfig->inputCfg.channels == CHANNEL_MONO) { + if (pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) { channelCount = 1; } else { channelCount = 2; @@ -281,16 +300,16 @@ int Equalizer_init(EqualizerContext *pContext) } pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; - pContext->config.inputCfg.channels = CHANNEL_STEREO; - pContext->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15; + pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; + pContext->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; pContext->config.inputCfg.samplingRate = 44100; pContext->config.inputCfg.bufferProvider.getBuffer = NULL; pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL; pContext->config.inputCfg.bufferProvider.cookie = NULL; pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL; pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE; - pContext->config.outputCfg.channels = CHANNEL_STEREO; - pContext->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15; + pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; + pContext->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; pContext->config.outputCfg.samplingRate = 44100; pContext->config.outputCfg.bufferProvider.getBuffer = NULL; pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL; @@ -402,7 +421,8 @@ int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t case EQ_PARAM_LEVEL_RANGE: *(int16_t *)pValue = -9600; *((int16_t *)pValue + 1) = 4800; - LOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", *(int32_t *)pValue, *((int32_t *)pValue + 1)); + LOGV("Equalizer_getParameter() EQ_PARAM_LEVEL_RANGE min %d, max %d", + *(int32_t *)pValue, *((int32_t *)pValue + 1)); break; case EQ_PARAM_BAND_LEVEL: @@ -412,7 +432,8 @@ int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t break; } *(int16_t *)pValue = (int16_t)pEqualizer->getGain(param2); - LOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", param2, *(int32_t *)pValue); + LOGV("Equalizer_getParameter() EQ_PARAM_BAND_LEVEL band %d, level %d", + param2, *(int32_t *)pValue); break; case EQ_PARAM_CENTER_FREQ: @@ -422,7 +443,8 @@ int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t break; } *(int32_t *)pValue = pEqualizer->getFrequency(param2); - LOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", param2, *(int32_t *)pValue); + LOGV("Equalizer_getParameter() EQ_PARAM_CENTER_FREQ band %d, frequency %d", + param2, *(int32_t *)pValue); break; case EQ_PARAM_BAND_FREQ_RANGE: @@ -432,13 +454,15 @@ int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t break; } pEqualizer->getBandRange(param2, *(uint32_t *)pValue, *((uint32_t *)pValue + 1)); - LOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", param2, *(int32_t *)pValue, *((int32_t *)pValue + 1)); + LOGV("Equalizer_getParameter() EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", + param2, *(int32_t *)pValue, *((int32_t *)pValue + 1)); break; case EQ_PARAM_GET_BAND: param2 = *pParam; *(uint16_t *)pValue = (uint16_t)pEqualizer->getMostRelevantBand(param2); - LOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", param2, *(int32_t *)pValue); + LOGV("Equalizer_getParameter() EQ_PARAM_GET_BAND frequency %d, band %d", + param2, *(int32_t *)pValue); break; case EQ_PARAM_CUR_PRESET: @@ -461,7 +485,8 @@ int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t strncpy(name, pEqualizer->getPresetName(param2), *pValueSize - 1); name[*pValueSize - 1] = 0; *pValueSize = strlen(name) + 1; - LOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", param2, gEqualizerPresets[param2].name, *pValueSize); + LOGV("Equalizer_getParameter() EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", + param2, gEqualizerPresets[param2].name, *pValueSize); break; case EQ_PARAM_PROPERTIES: { @@ -571,7 +596,7 @@ int Equalizer_setParameter (AudioEqualizer * pEqualizer, int32_t *pParam, void * //--- Effect Control Interface Implementation // -extern "C" int Equalizer_process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) +extern "C" int Equalizer_process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) { android::EqualizerContext * pContext = (android::EqualizerContext *) self; @@ -596,7 +621,7 @@ extern "C" int Equalizer_process(effect_interface_t self, audio_buffer_t *inBuff return 0; } // end Equalizer_process -extern "C" int Equalizer_command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize, +extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) { android::EqualizerContext * pContext = (android::EqualizerContext *) self; @@ -647,7 +672,8 @@ extern "C" int Equalizer_command(effect_interface_t self, uint32_t cmdCode, uint } break; case EFFECT_CMD_SET_PARAM: { - LOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData); + LOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p", + cmdSize, pCmdData, *replySize, pReplyData); if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) || pReplyData == NULL || *replySize != sizeof(int32_t)) { return -EINVAL; @@ -690,10 +716,37 @@ extern "C" int Equalizer_command(effect_interface_t self, uint32_t cmdCode, uint return 0; } -// effect_interface_t interface implementation for equalizer effect +extern "C" int Equalizer_getDescriptor(effect_handle_t self, + effect_descriptor_t *pDescriptor) +{ + android::EqualizerContext * pContext = (android::EqualizerContext *) self; + + if (pContext == NULL || pDescriptor == NULL) { + LOGV("Equalizer_getDescriptor() invalid param"); + return -EINVAL; + } + + memcpy(pDescriptor, &android::gEqualizerDescriptor, sizeof(effect_descriptor_t)); + + return 0; +} + +// effect_handle_t interface implementation for equalizer effect const struct effect_interface_s gEqualizerInterface = { Equalizer_process, - Equalizer_command + Equalizer_command, + Equalizer_getDescriptor }; +audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { + tag : AUDIO_EFFECT_LIBRARY_TAG, + version : EFFECT_LIBRARY_API_VERSION, + name : "Test Equalizer Library", + implementor : "The Android Open Source Project", + query_num_effects : android::EffectQueryNumberEffects, + query_effect : android::EffectQueryEffect, + create_effect : android::EffectCreate, + release_effect : android::EffectRelease, + get_descriptor : android::EffectGetDescriptor, +}; diff --git a/media/libeffects/testlibs/EffectReverb.c b/media/libeffects/testlibs/EffectReverb.c index 3eb8b2c..02762c9 100644 --- a/media/libeffects/testlibs/EffectReverb.c +++ b/media/libeffects/testlibs/EffectReverb.c @@ -23,59 +23,60 @@ #include "EffectReverb.h" #include "EffectsMath.h" -// effect_interface_t interface implementation for reverb effect +// effect_handle_t interface implementation for reverb effect const struct effect_interface_s gReverbInterface = { Reverb_Process, - Reverb_Command + Reverb_Command, + Reverb_GetDescriptor }; // Google auxiliary environmental reverb UUID: 1f0ae2e0-4ef7-11df-bc09-0002a5d5c51b static const effect_descriptor_t gAuxEnvReverbDescriptor = { {0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}}, {0x1f0ae2e0, 0x4ef7, 0x11df, 0xbc09, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, // flags other than EFFECT_FLAG_TYPE_AUXILIARY set for test purpose EFFECT_FLAG_TYPE_AUXILIARY | EFFECT_FLAG_DEVICE_IND | EFFECT_FLAG_AUDIO_MODE_IND, 0, // TODO 33, "Aux Environmental Reverb", - "Google Inc." + "The Android Open Source Project" }; // Google insert environmental reverb UUID: aa476040-6342-11df-91a4-0002a5d5c51b static const effect_descriptor_t gInsertEnvReverbDescriptor = { {0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}}, {0xaa476040, 0x6342, 0x11df, 0x91a4, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST, 0, // TODO 33, "Insert Environmental reverb", - "Google Inc." + "The Android Open Source Project" }; // Google auxiliary preset reverb UUID: 63909320-53a6-11df-bdbd-0002a5d5c51b static const effect_descriptor_t gAuxPresetReverbDescriptor = { {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, {0x63909320, 0x53a6, 0x11df, 0xbdbd, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, EFFECT_FLAG_TYPE_AUXILIARY, 0, // TODO 33, "Aux Preset Reverb", - "Google Inc." + "The Android Open Source Project" }; // Google insert preset reverb UUID: d93dc6a0-6342-11df-b128-0002a5d5c51b static const effect_descriptor_t gInsertPresetReverbDescriptor = { {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, {0xd93dc6a0, 0x6342, 0x11df, 0xb128, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST, 0, // TODO 33, "Insert Preset Reverb", - "Google Inc." + "The Android Open Source Project" }; // gDescriptors contains pointers to all defined effect descriptor in this library @@ -112,7 +113,7 @@ int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) { int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, - effect_interface_t *pInterface) { + effect_handle_t *pHandle) { int ret; int i; reverb_module_t *module; @@ -122,7 +123,7 @@ int EffectCreate(effect_uuid_t *uuid, LOGV("EffectLibCreateEffect start"); - if (pInterface == NULL || uuid == NULL) { + if (pHandle == NULL || uuid == NULL) { return -EINVAL; } @@ -157,7 +158,7 @@ int EffectCreate(effect_uuid_t *uuid, return ret; } - *pInterface = (effect_interface_t) module; + *pHandle = (effect_handle_t) module; module->context.mState = REVERB_STATE_INITIALIZED; @@ -166,11 +167,11 @@ int EffectCreate(effect_uuid_t *uuid, return 0; } -int EffectRelease(effect_interface_t interface) { - reverb_module_t *pRvbModule = (reverb_module_t *)interface; +int EffectRelease(effect_handle_t handle) { + reverb_module_t *pRvbModule = (reverb_module_t *)handle; - LOGV("EffectLibReleaseEffect %p", interface); - if (interface == NULL) { + LOGV("EffectLibReleaseEffect %p", handle); + if (handle == NULL) { return -EINVAL; } @@ -180,10 +181,31 @@ int EffectRelease(effect_interface_t interface) { return 0; } +int EffectGetDescriptor(effect_uuid_t *uuid, + effect_descriptor_t *pDescriptor) { + int i; + int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *); + + if (pDescriptor == NULL || uuid == NULL){ + LOGV("EffectGetDescriptor() called with NULL pointer"); + return -EINVAL; + } + + for (i = 0; i < length; i++) { + if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) { + memcpy(pDescriptor, gDescriptors[i], sizeof(effect_descriptor_t)); + LOGV("EffectGetDescriptor - UUID matched Reverb type %d, UUID = %x", + i, gDescriptors[i]->uuid.timeLow); + return 0; + } + } + + return -EINVAL; +} /* end EffectGetDescriptor */ /*--- Effect Control Interface Implementation ---*/ -static int Reverb_Process(effect_interface_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) { +static int Reverb_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) { reverb_object_t *pReverb; int16_t *pSrc, *pDst; reverb_module_t *pRvbModule = (reverb_module_t *)self; @@ -270,7 +292,7 @@ static int Reverb_Process(effect_interface_t self, audio_buffer_t *inBuffer, aud } -static int Reverb_Command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize, +static int Reverb_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) { reverb_module_t *pRvbModule = (reverb_module_t *) self; reverb_object_t *pReverb; @@ -383,6 +405,38 @@ static int Reverb_Command(effect_interface_t self, uint32_t cmdCode, uint32_t cm return 0; } +int Reverb_GetDescriptor(effect_handle_t self, + effect_descriptor_t *pDescriptor) +{ + reverb_module_t *pRvbModule = (reverb_module_t *) self; + reverb_object_t *pReverb; + const effect_descriptor_t *desc; + + if (pRvbModule == NULL || + pRvbModule->context.mState == REVERB_STATE_UNINITIALIZED) { + return -EINVAL; + } + + pReverb = (reverb_object_t*) &pRvbModule->context; + + if (pReverb->m_Aux) { + if (pReverb->m_Preset) { + desc = &gAuxPresetReverbDescriptor; + } else { + desc = &gAuxEnvReverbDescriptor; + } + } else { + if (pReverb->m_Preset) { + desc = &gInsertPresetReverbDescriptor; + } else { + desc = &gInsertEnvReverbDescriptor; + } + } + + memcpy(pDescriptor, desc, sizeof(effect_descriptor_t)); + + return 0; +} /* end Reverb_getDescriptor */ /*---------------------------------------------------------------------------- * Reverb internal functions @@ -418,19 +472,19 @@ int Reverb_Init(reverb_module_t *pRvbModule, int aux, int preset) { pRvbModule->config.inputCfg.samplingRate = 44100; if (aux) { - pRvbModule->config.inputCfg.channels = CHANNEL_MONO; + pRvbModule->config.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO; } else { - pRvbModule->config.inputCfg.channels = CHANNEL_STEREO; + pRvbModule->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; } - pRvbModule->config.inputCfg.format = SAMPLE_FORMAT_PCM_S15; + pRvbModule->config.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; pRvbModule->config.inputCfg.bufferProvider.getBuffer = NULL; pRvbModule->config.inputCfg.bufferProvider.releaseBuffer = NULL; pRvbModule->config.inputCfg.bufferProvider.cookie = NULL; pRvbModule->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; pRvbModule->config.inputCfg.mask = EFFECT_CONFIG_ALL; pRvbModule->config.outputCfg.samplingRate = 44100; - pRvbModule->config.outputCfg.channels = CHANNEL_STEREO; - pRvbModule->config.outputCfg.format = SAMPLE_FORMAT_PCM_S15; + pRvbModule->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; + pRvbModule->config.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; pRvbModule->config.outputCfg.bufferProvider.getBuffer = NULL; pRvbModule->config.outputCfg.bufferProvider.releaseBuffer = NULL; pRvbModule->config.outputCfg.bufferProvider.cookie = NULL; @@ -474,13 +528,13 @@ int Reverb_Configure(reverb_module_t *pRvbModule, effect_config_t *pConfig, if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate || pConfig->outputCfg.channels != OUTPUT_CHANNELS - || pConfig->inputCfg.format != SAMPLE_FORMAT_PCM_S15 - || pConfig->outputCfg.format != SAMPLE_FORMAT_PCM_S15) { + || pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT + || pConfig->outputCfg.format != AUDIO_FORMAT_PCM_16_BIT) { LOGV("Reverb_Configure invalid config"); return -EINVAL; } - if ((pReverb->m_Aux && (pConfig->inputCfg.channels != CHANNEL_MONO)) || - (!pReverb->m_Aux && (pConfig->inputCfg.channels != CHANNEL_STEREO))) { + if ((pReverb->m_Aux && (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_MONO)) || + (!pReverb->m_Aux && (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO))) { LOGV("Reverb_Configure invalid config"); return -EINVAL; } @@ -2133,3 +2187,15 @@ static int ReverbReadInPresets(reverb_object_t *pReverb) { return 0; } + +audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { + .tag = AUDIO_EFFECT_LIBRARY_TAG, + .version = EFFECT_LIBRARY_API_VERSION, + .name = "Test Equalizer Library", + .implementor = "The Android Open Source Project", + .query_num_effects = EffectQueryNumberEffects, + .query_effect = EffectQueryEffect, + .create_effect = EffectCreate, + .release_effect = EffectRelease, + .get_descriptor = EffectGetDescriptor, +}; diff --git a/media/libeffects/testlibs/EffectReverb.h b/media/libeffects/testlibs/EffectReverb.h index dbcd192..a239814 100644 --- a/media/libeffects/testlibs/EffectReverb.h +++ b/media/libeffects/testlibs/EffectReverb.h @@ -40,7 +40,7 @@ if the buffer size is a power of two. ) #define NUM_OUTPUT_CHANNELS 2 -#define OUTPUT_CHANNELS CHANNEL_STEREO +#define OUTPUT_CHANNELS AUDIO_CHANNEL_OUT_STEREO #define REVERB_BUFFER_SIZE_IN_SAMPLES_MAX 16384 @@ -306,19 +306,22 @@ int EffectQueryEffect(uint32_t index, int EffectCreate(effect_uuid_t *effectUID, int32_t sessionId, int32_t ioId, - effect_interface_t *pInterface); -int EffectRelease(effect_interface_t interface); + effect_handle_t *pHandle); +int EffectRelease(effect_handle_t handle); +int EffectGetDescriptor(effect_uuid_t *uuid, + effect_descriptor_t *pDescriptor); -static int Reverb_Process(effect_interface_t self, +static int Reverb_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer); -static int Reverb_Command(effect_interface_t self, +static int Reverb_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData); - +static int Reverb_GetDescriptor(effect_handle_t self, + effect_descriptor_t *pDescriptor); /*------------------------------------ * internal functions diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp index c957dba..80d1f69 100644 --- a/media/libeffects/visualizer/EffectVisualizer.cpp +++ b/media/libeffects/visualizer/EffectVisualizer.cpp @@ -23,21 +23,22 @@ #include #include -namespace android { -// effect_interface_t interface implementation for visualizer effect -extern "C" const struct effect_interface_s gVisualizerInterface; +extern "C" { + +// effect_handle_t interface implementation for visualizer effect +extern const struct effect_interface_s gVisualizerInterface; // Google Visualizer UUID: d069d9e0-8329-11df-9168-0002a5d5c51b const effect_descriptor_t gVisualizerDescriptor = { {0xe46b26a0, 0xdddd, 0x11db, 0x8afd, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // type {0xd069d9e0, 0x8329, 0x11df, 0x9168, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}}, // uuid - EFFECT_API_VERSION, + EFFECT_CONTROL_API_VERSION, (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST), 0, // TODO 1, "Visualizer", - "Google Inc.", + "The Android Open Source Project", }; enum visualizer_state_e { @@ -90,10 +91,10 @@ int Visualizer_configure(VisualizerContext *pContext, effect_config_t *pConfig) if (pConfig->inputCfg.samplingRate != pConfig->outputCfg.samplingRate) return -EINVAL; if (pConfig->inputCfg.channels != pConfig->outputCfg.channels) return -EINVAL; if (pConfig->inputCfg.format != pConfig->outputCfg.format) return -EINVAL; - if (pConfig->inputCfg.channels != CHANNEL_STEREO) return -EINVAL; + if (pConfig->inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) return -EINVAL; if (pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_WRITE && pConfig->outputCfg.accessMode != EFFECT_BUFFER_ACCESS_ACCUMULATE) return -EINVAL; - if (pConfig->inputCfg.format != SAMPLE_FORMAT_PCM_S15) return -EINVAL; + if (pConfig->inputCfg.format != AUDIO_FORMAT_PCM_16_BIT) return -EINVAL; memcpy(&pContext->mConfig, pConfig, sizeof(effect_config_t)); @@ -118,16 +119,16 @@ int Visualizer_configure(VisualizerContext *pContext, effect_config_t *pConfig) int Visualizer_init(VisualizerContext *pContext) { pContext->mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; - pContext->mConfig.inputCfg.channels = CHANNEL_STEREO; - pContext->mConfig.inputCfg.format = SAMPLE_FORMAT_PCM_S15; + pContext->mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; + pContext->mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; pContext->mConfig.inputCfg.samplingRate = 44100; pContext->mConfig.inputCfg.bufferProvider.getBuffer = NULL; pContext->mConfig.inputCfg.bufferProvider.releaseBuffer = NULL; pContext->mConfig.inputCfg.bufferProvider.cookie = NULL; pContext->mConfig.inputCfg.mask = EFFECT_CONFIG_ALL; pContext->mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE; - pContext->mConfig.outputCfg.channels = CHANNEL_STEREO; - pContext->mConfig.outputCfg.format = SAMPLE_FORMAT_PCM_S15; + pContext->mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; + pContext->mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; pContext->mConfig.outputCfg.samplingRate = 44100; pContext->mConfig.outputCfg.bufferProvider.getBuffer = NULL; pContext->mConfig.outputCfg.bufferProvider.releaseBuffer = NULL; @@ -145,12 +146,13 @@ int Visualizer_init(VisualizerContext *pContext) //--- Effect Library Interface Implementation // -extern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects) { +int VisualizerLib_QueryNumberEffects(uint32_t *pNumEffects) { *pNumEffects = 1; return 0; } -extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) { +int VisualizerLib_QueryEffect(uint32_t index, + effect_descriptor_t *pDescriptor) { if (pDescriptor == NULL) { return -EINVAL; } @@ -161,14 +163,14 @@ extern "C" int EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescripto return 0; } -extern "C" int EffectCreate(effect_uuid_t *uuid, - int32_t sessionId, - int32_t ioId, - effect_interface_t *pInterface) { +int VisualizerLib_Create(effect_uuid_t *uuid, + int32_t sessionId, + int32_t ioId, + effect_handle_t *pHandle) { int ret; int i; - if (pInterface == NULL || uuid == NULL) { + if (pHandle == NULL || uuid == NULL) { return -EINVAL; } @@ -183,25 +185,25 @@ extern "C" int EffectCreate(effect_uuid_t *uuid, ret = Visualizer_init(pContext); if (ret < 0) { - LOGW("EffectCreate() init failed"); + LOGW("VisualizerLib_Create() init failed"); delete pContext; return ret; } - *pInterface = (effect_interface_t)pContext; + *pHandle = (effect_handle_t)pContext; pContext->mState = VISUALIZER_STATE_INITIALIZED; - LOGV("EffectCreate %p", pContext); + LOGV("VisualizerLib_Create %p", pContext); return 0; } -extern "C" int EffectRelease(effect_interface_t interface) { - VisualizerContext * pContext = (VisualizerContext *)interface; +int VisualizerLib_Release(effect_handle_t handle) { + VisualizerContext * pContext = (VisualizerContext *)handle; - LOGV("EffectRelease %p", interface); + LOGV("VisualizerLib_Release %p", handle); if (pContext == NULL) { return -EINVAL; } @@ -211,6 +213,22 @@ extern "C" int EffectRelease(effect_interface_t interface) { return 0; } +int VisualizerLib_GetDescriptor(effect_uuid_t *uuid, + effect_descriptor_t *pDescriptor) { + + if (pDescriptor == NULL || uuid == NULL){ + LOGV("VisualizerLib_GetDescriptor() called with NULL pointer"); + return -EINVAL; + } + + if (memcmp(uuid, &gVisualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) { + memcpy(pDescriptor, &gVisualizerDescriptor, sizeof(effect_descriptor_t)); + return 0; + } + + return -EINVAL; +} /* end VisualizerLib_GetDescriptor */ + // //--- Effect Control Interface Implementation // @@ -222,10 +240,10 @@ static inline int16_t clamp16(int32_t sample) return sample; } -extern "C" int Visualizer_process( - effect_interface_t self,audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) +int Visualizer_process( + effect_handle_t self,audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) { - android::VisualizerContext * pContext = (android::VisualizerContext *)self; + VisualizerContext * pContext = (VisualizerContext *)self; if (pContext == NULL) { return -EINVAL; @@ -244,7 +262,7 @@ extern "C" int Visualizer_process( // this gives more interesting captures for display. int32_t shift = 32; int len = inBuffer->frameCount * 2; - for (size_t i = 0; i < len; i++) { + for (int i = 0; i < len; i++) { int32_t smp = inBuffer->s16[i]; if (smp < 0) smp = -smp - 1; // take care to keep the max negative in range int32_t clz = __builtin_clz(smp); @@ -293,10 +311,10 @@ extern "C" int Visualizer_process( return 0; } // end Visualizer_process -extern "C" int Visualizer_command(effect_interface_t self, uint32_t cmdCode, uint32_t cmdSize, +int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void *pCmdData, uint32_t *replySize, void *pReplyData) { - android::VisualizerContext * pContext = (android::VisualizerContext *)self; + VisualizerContext * pContext = (VisualizerContext *)self; int retsize; if (pContext == NULL || pContext->mState == VISUALIZER_STATE_UNINITIALIZED) { @@ -412,11 +430,40 @@ extern "C" int Visualizer_command(effect_interface_t self, uint32_t cmdCode, uin return 0; } -// effect_interface_t interface implementation for visualizer effect +/* Effect Control Interface Implementation: get_descriptor */ +int Visualizer_getDescriptor(effect_handle_t self, + effect_descriptor_t *pDescriptor) +{ + VisualizerContext * pContext = (VisualizerContext *) self; + + if (pContext == NULL || pDescriptor == NULL) { + LOGV("Visualizer_getDescriptor() invalid param"); + return -EINVAL; + } + + memcpy(pDescriptor, &gVisualizerDescriptor, sizeof(effect_descriptor_t)); + + return 0; +} /* end Visualizer_getDescriptor */ + +// effect_handle_t interface implementation for visualizer effect const struct effect_interface_s gVisualizerInterface = { Visualizer_process, - Visualizer_command + Visualizer_command, + Visualizer_getDescriptor }; -} // namespace +audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { + tag : AUDIO_EFFECT_LIBRARY_TAG, + version : EFFECT_LIBRARY_API_VERSION, + name : "Visualizer Library", + implementor : "The Android Open Source Project", + query_num_effects : VisualizerLib_QueryNumberEffects, + query_effect : VisualizerLib_QueryEffect, + create_effect : VisualizerLib_Create, + release_effect : VisualizerLib_Release, + get_descriptor : VisualizerLib_GetDescriptor, +}; + +}; // extern "C" diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 8e86eda..67c6d96 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -61,7 +61,6 @@ // ---------------------------------------------------------------------------- -extern const char * const gEffectLibPath; namespace android { @@ -4622,10 +4621,6 @@ status_t AudioFlinger::loadEffectLibrary(const char *libPath, int *handle) if (!settingsAllowed()) { return PERMISSION_DENIED; } - // only allow libraries loaded from /system/lib/soundfx for now - if (strncmp(gEffectLibPath, libPath, strlen(gEffectLibPath)) != 0) { - return PERMISSION_DENIED; - } Mutex::Autolock _l(mLock); return EffectLoadLibrary(libPath, handle); @@ -4677,7 +4672,6 @@ sp AudioFlinger::createEffect(pid_t pid, { status_t lStatus = NO_ERROR; sp handle; - effect_interface_t itfe; effect_descriptor_t desc; sp client; wp wclient; @@ -5515,19 +5509,19 @@ status_t AudioFlinger::EffectModule::configure() // TODO: handle configuration of effects replacing track process if (thread->channelCount() == 1) { - channels = CHANNEL_MONO; + channels = AUDIO_CHANNEL_OUT_MONO; } else { - channels = CHANNEL_STEREO; + channels = AUDIO_CHANNEL_OUT_STEREO; } if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { - mConfig.inputCfg.channels = CHANNEL_MONO; + mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO; } else { mConfig.inputCfg.channels = channels; } mConfig.outputCfg.channels = channels; - mConfig.inputCfg.format = SAMPLE_FORMAT_PCM_S15; - mConfig.outputCfg.format = SAMPLE_FORMAT_PCM_S15; + mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; + mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; mConfig.inputCfg.samplingRate = thread->sampleRate(); mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate; mConfig.inputCfg.bufferProvider.cookie = NULL; @@ -5772,11 +5766,6 @@ status_t AudioFlinger::EffectModule::setDevice(uint32_t device) Mutex::Autolock _l(mLock); status_t status = NO_ERROR; if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) { - // convert device bit field from AudioSystem to EffectApi format. - device = deviceAudioSystemToEffectApi(device); - if (device == 0) { - return BAD_VALUE; - } status_t cmdStatus; uint32_t size = sizeof(status_t); status = (*mEffectInterface)->command(mEffectInterface, @@ -5797,17 +5786,12 @@ status_t AudioFlinger::EffectModule::setMode(uint32_t mode) Mutex::Autolock _l(mLock); status_t status = NO_ERROR; if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) { - // convert audio mode from AudioSystem to EffectApi format. - int effectMode = modeAudioSystemToEffectApi(mode); - if (effectMode < 0) { - return BAD_VALUE; - } status_t cmdStatus; uint32_t size = sizeof(status_t); status = (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_SET_AUDIO_MODE, sizeof(int), - &effectMode, + &mode, &size, &cmdStatus); if (status == NO_ERROR) { @@ -5817,53 +5801,6 @@ status_t AudioFlinger::EffectModule::setMode(uint32_t mode) return status; } -// update this table when AudioSystem::audio_devices or audio_device_e (in EffectApi.h) are modified -const uint32_t AudioFlinger::EffectModule::sDeviceConvTable[] = { - DEVICE_EARPIECE, // AUDIO_DEVICE_OUT_EARPIECE - DEVICE_SPEAKER, // AUDIO_DEVICE_OUT_SPEAKER - DEVICE_WIRED_HEADSET, // case AUDIO_DEVICE_OUT_WIRED_HEADSET - DEVICE_WIRED_HEADPHONE, // AUDIO_DEVICE_OUT_WIRED_HEADPHONE - DEVICE_BLUETOOTH_SCO, // AUDIO_DEVICE_OUT_BLUETOOTH_SCO - DEVICE_BLUETOOTH_SCO_HEADSET, // AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET - DEVICE_BLUETOOTH_SCO_CARKIT, // AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT - DEVICE_BLUETOOTH_A2DP, // AUDIO_DEVICE_OUT_BLUETOOTH_A2DP - DEVICE_BLUETOOTH_A2DP_HEADPHONES, // AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES - DEVICE_BLUETOOTH_A2DP_SPEAKER, // AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER - DEVICE_AUX_DIGITAL // AUDIO_DEVICE_OUT_AUX_DIGITAL -}; - -uint32_t AudioFlinger::EffectModule::deviceAudioSystemToEffectApi(uint32_t device) -{ - uint32_t deviceOut = 0; - while (device) { - const uint32_t i = 31 - __builtin_clz(device); - device &= ~(1 << i); - if (i >= sizeof(sDeviceConvTable)/sizeof(uint32_t)) { - LOGE("device conversion error for AudioSystem device 0x%08x", device); - return 0; - } - deviceOut |= (uint32_t)sDeviceConvTable[i]; - } - return deviceOut; -} - -// update this table when AudioSystem::audio_mode or audio_mode_e (in EffectApi.h) are modified -const uint32_t AudioFlinger::EffectModule::sModeConvTable[] = { - AUDIO_EFFECT_MODE_NORMAL, // AUDIO_MODE_NORMAL - AUDIO_EFFECT_MODE_RINGTONE, // AUDIO_MODE_RINGTONE - AUDIO_EFFECT_MODE_IN_CALL, // AUDIO_MODE_IN_CALL - AUDIO_EFFECT_MODE_IN_CALL // AUDIO_MODE_IN_COMMUNICATION, same conversion as for AUDIO_MODE_IN_CALL -}; - -int AudioFlinger::EffectModule::modeAudioSystemToEffectApi(uint32_t mode) -{ - int modeOut = -1; - if (mode < sizeof(sModeConvTable) / sizeof(uint32_t)) { - modeOut = (int)sModeConvTable[mode]; - } - return modeOut; -} - status_t AudioFlinger::EffectModule::dump(int fd, const Vector& args) { const size_t SIZE = 256; @@ -5895,7 +5832,7 @@ status_t AudioFlinger::EffectModule::dump(int fd, const Vector& args) mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1],mDescriptor.type.node[2], mDescriptor.type.node[3],mDescriptor.type.node[4],mDescriptor.type.node[5]); result.append(buffer); - snprintf(buffer, SIZE, "\t\t- apiVersion: %04X\n\t\t- flags: %08X\n", + snprintf(buffer, SIZE, "\t\t- apiVersion: %08X\n\t\t- flags: %08X\n", mDescriptor.apiVersion, mDescriptor.flags); result.append(buffer); diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 39314ad..f3e1984 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -1002,14 +1002,6 @@ private: status_t start_l(); status_t stop_l(); - // update this table when AudioSystem::audio_devices or audio_device_e (in EffectApi.h) are modified - static const uint32_t sDeviceConvTable[]; - static uint32_t deviceAudioSystemToEffectApi(uint32_t device); - - // update this table when AudioSystem::audio_mode or audio_mode_e (in EffectApi.h) are modified - static const uint32_t sModeConvTable[]; - static int modeAudioSystemToEffectApi(uint32_t mode); - Mutex mLock; // mutex for process, commands and handles list protection wp mThread; // parent thread wp mChain; // parent effect chain @@ -1017,7 +1009,7 @@ private: int mSessionId; // audio session ID effect_descriptor_t mDescriptor;// effect descriptor received from effect engine effect_config_t mConfig; // input and output audio configuration - effect_interface_t mEffectInterface; // Effect module C API + effect_handle_t mEffectInterface; // Effect module C API status_t mStatus; // initialization status uint32_t mState; // current activation state (effect_state) Vector< wp > mHandles; // list of client handles -- cgit v1.1