1135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/* 2135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Copyright (C) 2010 The Android Open Source Project 3135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * 4135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License"); 5135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * you may not use this file except in compliance with the License. 6135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * You may obtain a copy of the License at 7135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * 8135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * http://www.apache.org/licenses/LICENSE-2.0 9135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * 10135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * Unless required by applicable law or agreed to in writing, software 11135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS, 12135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * See the License for the specific language governing permissions and 14135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent * limitations under the License. 15135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent */ 16135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 17135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#define LOG_TAG "EffectsFactory" 18135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//#define LOG_NDEBUG 0 19135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 20135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include "EffectsFactory.h" 2117217ab46e12fbdaad9e1d7460c48937f76fa0e2Eric Laurent#include <string.h> 2217217ab46e12fbdaad9e1d7460c48937f76fa0e2Eric Laurent#include <stdlib.h> 23135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <dlfcn.h> 24135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 25e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#include <cutils/misc.h> 26e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#include <cutils/config_utils.h> 2720569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi#include <cutils/properties.h> 287c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent#include <audio_effects/audio_effects_conf.h> 29135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 30135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects 31135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries 32d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic list_elem_t *gSkippedEffects; // list of effects skipped because of duplicate uuid 332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// list of effect_descriptor and list of sub effects : all currently loaded 342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// It does not contain effects without sub effects. 352eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanastatic list_sub_elem_t *gSubEffectList; 36135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic pthread_mutex_t gLibLock = PTHREAD_MUTEX_INITIALIZER; // controls access to gLibraryList 37ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gNumEffects; // total number number of effects 38135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurLib; // current library in enumeration process 39135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurEffect; // current effect in enumeration process 40ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gCurEffectIdx; // current effect index in enumeration process 41e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *gCachedLibrary; // last library accessed by getLibrary() 42135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 43135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int gInitDone; // true is global initialization has been preformed 44ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects 45ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent // was not modified since last call to EffectQueryNumberEffects() 46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 47e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 48135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 49135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Local functions prototypes 50135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 51135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 52135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int init(); 53e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffectConfigFile(const char *path); 54e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibraries(cnode *root); 55e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibrary(cnode *root, const char *name); 56e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffects(cnode *root); 57e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffect(cnode *node); 582eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// To get and add the effect pointed by the passed node to the gSubEffectList 592eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanastatic int addSubEffect(cnode *root); 60e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *getLibrary(const char *path); 61ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic void resetEffectEnumeration(); 62ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t updateNumEffects(); 635e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenstatic int findEffect(const effect_uuid_t *type, 645e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kasten const effect_uuid_t *uuid, 65e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent lib_entry_t **lib, 66e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_descriptor_t **desc); 672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// To search a subeffect in the gSubEffectList 68d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic int findSubEffect(const effect_uuid_t *uuid, 692eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana lib_entry_t **lib, 702eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t **desc); 71d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent); 72e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int stringToUuid(const char *str, effect_uuid_t *uuid); 73e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen); 74135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 75135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 76135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Effect Control Interface functions 77135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 78135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 79e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) 80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 84135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 85135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_entry_t *fx = (effect_entry_t *)self; 86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 87135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (fx->lib == NULL) { 88135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 89135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EPIPE; 90135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&fx->lib->lock); 92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = (*fx->subItfe)->process(fx->subItfe, inBuffer, outBuffer); 95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&fx->lib->lock); 96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 99e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Command(effect_handle_t self, 10025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent uint32_t cmdCode, 10125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent uint32_t cmdSize, 10225f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent void *pCmdData, 10325f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent uint32_t *replySize, 10425f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent void *pReplyData) 105135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 106135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 107135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 108135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 109135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_entry_t *fx = (effect_entry_t *)self; 111135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 112135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (fx->lib == NULL) { 113135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 114135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EPIPE; 115135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 116135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&fx->lib->lock); 117135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 118135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 119135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = (*fx->subItfe)->command(fx->subItfe, cmdCode, cmdSize, pCmdData, replySize, pReplyData); 120135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&fx->lib->lock); 121135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 122135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 123135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 124e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_GetDescriptor(effect_handle_t self, 125e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_descriptor_t *desc) 126e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 127e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent int ret = init(); 128e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (ret < 0) { 129e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return ret; 130e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 131e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_entry_t *fx = (effect_entry_t *)self; 132e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_lock(&gLibLock); 133e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (fx->lib == NULL) { 134e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_unlock(&gLibLock); 135e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EPIPE; 136e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 137e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_lock(&fx->lib->lock); 138e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_unlock(&gLibLock); 139e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 140e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent ret = (*fx->subItfe)->get_descriptor(fx->subItfe, desc); 141e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_unlock(&fx->lib->lock); 142e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return ret; 143e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 144e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 145ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentint Effect_ProcessReverse(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) 146ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent{ 147ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent int ret = init(); 148ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent if (ret < 0) { 149ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent return ret; 150ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } 151ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent effect_entry_t *fx = (effect_entry_t *)self; 152ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent pthread_mutex_lock(&gLibLock); 153ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent if (fx->lib == NULL) { 154ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent pthread_mutex_unlock(&gLibLock); 155ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent return -EPIPE; 156ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } 157ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent pthread_mutex_lock(&fx->lib->lock); 158ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent pthread_mutex_unlock(&gLibLock); 159ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent 160ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent if ((*fx->subItfe)->process_reverse != NULL) { 161ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent ret = (*fx->subItfe)->process_reverse(fx->subItfe, inBuffer, outBuffer); 162ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } else { 163ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent ret = -ENOSYS; 164ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } 165ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent pthread_mutex_unlock(&fx->lib->lock); 166ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent return ret; 167ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent} 168ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent 169ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent 170135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst struct effect_interface_s gInterface = { 171135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent Effect_Process, 172e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent Effect_Command, 173ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent Effect_GetDescriptor, 174ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent NULL 175ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent}; 176ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent 177ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentconst struct effect_interface_s gInterfaceWithReverse = { 178ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent Effect_Process, 179ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent Effect_Command, 180ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent Effect_GetDescriptor, 181ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent Effect_ProcessReverse 182135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}; 183135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 184135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 185135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Effect Factory Interface functions 186135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 187135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 188be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentint EffectQueryNumberEffects(uint32_t *pNumEffects) 189135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 190135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 191135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 192135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 193135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 194135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (pNumEffects == NULL) { 195135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EINVAL; 196135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 197135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 198135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 199ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent *pNumEffects = gNumEffects; 200ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCanQueryEffect = 1; 201135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 2023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectQueryNumberEffects(): %d", *pNumEffects); 203135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 204135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 205135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 206ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentint EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) 207135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 208135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 209135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 210135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 211135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 212ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (pDescriptor == NULL || 213ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent index >= gNumEffects) { 214135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EINVAL; 215135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 216ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (gCanQueryEffect == 0) { 217ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent return -ENOSYS; 218ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent } 219135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 220135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 221135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = -ENOENT; 222ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (index < gCurEffectIdx) { 223ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent resetEffectEnumeration(); 224ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent } 225135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (gCurLib) { 226135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (gCurEffect) { 227ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (index == gCurEffectIdx) { 228a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten *pDescriptor = *(effect_descriptor_t *)gCurEffect->object; 229ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent ret = 0; 230ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent break; 231ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent } else { 232ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurEffect = gCurEffect->next; 233ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurEffectIdx++; 234ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent } 235135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } else { 236135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gCurLib = gCurLib->next; 237135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gCurEffect = ((lib_entry_t *)gCurLib->object)->effects; 238135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 239135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 240ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent 241ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#if (LOG_NDEBUG == 0) 242d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char str[512]; 243d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dumpEffectDescriptor(pDescriptor, str, sizeof(str), 0 /* indent */); 2443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectQueryEffect() desc:%s", str); 245ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#endif 246135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 247135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 248135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 249135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 2505e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) 251135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 252135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent lib_entry_t *l = NULL; 253135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_descriptor_t *d = NULL; 254135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 255135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 256135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 257135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 258135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 259135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (pDescriptor == NULL || uuid == NULL) { 260135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EINVAL; 261135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 262135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 263e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent ret = findEffect(NULL, uuid, &l, &d); 264135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret == 0) { 265a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten *pDescriptor = *d; 266135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 267135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 268135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 269135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 270135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 2715e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle) 272135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 273135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *e = gLibraryList; 274135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent lib_entry_t *l = NULL; 275135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_descriptor_t *d = NULL; 276e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_handle_t itfe; 277135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_entry_t *fx; 278135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int found = 0; 279135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret; 280135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 281e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (uuid == NULL || pHandle == NULL) { 282135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EINVAL; 283135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 284135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 2853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectCreate() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n", 286135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, 287135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2], 288135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uuid->node[3],uuid->node[4],uuid->node[5]); 289135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 290135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = init(); 291135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 292135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 2935ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("EffectCreate() init error: %d", ret); 294135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 295135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 296135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 297135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 298135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 299e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent ret = findEffect(NULL, uuid, &l, &d); 300135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0){ 3012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // Sub effects are not associated with the library->effects, 3022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // so, findEffect will fail. Search for the effect in gSubEffectList. 3032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ret = findSubEffect(uuid, &l, &d); 3042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (ret < 0 ) { 3052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana goto exit; 3062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 307135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 308135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 309135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // create effect in library 310342484f01824ab45af953c7c9193b1e5ad6326deEric Laurent ret = l->desc->create_effect(uuid, sessionId, ioId, &itfe); 311ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (ret != 0) { 3125ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret); 313135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent goto exit; 314135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 315135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 316135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // add entry to effect list 317135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent fx = (effect_entry_t *)malloc(sizeof(effect_entry_t)); 318135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent fx->subItfe = itfe; 319ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent if ((*itfe)->process_reverse != NULL) { 320ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent fx->itfe = (struct effect_interface_s *)&gInterfaceWithReverse; 3213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectCreate() gInterfaceWithReverse"); 322ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } else { 323ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent fx->itfe = (struct effect_interface_s *)&gInterface; 3243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectCreate() gInterface"); 325ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } 326135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent fx->lib = l; 327135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 328135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e = (list_elem_t *)malloc(sizeof(list_elem_t)); 329135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e->object = fx; 330135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e->next = gEffectList; 331135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gEffectList = e; 332135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 333e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent *pHandle = (effect_handle_t)fx; 334135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 3353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pHandle, itfe, l->name); 336135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 337135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit: 338135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 339135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 340135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 341135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 342e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint EffectRelease(effect_handle_t handle) 343135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 344135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_entry_t *fx; 345135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *e1; 346135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *e2; 347135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 348135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 349135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 350135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 351135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 352135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 353135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // remove effect from effect list 354135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 355135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e1 = gEffectList; 356135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e2 = NULL; 357135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (e1) { 358e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (e1->object == handle) { 359135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (e2) { 360135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e2->next = e1->next; 361135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } else { 362135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gEffectList = e1->next; 363135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 364135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent fx = (effect_entry_t *)e1->object; 365135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent free(e1); 366135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent break; 367135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 368135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e2 = e1; 369135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e1 = e1->next; 370135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 371135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (e1 == NULL) { 372135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = -ENOENT; 373135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent goto exit; 374135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 375135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 376135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // release effect in library 377135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (fx->lib == NULL) { 3785ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("EffectRelease() fx %p library already unloaded", handle); 379135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } else { 380135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&fx->lib->lock); 381e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent fx->lib->desc->release_effect(fx->subItfe); 382135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&fx->lib->lock); 383135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 384135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent free(fx); 385135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 386135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit: 387f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana pthread_mutex_unlock(&gLibLock); 388135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 389135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 390135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 3915e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectIsNullUuid(const effect_uuid_t *uuid) 392135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 393135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (memcmp(uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t))) { 394135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return 0; 395135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 396135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return 1; 397135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 398135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 3992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Function to get the sub effect descriptors of the effect whose uuid 4002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// is pointed by the first argument. It searches the gSubEffectList for the 4012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// matching uuid and then copies the corresponding sub effect descriptors 4022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// to the inout param 403f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmanaint EffectGetSubEffects(const effect_uuid_t *uuid, sub_effect_entry_t **pSube, 404f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana size_t size) 4052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{ 4062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("EffectGetSubEffects() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X" 4072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana "%02X\n",uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, 4082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2], 4092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana uuid->node[3],uuid->node[4],uuid->node[5]); 4102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana 4112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // Check if the size of the desc buffer is large enough for 2 subeffects 412f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana if ((uuid == NULL) || (pSube == NULL) || (size < 2)) { 4132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("NULL pointer or insufficient memory. Cannot query subeffects"); 4142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 4152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 4162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana int ret = init(); 4172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (ret < 0) 4182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return ret; 4192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_sub_elem_t *e = gSubEffectList; 4202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect_entry_t *subeffect; 4212eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t *d; 4222eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana int count = 0; 4232eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana while (e != NULL) { 4242eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana d = (effect_descriptor_t*)e->object; 4252eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (memcmp(uuid, &d->uuid, sizeof(effect_uuid_t)) == 0) { 4262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("EffectGetSubEffects: effect found in the list"); 4272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_elem_t *subefx = e->sub_elem; 4282eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana while (subefx != NULL) { 4292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana subeffect = (sub_effect_entry_t*)subefx->object; 430f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana pSube[count++] = subeffect; 4312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana subefx = subefx->next; 4322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 433f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana ALOGV("EffectGetSubEffects end - copied the sub effect structures"); 4342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return count; 4352eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 4362eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana e = e->next; 4372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 4382eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -ENOENT; 4392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana} 440135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 441135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Local functions 442135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 443135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 444135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint init() { 445135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int hdl; 446135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 447135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (gInitDone) { 448135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return 0; 449135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 450135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 45120569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi // ignore effects or not? 45220569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi const bool ignoreFxConfFiles = property_get_bool(PROPERTY_IGNORE_EFFECTS, false); 45320569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi 454135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_init(&gLibLock, NULL); 455135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 45620569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi if (ignoreFxConfFiles) { 45720569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi ALOGI("Audio effects in configuration files will be ignored"); 45820569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi } else { 45920569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) { 46020569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE); 46120569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) { 46220569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE); 46320569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi } 464135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 465e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 466ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent updateNumEffects(); 467135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gInitDone = 1; 4683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("init() done"); 469135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return 0; 470135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 471135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 472e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffectConfigFile(const char *path) 473135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 474e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent cnode *root; 475e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent char *data; 476135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 477e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent data = load_file(path, NULL); 478e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (data == NULL) { 479e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -ENODEV; 480135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 481e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent root = config_node("", ""); 482e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent config_load(root, data); 483e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent loadLibraries(root); 484e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent loadEffects(root); 485e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent config_free(root); 486e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent free(root); 487e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent free(data); 488135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 489e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 490e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 491135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 492e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibraries(cnode *root) 493e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 494e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent cnode *node; 495135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 496e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = config_find(root, LIBRARIES_TAG); 497e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (node == NULL) { 498e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -ENOENT; 499135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 500e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = node->first_child; 501e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent while (node) { 502e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent loadLibrary(node, node->name); 503e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = node->next; 504135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 505e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 506e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 507e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 508e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibrary(cnode *root, const char *name) 509e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 510e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent cnode *node; 511e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent void *hdl; 512e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent audio_effect_library_t *desc; 513e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent list_elem_t *e; 514e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent lib_entry_t *l; 515a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent char path[PATH_MAX]; 516a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent char *str; 517a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent size_t len; 518e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 519e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = config_find(root, PATH_TAG); 520e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (node == NULL) { 521e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 522135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 523a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent // audio_effects.conf always specifies 32 bit lib path: convert to 64 bit path if needed 524a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent strlcpy(path, node->value, PATH_MAX); 525a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent#ifdef __LP64__ 526a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent str = strstr(path, "/lib/"); 527a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent if (str == NULL) 528a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent return -EINVAL; 529a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent len = str - path; 530a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent path[len] = '\0'; 531a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent strlcat(path, "/lib64/", PATH_MAX); 532a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent strlcat(path, node->value + len + strlen("/lib/"), PATH_MAX); 533a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent#endif 534a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent if (strlen(path) >= PATH_MAX - 1) 535a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent return -EINVAL; 536e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 537a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent hdl = dlopen(path, RTLD_NOW); 538e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (hdl == NULL) { 539a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent ALOGW("loadLibrary() failed to open %s", path); 540135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent goto error; 541135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 542135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 543e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR); 544e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (desc == NULL) { 5455ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR); 546135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent goto error; 547135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 548135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 549e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) { 5505ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("getLibrary() bad tag %08x in lib info struct", desc->tag); 551e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent goto error; 552135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 553ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent 554e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (EFFECT_API_VERSION_MAJOR(desc->version) != 555e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) { 5565ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("loadLibrary() bad lib version %08x", desc->version); 557e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent goto error; 558e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 559ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent 560135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // add entry for library in gLibraryList 561135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent l = malloc(sizeof(lib_entry_t)); 562e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent l->name = strndup(name, PATH_MAX); 563a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent l->path = strndup(path, PATH_MAX); 564135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent l->handle = hdl; 565e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent l->desc = desc; 566e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent l->effects = NULL; 567135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_init(&l->lock, NULL); 568135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 569135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e = malloc(sizeof(list_elem_t)); 570135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e->object = l; 571e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_lock(&gLibLock); 572e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent e->next = gLibraryList; 573135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gLibraryList = e; 574135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 575a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent ALOGV("getLibrary() linked library %p for path %s", l, path); 576135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 577135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return 0; 578135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 579135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurenterror: 580e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (hdl != NULL) { 581e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent dlclose(hdl); 582e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 583e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 584135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 585135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 5862eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// This will find the library and UUID tags of the sub effect pointed by the 5872eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// node, gets the effect descriptor and lib_entry_t and adds the subeffect - 5882eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// sub_entry_t to the gSubEffectList 5892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint addSubEffect(cnode *root) 5902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{ 5912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("addSubEffect"); 5922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana cnode *node; 5932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_uuid_t uuid; 5942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t *d; 5952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana lib_entry_t *l; 5962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_elem_t *e; 5972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana node = config_find(root, LIBRARY_TAG); 5982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (node == NULL) { 5992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana l = getLibrary(node->value); 6022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (l == NULL) { 6032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("addSubEffect() could not get library %s", node->value); 6042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana node = config_find(root, UUID_TAG); 6072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (node == NULL) { 6082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (stringToUuid(node->value, &uuid) != 0) { 6112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("addSubEffect() invalid uuid %s", node->value); 6122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana d = malloc(sizeof(effect_descriptor_t)); 6152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (l->desc->get_descriptor(&uuid, d) != 0) { 6162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana char s[40]; 6172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana uuidToString(&uuid, s, 40); 6182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("Error querying effect %s on lib %s", s, l->name); 6192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana free(d); 6202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6212eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6222eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana#if (LOG_NDEBUG==0) 623d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char s[512]; 624d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */); 6252eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("addSubEffect() read descriptor %p:%s",d, s); 6262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana#endif 6272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (EFFECT_API_VERSION_MAJOR(d->apiVersion) != 6282eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) { 6292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name); 6302eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana free(d); 6312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t)); 6342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect->object = d; 6352eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // lib_entry_t is stored since the sub effects are not linked to the library 6362eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect->lib = l; 6372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana e = malloc(sizeof(list_elem_t)); 6382eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana e->object = sub_effect; 6392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana e->next = gSubEffectList->sub_elem; 6402eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana gSubEffectList->sub_elem = e; 6412eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("addSubEffect end"); 6422eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return 0; 6432eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana} 6442eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana 645e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffects(cnode *root) 646135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 647e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent cnode *node; 648e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 649e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = config_find(root, EFFECTS_TAG); 650e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (node == NULL) { 651e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -ENOENT; 652e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 653e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = node->first_child; 654e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent while (node) { 655e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent loadEffect(node); 656e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = node->next; 657e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 658e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 659e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 660e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 661e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffect(cnode *root) 662e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 663e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent cnode *node; 664e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_uuid_t uuid; 665135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent lib_entry_t *l; 666e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_descriptor_t *d; 667e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent list_elem_t *e; 668135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 669e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = config_find(root, LIBRARY_TAG); 670e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (node == NULL) { 671e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 672135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 673e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 674e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent l = getLibrary(node->value); 675e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (l == NULL) { 6765ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("loadEffect() could not get library %s", node->value); 677e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 678135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 679135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 680e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = config_find(root, UUID_TAG); 681e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (node == NULL) { 682e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 683e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 684e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (stringToUuid(node->value, &uuid) != 0) { 6855ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("loadEffect() invalid uuid %s", node->value); 686e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 687e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 688d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen lib_entry_t *tmp; 689d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen bool skip = false; 690d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen if (findEffect(NULL, &uuid, &tmp, NULL) == 0) { 691d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen ALOGW("skipping duplicate uuid %s %s", node->value, 692d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen node->next ? "and its sub-effects" : ""); 693d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen skip = true; 694d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 695e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 696e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent d = malloc(sizeof(effect_descriptor_t)); 697e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (l->desc->get_descriptor(&uuid, d) != 0) { 698e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent char s[40]; 699e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuidToString(&uuid, s, 40); 7005ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Error querying effect %s on lib %s", s, l->name); 701e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent free(d); 702e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 703e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 704e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#if (LOG_NDEBUG==0) 705d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char s[512]; 706d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */); 7073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("loadEffect() read descriptor %p:%s",d, s); 708e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#endif 709e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (EFFECT_API_VERSION_MAJOR(d->apiVersion) != 710e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) { 7115ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name); 712e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent free(d); 713e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 714135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 715e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent e = malloc(sizeof(list_elem_t)); 716e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent e->object = d; 717d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen if (skip) { 718d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen e->next = gSkippedEffects; 719d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen gSkippedEffects = e; 720d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen return -EINVAL; 721d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } else { 722d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen e->next = l->effects; 723d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen l->effects = e; 724d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 725e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 7262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // After the UUID node in the config_tree, if node->next is valid, 7272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // that would be sub effect node. 7282eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // Find the sub effects and add them to the gSubEffectList 7292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana node = node->next; 7302eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana int count = 2; 7312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana bool hwSubefx = false, swSubefx = false; 7322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_sub_elem_t *sube = NULL; 7332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (node != NULL) { 7342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("Adding the effect to gEffectSubList as there are sub effects"); 7352eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sube = malloc(sizeof(list_sub_elem_t)); 7362eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sube->object = d; 7372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sube->sub_elem = NULL; 7382eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sube->next = gSubEffectList; 7392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana gSubEffectList = sube; 7402eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 7412eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana while (node != NULL && count) { 7422eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (addSubEffect(node)) { 7432eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("loadEffect() could not add subEffect %s", node->value); 7442eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // Change the gSubEffectList to point to older list; 7452eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana gSubEffectList = sube->next; 7462eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana free(sube->sub_elem);// Free an already added sub effect 7472eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sube->sub_elem = NULL; 7482eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana free(sube); 7492eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -ENOENT; 7502eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 7512eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object; 7522eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object); 7532eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // Since we return a dummy descriptor for the proxy during 7542eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // get_descriptor call,we replace it with the correspoding 7552eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // sw effect descriptor, but with Proxy UUID 7562eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // check for Sw desc 7572eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) == 7582eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana EFFECT_FLAG_HW_ACC_TUNNEL)) { 7592eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana swSubefx = true; 7602eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana *d = *subEffectDesc; 7612eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana d->uuid = uuid; 7622eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("loadEffect() Changed the Proxy desc"); 7632eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } else 7642eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana hwSubefx = true; 7652eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana count--; 7662eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana node = node->next; 7672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 7682eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc 7692eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (hwSubefx && swSubefx) { 7702eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED; 7712eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 772e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 773e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 774135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 7752eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Searches the sub effect matching to the specified uuid 7762eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// in the gSubEffectList. It gets the lib_entry_t for 7772eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// the matched sub_effect . Used in EffectCreate of sub effects 7782eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint findSubEffect(const effect_uuid_t *uuid, 7792eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana lib_entry_t **lib, 7802eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t **desc) 7812eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{ 7822eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_sub_elem_t *e = gSubEffectList; 7832eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_elem_t *subefx; 7842eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect_entry_t *effect; 7852eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana lib_entry_t *l = NULL; 7862eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t *d = NULL; 7872eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana int found = 0; 7882eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana int ret = 0; 7892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana 7902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (uuid == NULL) 7912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 7922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana 7932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana while (e != NULL && !found) { 7942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana subefx = (list_elem_t*)(e->sub_elem); 7952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana while (subefx != NULL) { 7962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect = (sub_effect_entry_t*)subefx->object; 7972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana l = (lib_entry_t *)effect->lib; 7982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana d = (effect_descriptor_t *)effect->object; 7992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) { 8002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("uuid matched"); 8012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana found = 1; 8022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana break; 8032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana subefx = subefx->next; 8052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana e = e->next; 8072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (!found) { 8092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("findSubEffect() effect not found"); 8102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ret = -ENOENT; 8112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } else { 8122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("findSubEffect() found effect: %s in lib %s", d->name, l->name); 8132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana *lib = l; 8142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (desc != NULL) { 8152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana *desc = d; 8162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return ret; 8192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana} 8202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana 821e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentlib_entry_t *getLibrary(const char *name) 822e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 823e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent list_elem_t *e; 824ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent 825e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (gCachedLibrary && 826e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent !strncmp(gCachedLibrary->name, name, PATH_MAX)) { 827e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return gCachedLibrary; 828e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 829e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 830e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent e = gLibraryList; 831e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent while (e) { 832e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent lib_entry_t *l = (lib_entry_t *)e->object; 833e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (!strcmp(l->name, name)) { 834e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent gCachedLibrary = l; 835e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return l; 836135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 837e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent e = e->next; 838135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 839135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 840e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return NULL; 841135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 842135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 843e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 844ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentvoid resetEffectEnumeration() 845ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent{ 846ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurLib = gLibraryList; 847ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurEffect = NULL; 848ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (gCurLib) { 849ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurEffect = ((lib_entry_t *)gCurLib->object)->effects; 850ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent } 851ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurEffectIdx = 0; 852ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent} 853135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 854ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentuint32_t updateNumEffects() { 855ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent list_elem_t *e; 856be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent uint32_t cnt = 0; 857135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 858ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent resetEffectEnumeration(); 859ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent 860ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent e = gLibraryList; 861135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (e) { 862135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent lib_entry_t *l = (lib_entry_t *)e->object; 863135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *efx = l->effects; 864135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (efx) { 865135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent cnt++; 866135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent efx = efx->next; 867135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 868135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e = e->next; 869135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 870ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gNumEffects = cnt; 871ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCanQueryEffect = 0; 872135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return cnt; 873135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 874135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 8755e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint findEffect(const effect_uuid_t *type, 8765e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kasten const effect_uuid_t *uuid, 877e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent lib_entry_t **lib, 878e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_descriptor_t **desc) 879135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 880135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *e = gLibraryList; 881135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent lib_entry_t *l = NULL; 882135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_descriptor_t *d = NULL; 883135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int found = 0; 884135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = 0; 885135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 886135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (e && !found) { 887135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent l = (lib_entry_t *)e->object; 888135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *efx = l->effects; 889135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (efx) { 890135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent d = (effect_descriptor_t *)efx->object; 891e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) { 892e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent found = 1; 893e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent break; 894e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 895e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) { 896135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent found = 1; 897135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent break; 898135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 899135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent efx = efx->next; 900135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 901135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e = e->next; 902135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 903135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (!found) { 9043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("findEffect() effect not found"); 905135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = -ENOENT; 906135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } else { 9073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("findEffect() found effect: %s in lib %s", d->name, l->name); 908135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *lib = l; 909e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (desc) { 910e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent *desc = d; 911e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 912135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 913135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 914135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 915135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 916135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 917d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenvoid dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent) { 918135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent char s[256]; 919d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char ss[256]; 920d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char idt[indent + 1]; 921d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 922d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen memset(idt, ' ', indent); 923d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen idt[indent] = 0; 924d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 925d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen str[0] = 0; 926135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 927d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen snprintf(s, sizeof(s), "%s%s / %s\n", idt, desc->name, desc->implementor); 928d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen strlcat(str, s, len); 929d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 930d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen uuidToString(&desc->uuid, s, sizeof(s)); 931d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen snprintf(ss, sizeof(ss), "%s UUID: %s\n", idt, s); 932d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen strlcat(str, ss, len); 933d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 934d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen uuidToString(&desc->type, s, sizeof(s)); 935d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen snprintf(ss, sizeof(ss), "%s TYPE: %s\n", idt, s); 936d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen strlcat(str, ss, len); 937d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 938d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen sprintf(s, "%s apiVersion: %08X\n%s flags: %08X\n", idt, 939d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen desc->apiVersion, idt, desc->flags); 940d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen strlcat(str, s, len); 941135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 942135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 943e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint stringToUuid(const char *str, effect_uuid_t *uuid) 944e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 945e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent int tmp[10]; 946e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 947e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", 948e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) { 949e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 950e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 951e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeLow = (uint32_t)tmp[0]; 952e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeMid = (uint16_t)tmp[1]; 953e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeHiAndVersion = (uint16_t)tmp[2]; 954e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->clockSeq = (uint16_t)tmp[3]; 955e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[0] = (uint8_t)tmp[4]; 956e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[1] = (uint8_t)tmp[5]; 957e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[2] = (uint8_t)tmp[6]; 958e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[3] = (uint8_t)tmp[7]; 959e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[4] = (uint8_t)tmp[8]; 960e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[5] = (uint8_t)tmp[9]; 961e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 962e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 963e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 964e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 965e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen) 966e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 967e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 968e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", 969e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeLow, 970e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeMid, 971e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeHiAndVersion, 972e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->clockSeq, 973e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[0], 974e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[1], 975e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[2], 976e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[3], 977e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[4], 978e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[5]); 979e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 980e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 981e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 982e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 983d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenint EffectDumpEffects(int fd) { 984d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char s[512]; 985d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen list_elem_t *e = gLibraryList; 986d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen lib_entry_t *l = NULL; 987d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen effect_descriptor_t *d = NULL; 988d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen int found = 0; 989d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen int ret = 0; 990d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 991d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen while (e) { 992d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen l = (lib_entry_t *)e->object; 993d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen list_elem_t *efx = l->effects; 994d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dprintf(fd, "Library %s\n", l->name); 995d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen if (!efx) { 996d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dprintf(fd, " (no effects)\n"); 997d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 998d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen while (efx) { 999d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen d = (effect_descriptor_t *)efx->object; 1000d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dumpEffectDescriptor(d, s, sizeof(s), 2); 1001d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dprintf(fd, "%s", s); 1002d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen efx = efx->next; 1003d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 1004d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen e = e->next; 1005d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 1006d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 1007d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen e = gSkippedEffects; 1008d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen if (e) { 1009d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dprintf(fd, "Skipped effects\n"); 1010d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen while(e) { 1011d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen d = (effect_descriptor_t *)e->object; 1012d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dumpEffectDescriptor(d, s, sizeof(s), 2 /* indent */); 1013d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dprintf(fd, "%s", s); 1014d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen e = e->next; 1015d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 1016d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 1017d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen return ret; 1018d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen} 1019d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 1020