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" 2160d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn 22135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent#include <dlfcn.h> 2360d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn#include <stdlib.h> 2460d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn#include <string.h> 2560d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn#include <unistd.h> 26135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 27e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#include <cutils/config_utils.h> 2860d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn#include <cutils/misc.h> 2920569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi#include <cutils/properties.h> 30eb16561336e6445f7edae047998f2459e046cdfeMark Salyzyn#include <log/log.h> 3160d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn 32c2f710f89ec1a3ea8e448bfafcc02b03529cc681Mikhail Naganov#include <system/audio_effects/audio_effects_conf.h> 33135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 34135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects 35135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries 36d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic list_elem_t *gSkippedEffects; // list of effects skipped because of duplicate uuid 372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// list of effect_descriptor and list of sub effects : all currently loaded 382eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// It does not contain effects without sub effects. 392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanastatic list_sub_elem_t *gSubEffectList; 40135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic pthread_mutex_t gLibLock = PTHREAD_MUTEX_INITIALIZER; // controls access to gLibraryList 41ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gNumEffects; // total number number of effects 42135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurLib; // current library in enumeration process 43135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurEffect; // current effect in enumeration process 44ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gCurEffectIdx; // current effect index in enumeration process 45e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *gCachedLibrary; // last library accessed by getLibrary() 46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 47135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int gInitDone; // true is global initialization has been preformed 48ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects 49ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent // was not modified since last call to EffectQueryNumberEffects() 50135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 51090eb09be1600b101b6d6e4e092f30763776bc80ragostatic list_elem_t *gLibraryFailedList; //list of lib_failed_entry_t: libraries failed to load 52e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 53135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 54135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Local functions prototypes 55135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 56135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 57135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int init(); 58e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffectConfigFile(const char *path); 59e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibraries(cnode *root); 60e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibrary(cnode *root, const char *name); 61e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffects(cnode *root); 62e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffect(cnode *node); 632eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// To get and add the effect pointed by the passed node to the gSubEffectList 642eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanastatic int addSubEffect(cnode *root); 65e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *getLibrary(const char *path); 66ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic void resetEffectEnumeration(); 67ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t updateNumEffects(); 685e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenstatic int findEffect(const effect_uuid_t *type, 695e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kasten const effect_uuid_t *uuid, 70e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent lib_entry_t **lib, 71e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_descriptor_t **desc); 722eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// To search a subeffect in the gSubEffectList 73d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic int findSubEffect(const effect_uuid_t *uuid, 742eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana lib_entry_t **lib, 752eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t **desc); 76d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent); 77e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int stringToUuid(const char *str, effect_uuid_t *uuid); 78e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen); 79135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Effect Control Interface functions 82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 84e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) 85135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 87135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 88135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 89135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 90135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_entry_t *fx = (effect_entry_t *)self; 91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (fx->lib == NULL) { 93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EPIPE; 95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&fx->lib->lock); 97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 99135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = (*fx->subItfe)->process(fx->subItfe, inBuffer, outBuffer); 100135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&fx->lib->lock); 101135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 102135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 103135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 104e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Command(effect_handle_t self, 10525f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent uint32_t cmdCode, 10625f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent uint32_t cmdSize, 10725f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent void *pCmdData, 10825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent uint32_t *replySize, 10925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent void *pReplyData) 110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 111135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 112135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 113135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 114135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 115135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_entry_t *fx = (effect_entry_t *)self; 116135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 117135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (fx->lib == NULL) { 118135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 119135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EPIPE; 120135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 121135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&fx->lib->lock); 122135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 123135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 124135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = (*fx->subItfe)->command(fx->subItfe, cmdCode, cmdSize, pCmdData, replySize, pReplyData); 125135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&fx->lib->lock); 126135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 127135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 128135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 129e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_GetDescriptor(effect_handle_t self, 130e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_descriptor_t *desc) 131e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 132e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent int ret = init(); 133e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (ret < 0) { 134e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return ret; 135e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 136e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_entry_t *fx = (effect_entry_t *)self; 137e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_lock(&gLibLock); 138e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (fx->lib == NULL) { 139e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_unlock(&gLibLock); 140e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EPIPE; 141e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 142e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_lock(&fx->lib->lock); 143e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_unlock(&gLibLock); 144e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 145e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent ret = (*fx->subItfe)->get_descriptor(fx->subItfe, desc); 146e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_unlock(&fx->lib->lock); 147e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return ret; 148e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 149e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 150ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentint Effect_ProcessReverse(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) 151ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent{ 152ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent int ret = init(); 153ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent if (ret < 0) { 154ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent return ret; 155ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } 156ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent effect_entry_t *fx = (effect_entry_t *)self; 157ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent pthread_mutex_lock(&gLibLock); 158ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent if (fx->lib == NULL) { 159ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent pthread_mutex_unlock(&gLibLock); 160ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent return -EPIPE; 161ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } 162ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent pthread_mutex_lock(&fx->lib->lock); 163ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent pthread_mutex_unlock(&gLibLock); 164ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent 165ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent if ((*fx->subItfe)->process_reverse != NULL) { 166ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent ret = (*fx->subItfe)->process_reverse(fx->subItfe, inBuffer, outBuffer); 167ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } else { 168ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent ret = -ENOSYS; 169ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } 170ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent pthread_mutex_unlock(&fx->lib->lock); 171ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent return ret; 172ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent} 173ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent 174ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent 175135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst struct effect_interface_s gInterface = { 176135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent Effect_Process, 177e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent Effect_Command, 178ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent Effect_GetDescriptor, 179ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent NULL 180ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent}; 181ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent 182ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentconst struct effect_interface_s gInterfaceWithReverse = { 183ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent Effect_Process, 184ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent Effect_Command, 185ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent Effect_GetDescriptor, 186ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent Effect_ProcessReverse 187135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}; 188135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 189135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 190135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Effect Factory Interface functions 191135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 192135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 193be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentint EffectQueryNumberEffects(uint32_t *pNumEffects) 194135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 195135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 196135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 197135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 198135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 199135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (pNumEffects == NULL) { 200135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EINVAL; 201135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 202135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 203135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 204ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent *pNumEffects = gNumEffects; 205ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCanQueryEffect = 1; 206135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 2073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectQueryNumberEffects(): %d", *pNumEffects); 208135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 209135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 210135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 211ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentint EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor) 212135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 213135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 214135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 215135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 216135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 217ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (pDescriptor == NULL || 218ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent index >= gNumEffects) { 219135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EINVAL; 220135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 221ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (gCanQueryEffect == 0) { 222ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent return -ENOSYS; 223ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent } 224135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 225135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 226135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = -ENOENT; 227ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (index < gCurEffectIdx) { 228ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent resetEffectEnumeration(); 229ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent } 230135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (gCurLib) { 231135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (gCurEffect) { 232ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (index == gCurEffectIdx) { 233a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten *pDescriptor = *(effect_descriptor_t *)gCurEffect->object; 234ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent ret = 0; 235ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent break; 236ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent } else { 237ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurEffect = gCurEffect->next; 238ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurEffectIdx++; 239ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent } 240135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } else { 241135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gCurLib = gCurLib->next; 242135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gCurEffect = ((lib_entry_t *)gCurLib->object)->effects; 243135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 244135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 245ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent 246ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#if (LOG_NDEBUG == 0) 247d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char str[512]; 248d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dumpEffectDescriptor(pDescriptor, str, sizeof(str), 0 /* indent */); 2493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectQueryEffect() desc:%s", str); 250ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#endif 251135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 252135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 253135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 254135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 2555e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor) 256135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 257135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent lib_entry_t *l = NULL; 258135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_descriptor_t *d = NULL; 259135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 260135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 261135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 262135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 263135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 264135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (pDescriptor == NULL || uuid == NULL) { 265135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EINVAL; 266135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 267135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 268e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent ret = findEffect(NULL, uuid, &l, &d); 269135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret == 0) { 270a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten *pDescriptor = *d; 271135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 272135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 273135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 274135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 275135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 2765e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle) 277135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 278135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *e = gLibraryList; 279135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent lib_entry_t *l = NULL; 280135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_descriptor_t *d = NULL; 281e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_handle_t itfe; 282135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_entry_t *fx; 283135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int found = 0; 284135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret; 285135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 286e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (uuid == NULL || pHandle == NULL) { 287135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return -EINVAL; 288135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 289135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 2903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectCreate() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n", 291135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, 292135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2], 293135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent uuid->node[3],uuid->node[4],uuid->node[5]); 294135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 295135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = init(); 296135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 297135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 2985ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("EffectCreate() init error: %d", ret); 299135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 300135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 301135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 302135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 303135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 304e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent ret = findEffect(NULL, uuid, &l, &d); 305135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0){ 3062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // Sub effects are not associated with the library->effects, 3072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // so, findEffect will fail. Search for the effect in gSubEffectList. 3082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ret = findSubEffect(uuid, &l, &d); 3092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (ret < 0 ) { 3102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana goto exit; 3112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 312135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 313135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 314135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // create effect in library 315342484f01824ab45af953c7c9193b1e5ad6326deEric Laurent ret = l->desc->create_effect(uuid, sessionId, ioId, &itfe); 316ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (ret != 0) { 3175ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret); 318135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent goto exit; 319135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 320135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 321135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // add entry to effect list 322135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent fx = (effect_entry_t *)malloc(sizeof(effect_entry_t)); 323135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent fx->subItfe = itfe; 324ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent if ((*itfe)->process_reverse != NULL) { 325ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent fx->itfe = (struct effect_interface_s *)&gInterfaceWithReverse; 3263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectCreate() gInterfaceWithReverse"); 327ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } else { 328ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent fx->itfe = (struct effect_interface_s *)&gInterface; 3293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectCreate() gInterface"); 330ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent } 331135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent fx->lib = l; 332135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 333135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e = (list_elem_t *)malloc(sizeof(list_elem_t)); 334135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e->object = fx; 335135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e->next = gEffectList; 336135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gEffectList = e; 337135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 338e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent *pHandle = (effect_handle_t)fx; 339135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 3403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pHandle, itfe, l->name); 341135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 342135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit: 343135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 344135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 345135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 346135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 347e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint EffectRelease(effect_handle_t handle) 348135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 349135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_entry_t *fx; 350135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *e1; 351135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *e2; 352135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 353135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = init(); 354135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (ret < 0) { 355135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 356135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 357135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 358135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // remove effect from effect list 359135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&gLibLock); 360135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e1 = gEffectList; 361135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e2 = NULL; 362135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (e1) { 363e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (e1->object == handle) { 364135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (e2) { 365135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e2->next = e1->next; 366135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } else { 367135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gEffectList = e1->next; 368135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 369135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent fx = (effect_entry_t *)e1->object; 370135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent free(e1); 371135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent break; 372135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 373135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e2 = e1; 374135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e1 = e1->next; 375135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 376135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (e1 == NULL) { 377135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = -ENOENT; 378135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent goto exit; 379135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 380135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 381135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // release effect in library 382135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (fx->lib == NULL) { 3835ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("EffectRelease() fx %p library already unloaded", handle); 384135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } else { 385135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_lock(&fx->lib->lock); 386e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent fx->lib->desc->release_effect(fx->subItfe); 387135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&fx->lib->lock); 388135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 389135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent free(fx); 390135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 391135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit: 392f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana pthread_mutex_unlock(&gLibLock); 393135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 394135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 395135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 3965e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectIsNullUuid(const effect_uuid_t *uuid) 397135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 398135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (memcmp(uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t))) { 399135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return 0; 400135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 401135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return 1; 402135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 403135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 4042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Function to get the sub effect descriptors of the effect whose uuid 4052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// is pointed by the first argument. It searches the gSubEffectList for the 4062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// matching uuid and then copies the corresponding sub effect descriptors 4072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// to the inout param 408f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmanaint EffectGetSubEffects(const effect_uuid_t *uuid, sub_effect_entry_t **pSube, 409f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana size_t size) 4102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{ 4112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("EffectGetSubEffects() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X" 4122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana "%02X\n",uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, 4132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2], 4142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana uuid->node[3],uuid->node[4],uuid->node[5]); 4152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana 4162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // Check if the size of the desc buffer is large enough for 2 subeffects 417f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana if ((uuid == NULL) || (pSube == NULL) || (size < 2)) { 4182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("NULL pointer or insufficient memory. Cannot query subeffects"); 4192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 4202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 4212eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana int ret = init(); 4222eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (ret < 0) 4232eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return ret; 4242eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_sub_elem_t *e = gSubEffectList; 4252eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect_entry_t *subeffect; 4262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t *d; 4272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana int count = 0; 4282eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana while (e != NULL) { 4292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana d = (effect_descriptor_t*)e->object; 4302eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (memcmp(uuid, &d->uuid, sizeof(effect_uuid_t)) == 0) { 4312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("EffectGetSubEffects: effect found in the list"); 4322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_elem_t *subefx = e->sub_elem; 4332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana while (subefx != NULL) { 4342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana subeffect = (sub_effect_entry_t*)subefx->object; 435f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana pSube[count++] = subeffect; 4362eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana subefx = subefx->next; 4372eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 438f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana ALOGV("EffectGetSubEffects end - copied the sub effect structures"); 4392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return count; 4402eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 4412eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana e = e->next; 4422eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 4432eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -ENOENT; 4442eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana} 445135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 446135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent// Local functions 447135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent///////////////////////////////////////////////// 448135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 449135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint init() { 450135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int hdl; 451135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 452135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (gInitDone) { 453135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return 0; 454135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 455135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 45620569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi // ignore effects or not? 45720569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi const bool ignoreFxConfFiles = property_get_bool(PROPERTY_IGNORE_EFFECTS, false); 45820569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi 459135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_init(&gLibLock, NULL); 460135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 46120569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi if (ignoreFxConfFiles) { 46220569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi ALOGI("Audio effects in configuration files will be ignored"); 46320569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi } else { 46420569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) { 46520569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE); 46620569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) { 46720569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE); 46820569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi } 469135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 470e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 471ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent updateNumEffects(); 472135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gInitDone = 1; 4733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("init() done"); 474135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return 0; 475135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 476135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 477e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffectConfigFile(const char *path) 478135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 479e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent cnode *root; 480e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent char *data; 481135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 482e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent data = load_file(path, NULL); 483e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (data == NULL) { 484e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -ENODEV; 485135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 486e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent root = config_node("", ""); 487e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent config_load(root, data); 488e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent loadLibraries(root); 489e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent loadEffects(root); 490e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent config_free(root); 491e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent free(root); 492e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent free(data); 493135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 494e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 495e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 496135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 497e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibraries(cnode *root) 498e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 499e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent cnode *node; 500135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 501e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = config_find(root, LIBRARIES_TAG); 502e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (node == NULL) { 503e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -ENOENT; 504135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 505e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = node->first_child; 506e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent while (node) { 507e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent loadLibrary(node, node->name); 508e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = node->next; 509135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 510e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 511e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 512e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 5130556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent#ifdef __LP64__ 5140556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent// audio_effects.conf always specifies 32 bit lib path: convert to 64 bit path if needed 5150556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurentstatic const char *kLibraryPathRoot[] = 5160556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent {"/odm/lib64/soundfx", "/vendor/lib64/soundfx", "/system/lib64/soundfx"}; 5170556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent#else 5180556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurentstatic const char *kLibraryPathRoot[] = 5190556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent {"/odm/lib/soundfx", "/vendor/lib/soundfx", "/system/lib/soundfx"}; 5200556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent#endif 5210556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 5220556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurentstatic const int kLibraryPathRootSize = 5230556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent (sizeof(kLibraryPathRoot) / sizeof(kLibraryPathRoot[0])); 5240556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 5250556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent// Checks if the library path passed as lib_path_in can be opened and if not 5260556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent// tries in standard effect library directories with just the library name and returns correct path 5270556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent// in lib_path_out 5280556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurentint checkLibraryPath(const char *lib_path_in, char *lib_path_out) { 5290556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent char *str; 5300556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent const char *lib_name; 5310556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent size_t len; 5320556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 5330556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent if (lib_path_in == NULL || lib_path_out == NULL) { 5340556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent return -EINVAL; 5350556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent } 5360556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 5370556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent strlcpy(lib_path_out, lib_path_in, PATH_MAX); 5380556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 5390556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent // Try exact path first 5400556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent str = strstr(lib_path_out, "/lib/soundfx/"); 5410556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent if (str == NULL) { 5420556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent return -EINVAL; 5430556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent } 5440556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 5450556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent // Extract library name from input path 5460556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent len = str - lib_path_out; 5470556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent lib_name = lib_path_in + len + strlen("/lib/soundfx/"); 5480556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 5490556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent // Then try with library name and standard path names in order of preference 5500556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent for (int i = 0; i < kLibraryPathRootSize; i++) { 5510556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent char path[PATH_MAX]; 5520556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 5530556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent snprintf(path, 5540556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent PATH_MAX, 5550556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent "%s/%s", 5560556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent kLibraryPathRoot[i], 5570556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent lib_name); 5580556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent if (F_OK == access(path, 0)) { 5590556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent strcpy(lib_path_out, path); 5600556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent ALOGW_IF(strncmp(lib_path_out, lib_path_in, PATH_MAX) != 0, 5610556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent "checkLibraryPath() corrected library path %s to %s", lib_path_in, lib_path_out); 5620556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent return 0; 5630556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent } 5640556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent } 5650556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent return -EINVAL; 5660556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent} 5670556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 5680556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 5690556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 570e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibrary(cnode *root, const char *name) 571e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 572e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent cnode *node; 5730556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent void *hdl = NULL; 574e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent audio_effect_library_t *desc; 575e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent list_elem_t *e; 576e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent lib_entry_t *l; 577a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent char path[PATH_MAX]; 578e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 579e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = config_find(root, PATH_TAG); 580e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (node == NULL) { 581e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 582135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 5830556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent 5840556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent if (checkLibraryPath((const char *)node->value, path) != 0) { 5850556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent ALOGW("loadLibrary() could not find library %s", path); 5860556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent goto error; 5870556a2363ff5eb49bd35dc47f2d34cc2042de052Eric Laurent } 588e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 589a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent hdl = dlopen(path, RTLD_NOW); 590e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (hdl == NULL) { 591a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent ALOGW("loadLibrary() failed to open %s", path); 592135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent goto error; 593135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 594135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 595e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR); 596e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (desc == NULL) { 5975ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR); 598135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent goto error; 599135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 600135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 601e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) { 6025ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("getLibrary() bad tag %08x in lib info struct", desc->tag); 603e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent goto error; 604135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 605ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent 606e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (EFFECT_API_VERSION_MAJOR(desc->version) != 607e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) { 6085ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("loadLibrary() bad lib version %08x", desc->version); 609e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent goto error; 610e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 611ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent 612135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent // add entry for library in gLibraryList 613135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent l = malloc(sizeof(lib_entry_t)); 614e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent l->name = strndup(name, PATH_MAX); 615a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent l->path = strndup(path, PATH_MAX); 616135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent l->handle = hdl; 617e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent l->desc = desc; 618e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent l->effects = NULL; 619135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_init(&l->lock, NULL); 620135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 621135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e = malloc(sizeof(list_elem_t)); 622135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e->object = l; 623e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent pthread_mutex_lock(&gLibLock); 624e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent e->next = gLibraryList; 625135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent gLibraryList = e; 626135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent pthread_mutex_unlock(&gLibLock); 627a5309e5c2a7a02852d2a0db7ada89a2eacb047d0Eric Laurent ALOGV("getLibrary() linked library %p for path %s", l, path); 628135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 629135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return 0; 630135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 631135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurenterror: 632e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (hdl != NULL) { 633e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent dlclose(hdl); 634e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 635090eb09be1600b101b6d6e4e092f30763776bc80rago //add entry for library errors in gLibraryFailedList 636090eb09be1600b101b6d6e4e092f30763776bc80rago lib_failed_entry_t *fl = malloc(sizeof(lib_failed_entry_t)); 637090eb09be1600b101b6d6e4e092f30763776bc80rago fl->name = strndup(name, PATH_MAX); 638090eb09be1600b101b6d6e4e092f30763776bc80rago fl->path = strndup(path, PATH_MAX); 639090eb09be1600b101b6d6e4e092f30763776bc80rago 640090eb09be1600b101b6d6e4e092f30763776bc80rago list_elem_t *fe = malloc(sizeof(list_elem_t)); 641090eb09be1600b101b6d6e4e092f30763776bc80rago fe->object = fl; 642090eb09be1600b101b6d6e4e092f30763776bc80rago fe->next = gLibraryFailedList; 643090eb09be1600b101b6d6e4e092f30763776bc80rago gLibraryFailedList = fe; 644090eb09be1600b101b6d6e4e092f30763776bc80rago ALOGV("getLibrary() linked error in library %p for path %s", fl, path); 645090eb09be1600b101b6d6e4e092f30763776bc80rago 646e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 647135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 648135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 6492eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// This will find the library and UUID tags of the sub effect pointed by the 6502eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// node, gets the effect descriptor and lib_entry_t and adds the subeffect - 6512eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// sub_entry_t to the gSubEffectList 6522eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint addSubEffect(cnode *root) 6532eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{ 6542eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("addSubEffect"); 6552eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana cnode *node; 6562eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_uuid_t uuid; 6572eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t *d; 6582eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana lib_entry_t *l; 6592eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_elem_t *e; 6602eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana node = config_find(root, LIBRARY_TAG); 6612eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (node == NULL) { 6622eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6632eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6642eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana l = getLibrary(node->value); 6652eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (l == NULL) { 6662eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("addSubEffect() could not get library %s", node->value); 6672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6682eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6692eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana node = config_find(root, UUID_TAG); 6702eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (node == NULL) { 6712eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6722eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6732eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (stringToUuid(node->value, &uuid) != 0) { 6742eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("addSubEffect() invalid uuid %s", node->value); 6752eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6762eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6772eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana d = malloc(sizeof(effect_descriptor_t)); 6782eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (l->desc->get_descriptor(&uuid, d) != 0) { 6792eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana char s[40]; 6802eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana uuidToString(&uuid, s, 40); 6812eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("Error querying effect %s on lib %s", s, l->name); 6822eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana free(d); 6832eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6842eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6852eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana#if (LOG_NDEBUG==0) 686d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char s[512]; 687d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */); 6882eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("addSubEffect() read descriptor %p:%s",d, s); 6892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana#endif 6902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (EFFECT_API_VERSION_MAJOR(d->apiVersion) != 6912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) { 6922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name); 6932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana free(d); 6942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 6952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 6962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect_entry_t *sub_effect = malloc(sizeof(sub_effect_entry_t)); 6972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect->object = d; 6982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // lib_entry_t is stored since the sub effects are not linked to the library 6992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect->lib = l; 7002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana e = malloc(sizeof(list_elem_t)); 7012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana e->object = sub_effect; 7022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana e->next = gSubEffectList->sub_elem; 7032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana gSubEffectList->sub_elem = e; 7042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("addSubEffect end"); 7052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return 0; 7062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana} 7072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana 708e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffects(cnode *root) 709135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 710e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent cnode *node; 711e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 712e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = config_find(root, EFFECTS_TAG); 713e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (node == NULL) { 714e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -ENOENT; 715e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 716e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = node->first_child; 717e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent while (node) { 718e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent loadEffect(node); 719e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = node->next; 720e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 721e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 722e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 723e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 724e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffect(cnode *root) 725e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 726e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent cnode *node; 727e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_uuid_t uuid; 728135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent lib_entry_t *l; 729e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_descriptor_t *d; 730e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent list_elem_t *e; 731135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 732e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = config_find(root, LIBRARY_TAG); 733e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (node == NULL) { 734e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 735135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 736e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 737e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent l = getLibrary(node->value); 738e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (l == NULL) { 7395ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("loadEffect() could not get library %s", node->value); 740e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 741135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 742135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 743e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent node = config_find(root, UUID_TAG); 744e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (node == NULL) { 745e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 746e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 747e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (stringToUuid(node->value, &uuid) != 0) { 7485ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("loadEffect() invalid uuid %s", node->value); 749e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 750e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 751d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen lib_entry_t *tmp; 752d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen bool skip = false; 753d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen if (findEffect(NULL, &uuid, &tmp, NULL) == 0) { 754d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen ALOGW("skipping duplicate uuid %s %s", node->value, 755d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen node->next ? "and its sub-effects" : ""); 756d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen skip = true; 757d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 758e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 759e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent d = malloc(sizeof(effect_descriptor_t)); 760e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (l->desc->get_descriptor(&uuid, d) != 0) { 761e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent char s[40]; 762e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuidToString(&uuid, s, 40); 7635ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Error querying effect %s on lib %s", s, l->name); 764e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent free(d); 765e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 766e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 767e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#if (LOG_NDEBUG==0) 768d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char s[512]; 769d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dumpEffectDescriptor(d, s, sizeof(s), 0 /* indent */); 7703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("loadEffect() read descriptor %p:%s",d, s); 771e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#endif 772e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (EFFECT_API_VERSION_MAJOR(d->apiVersion) != 773e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) { 7745ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("Bad API version %08x on lib %s", d->apiVersion, l->name); 775e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent free(d); 776e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 777135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 778e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent e = malloc(sizeof(list_elem_t)); 779e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent e->object = d; 780d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen if (skip) { 781d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen e->next = gSkippedEffects; 782d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen gSkippedEffects = e; 783d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen return -EINVAL; 784d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } else { 785d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen e->next = l->effects; 786d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen l->effects = e; 787d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 788e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 7892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // After the UUID node in the config_tree, if node->next is valid, 7902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // that would be sub effect node. 7912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // Find the sub effects and add them to the gSubEffectList 7922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana node = node->next; 7932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana int count = 2; 7942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana bool hwSubefx = false, swSubefx = false; 7952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_sub_elem_t *sube = NULL; 7962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (node != NULL) { 7972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("Adding the effect to gEffectSubList as there are sub effects"); 7982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sube = malloc(sizeof(list_sub_elem_t)); 7992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sube->object = d; 8002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sube->sub_elem = NULL; 8012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sube->next = gSubEffectList; 8022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana gSubEffectList = sube; 8032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana while (node != NULL && count) { 8052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (addSubEffect(node)) { 8062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGW("loadEffect() could not add subEffect %s", node->value); 8072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // Change the gSubEffectList to point to older list; 8082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana gSubEffectList = sube->next; 8092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana free(sube->sub_elem);// Free an already added sub effect 8102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sube->sub_elem = NULL; 8112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana free(sube); 8122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -ENOENT; 8132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect_entry_t *subEntry = (sub_effect_entry_t*)gSubEffectList->sub_elem->object; 8152eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t *subEffectDesc = (effect_descriptor_t*)(subEntry->object); 8162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // Since we return a dummy descriptor for the proxy during 8172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // get_descriptor call,we replace it with the correspoding 8182eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // sw effect descriptor, but with Proxy UUID 8192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // check for Sw desc 8202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (!((subEffectDesc->flags & EFFECT_FLAG_HW_ACC_MASK) == 8212eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana EFFECT_FLAG_HW_ACC_TUNNEL)) { 8222eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana swSubefx = true; 8232eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana *d = *subEffectDesc; 8242eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana d->uuid = uuid; 8252eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("loadEffect() Changed the Proxy desc"); 8262eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } else 8272eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana hwSubefx = true; 8282eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana count--; 8292eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana node = node->next; 8302eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8312eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana // 1 HW and 1 SW sub effect found. Set the offload flag in the Proxy desc 8322eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (hwSubefx && swSubefx) { 8332eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana d->flags |= EFFECT_FLAG_OFFLOAD_SUPPORTED; 8342eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 835e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 836e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 837135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 8382eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Searches the sub effect matching to the specified uuid 8392eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// in the gSubEffectList. It gets the lib_entry_t for 8402eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// the matched sub_effect . Used in EffectCreate of sub effects 8412eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint findSubEffect(const effect_uuid_t *uuid, 8422eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana lib_entry_t **lib, 8432eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t **desc) 8442eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{ 8452eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_sub_elem_t *e = gSubEffectList; 8462eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana list_elem_t *subefx; 8472eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana sub_effect_entry_t *effect; 8482eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana lib_entry_t *l = NULL; 8492eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect_descriptor_t *d = NULL; 8502eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana int found = 0; 8512eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana int ret = 0; 8522eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana 8532eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (uuid == NULL) 8542eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return -EINVAL; 8552eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana 8562eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana while (e != NULL && !found) { 8572eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana subefx = (list_elem_t*)(e->sub_elem); 8582eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana while (subefx != NULL) { 8592eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana effect = (sub_effect_entry_t*)subefx->object; 8602eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana l = (lib_entry_t *)effect->lib; 8612eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana d = (effect_descriptor_t *)effect->object; 8622eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) { 8632eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("uuid matched"); 8642eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana found = 1; 8652eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana break; 8662eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana subefx = subefx->next; 8682eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8692eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana e = e->next; 8702eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8712eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (!found) { 8722eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("findSubEffect() effect not found"); 8732eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ret = -ENOENT; 8742eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } else { 8752eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana ALOGV("findSubEffect() found effect: %s in lib %s", d->name, l->name); 8762eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana *lib = l; 8772eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana if (desc != NULL) { 8782eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana *desc = d; 8792eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8802eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana } 8812eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana return ret; 8822eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana} 8832eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana 884e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentlib_entry_t *getLibrary(const char *name) 885e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 886e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent list_elem_t *e; 887ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent 888e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (gCachedLibrary && 889e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent !strncmp(gCachedLibrary->name, name, PATH_MAX)) { 890e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return gCachedLibrary; 891e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 892e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 893e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent e = gLibraryList; 894e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent while (e) { 895e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent lib_entry_t *l = (lib_entry_t *)e->object; 896e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (!strcmp(l->name, name)) { 897e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent gCachedLibrary = l; 898e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return l; 899135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 900e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent e = e->next; 901135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 902135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 903e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return NULL; 904135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 905135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 906e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 907ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentvoid resetEffectEnumeration() 908ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent{ 909ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurLib = gLibraryList; 910ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurEffect = NULL; 911ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent if (gCurLib) { 912ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurEffect = ((lib_entry_t *)gCurLib->object)->effects; 913ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent } 914ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCurEffectIdx = 0; 915ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent} 916135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 917ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentuint32_t updateNumEffects() { 918ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent list_elem_t *e; 919be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent uint32_t cnt = 0; 920135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 921ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent resetEffectEnumeration(); 922ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent 923ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent e = gLibraryList; 924135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (e) { 925135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent lib_entry_t *l = (lib_entry_t *)e->object; 926135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *efx = l->effects; 927135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (efx) { 928135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent cnt++; 929135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent efx = efx->next; 930135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 931135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e = e->next; 932135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 933ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gNumEffects = cnt; 934ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent gCanQueryEffect = 0; 935135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return cnt; 936135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 937135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 9385e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint findEffect(const effect_uuid_t *type, 9395e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kasten const effect_uuid_t *uuid, 940e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent lib_entry_t **lib, 941e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent effect_descriptor_t **desc) 942135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{ 943135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *e = gLibraryList; 944135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent lib_entry_t *l = NULL; 945135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent effect_descriptor_t *d = NULL; 946135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int found = 0; 947135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent int ret = 0; 948135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 949135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (e && !found) { 950135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent l = (lib_entry_t *)e->object; 951135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent list_elem_t *efx = l->effects; 952135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent while (efx) { 953135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent d = (effect_descriptor_t *)efx->object; 954e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) { 955e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent found = 1; 956e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent break; 957e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 958e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) { 959135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent found = 1; 960135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent break; 961135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 962135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent efx = efx->next; 963135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 964135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent e = e->next; 965135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 966135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent if (!found) { 9673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("findEffect() effect not found"); 968135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent ret = -ENOENT; 969135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } else { 9703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("findEffect() found effect: %s in lib %s", d->name, l->name); 971135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent *lib = l; 972e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (desc) { 973e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent *desc = d; 974e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 975135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent } 976135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 977135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent return ret; 978135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 979135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 980d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenvoid dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len, int indent) { 981135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent char s[256]; 982d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char ss[256]; 983d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char idt[indent + 1]; 984d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 985d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen memset(idt, ' ', indent); 986d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen idt[indent] = 0; 987d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 988d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen str[0] = 0; 989135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 990d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen snprintf(s, sizeof(s), "%s%s / %s\n", idt, desc->name, desc->implementor); 991d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen strlcat(str, s, len); 992d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 993d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen uuidToString(&desc->uuid, s, sizeof(s)); 994d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen snprintf(ss, sizeof(ss), "%s UUID: %s\n", idt, s); 995d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen strlcat(str, ss, len); 996d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 997d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen uuidToString(&desc->type, s, sizeof(s)); 998d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen snprintf(ss, sizeof(ss), "%s TYPE: %s\n", idt, s); 999d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen strlcat(str, ss, len); 1000d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 1001d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen sprintf(s, "%s apiVersion: %08X\n%s flags: %08X\n", idt, 1002d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen desc->apiVersion, idt, desc->flags); 1003d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen strlcat(str, s, len); 1004135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent} 1005135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent 1006e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint stringToUuid(const char *str, effect_uuid_t *uuid) 1007e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 1008e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent int tmp[10]; 1009e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 1010e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", 1011e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) { 1012e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return -EINVAL; 1013e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent } 1014e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeLow = (uint32_t)tmp[0]; 1015e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeMid = (uint16_t)tmp[1]; 1016e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeHiAndVersion = (uint16_t)tmp[2]; 1017e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->clockSeq = (uint16_t)tmp[3]; 1018e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[0] = (uint8_t)tmp[4]; 1019e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[1] = (uint8_t)tmp[5]; 1020e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[2] = (uint8_t)tmp[6]; 1021e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[3] = (uint8_t)tmp[7]; 1022e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[4] = (uint8_t)tmp[8]; 1023e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[5] = (uint8_t)tmp[9]; 1024e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 1025e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 1026e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 1027e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 1028e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen) 1029e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{ 1030e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 1031e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", 1032e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeLow, 1033e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeMid, 1034e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->timeHiAndVersion, 1035e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->clockSeq, 1036e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[0], 1037e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[1], 1038e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[2], 1039e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[3], 1040e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[4], 1041e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent uuid->node[5]); 1042e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 1043e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent return 0; 1044e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} 1045e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent 1046d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenint EffectDumpEffects(int fd) { 1047d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen char s[512]; 1048090eb09be1600b101b6d6e4e092f30763776bc80rago 1049090eb09be1600b101b6d6e4e092f30763776bc80rago list_elem_t *fe = gLibraryFailedList; 1050090eb09be1600b101b6d6e4e092f30763776bc80rago lib_failed_entry_t *fl = NULL; 1051090eb09be1600b101b6d6e4e092f30763776bc80rago 1052090eb09be1600b101b6d6e4e092f30763776bc80rago dprintf(fd, "Libraries NOT loaded:\n"); 1053090eb09be1600b101b6d6e4e092f30763776bc80rago 1054090eb09be1600b101b6d6e4e092f30763776bc80rago while (fe) { 1055090eb09be1600b101b6d6e4e092f30763776bc80rago fl = (lib_failed_entry_t *)fe->object; 1056090eb09be1600b101b6d6e4e092f30763776bc80rago dprintf(fd, " Library %s\n", fl->name); 1057090eb09be1600b101b6d6e4e092f30763776bc80rago dprintf(fd, " path: %s\n", fl->path); 1058090eb09be1600b101b6d6e4e092f30763776bc80rago fe = fe->next; 1059090eb09be1600b101b6d6e4e092f30763776bc80rago } 1060090eb09be1600b101b6d6e4e092f30763776bc80rago 1061d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen list_elem_t *e = gLibraryList; 1062d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen lib_entry_t *l = NULL; 1063d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen effect_descriptor_t *d = NULL; 1064d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen int found = 0; 1065d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen int ret = 0; 1066d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 1067090eb09be1600b101b6d6e4e092f30763776bc80rago dprintf(fd, "Libraries loaded:\n"); 1068d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen while (e) { 1069d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen l = (lib_entry_t *)e->object; 1070d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen list_elem_t *efx = l->effects; 1071090eb09be1600b101b6d6e4e092f30763776bc80rago dprintf(fd, " Library %s\n", l->name); 1072090eb09be1600b101b6d6e4e092f30763776bc80rago dprintf(fd, " path: %s\n", l->path); 1073d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen if (!efx) { 1074d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dprintf(fd, " (no effects)\n"); 1075d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 1076d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen while (efx) { 1077d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen d = (effect_descriptor_t *)efx->object; 1078d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dumpEffectDescriptor(d, s, sizeof(s), 2); 1079d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dprintf(fd, "%s", s); 1080d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen efx = efx->next; 1081d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 1082d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen e = e->next; 1083d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 1084d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 1085d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen e = gSkippedEffects; 1086d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen if (e) { 1087d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dprintf(fd, "Skipped effects\n"); 1088d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen while(e) { 1089d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen d = (effect_descriptor_t *)e->object; 1090d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dumpEffectDescriptor(d, s, sizeof(s), 2 /* indent */); 1091d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen dprintf(fd, "%s", s); 1092d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen e = e->next; 1093d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 1094d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen } 1095d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen return ret; 1096d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen} 1097d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen 1098