EffectsFactory.c revision e1315cf0b63b4c14a77046519e6b01f6f60d74b0
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>
27135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
28135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects
29135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gLibraryList; // list of lib_entry_t: all currently loaded libraries
30135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic pthread_mutex_t gLibLock = PTHREAD_MUTEX_INITIALIZER; // controls access to gLibraryList
31ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gNumEffects;         // total number number of effects
32135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurLib;    // current library in enumeration process
33135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurEffect; // current effect in enumeration process
34ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gCurEffectIdx;       // current effect index in enumeration process
35e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *gCachedLibrary;  // last library accessed by getLibrary()
36135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
37135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int gInitDone; // true is global initialization has been preformed
38ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects
39ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                          // was not modified since last call to EffectQueryNumberEffects()
40135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
41e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
42135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
43135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Local functions prototypes
44135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
45135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int init();
47e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffectConfigFile(const char *path);
48e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibraries(cnode *root);
49e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadLibrary(cnode *root, const char *name);
50e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffects(cnode *root);
51e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int loadEffect(cnode *node);
52e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic lib_entry_t *getLibrary(const char *path);
53ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic void resetEffectEnumeration();
54ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t updateNumEffects();
55e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int findEffect(effect_uuid_t *type,
56e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               effect_uuid_t *uuid,
57e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               lib_entry_t **lib,
58e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               effect_descriptor_t **desc);
59135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic void dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len);
60e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int stringToUuid(const char *str, effect_uuid_t *uuid);
61e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentstatic int uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen);
62135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
63135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
64135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Effect Control Interface functions
65135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
66135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
67e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
68135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
69135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
70135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
71135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
72135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
73135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
74135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
75135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
76135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&gLibLock);
77135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EPIPE;
78135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
79135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = (*fx->subItfe)->process(fx->subItfe, inBuffer, outBuffer);
83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
84135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
85135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
86135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
87e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Command(effect_handle_t self,
8825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t cmdCode,
8925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t cmdSize,
9025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   void *pCmdData,
9125f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t *replySize,
9225f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   void *pReplyData)
93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
99135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
100135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
101135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&gLibLock);
102135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EPIPE;
103135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
104135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
105135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
106135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
107135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = (*fx->subItfe)->command(fx->subItfe, cmdCode, cmdSize, pCmdData, replySize, pReplyData);
108135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
109135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
110135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
111135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
112e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_GetDescriptor(effect_handle_t self,
113e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                         effect_descriptor_t *desc)
114e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
115e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    int ret = init();
116e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (ret < 0) {
117e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return ret;
118e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
119e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
120e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&gLibLock);
121e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (fx->lib == NULL) {
122e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        pthread_mutex_unlock(&gLibLock);
123e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EPIPE;
124e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
125e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
126e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_unlock(&gLibLock);
127e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
128e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = (*fx->subItfe)->get_descriptor(fx->subItfe, desc);
129e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
130e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return ret;
131e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
132e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
133135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst struct effect_interface_s gInterface = {
134135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        Effect_Process,
135e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        Effect_Command,
136e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        Effect_GetDescriptor
137135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
138135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
139135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
140135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Effect Factory Interface functions
141135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
142135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
143be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentint EffectQueryNumberEffects(uint32_t *pNumEffects)
144135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
145135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
146135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
147135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
148135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
149135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pNumEffects == NULL) {
150135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
151135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
152135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
153135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
154ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    *pNumEffects = gNumEffects;
155ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCanQueryEffect = 1;
156135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
157135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    LOGV("EffectQueryNumberEffects(): %d", *pNumEffects);
158135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
159135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
160135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
161ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentint EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor)
162135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
163135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
164135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
165135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
166135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
167ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (pDescriptor == NULL ||
168ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        index >= gNumEffects) {
169135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
170135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
171ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (gCanQueryEffect == 0) {
172ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        return -ENOSYS;
173ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
174135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
175135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
176135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = -ENOENT;
177ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (index < gCurEffectIdx) {
178ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        resetEffectEnumeration();
179ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
180135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (gCurLib) {
181135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (gCurEffect) {
182ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            if (index == gCurEffectIdx) {
183ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                memcpy(pDescriptor, gCurEffect->object, sizeof(effect_descriptor_t));
184ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                ret = 0;
185ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                break;
186ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            } else {
187ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                gCurEffect = gCurEffect->next;
188ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                gCurEffectIdx++;
189ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            }
190135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        } else {
191135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            gCurLib = gCurLib->next;
192135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            gCurEffect = ((lib_entry_t *)gCurLib->object)->effects;
193135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
194135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
195ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
196ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#if (LOG_NDEBUG == 0)
197135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    char str[256];
198135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    dumpEffectDescriptor(pDescriptor, str, 256);
199ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    LOGV("EffectQueryEffect() desc:%s", str);
200ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#endif
201135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
202135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
203135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
204135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
205135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint EffectGetDescriptor(effect_uuid_t *uuid, effect_descriptor_t *pDescriptor)
206135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
207135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
208135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
209135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
210135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
211135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
212135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
213135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
214135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pDescriptor == NULL || uuid == NULL) {
215135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
216135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
217135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
218e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = findEffect(NULL, uuid, &l, &d);
219135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret == 0) {
220135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        memcpy(pDescriptor, d, sizeof(effect_descriptor_t));
221135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
222135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
223135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
224135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
225135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
226e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle)
227135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
228135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e = gLibraryList;
229135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
230135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
231e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_handle_t itfe;
232135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx;
233135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int found = 0;
234135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret;
235135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
236e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (uuid == NULL || pHandle == NULL) {
237135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
238135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
239135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
240135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    LOGV("EffectCreate() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
241135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
242135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2],
243135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->node[3],uuid->node[4],uuid->node[5]);
244135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
245135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = init();
246135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
247135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
248135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        LOGW("EffectCreate() init error: %d", ret);
249135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
250135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
251135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
252135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
253135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
254e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = findEffect(NULL, uuid, &l, &d);
255135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0){
256135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto exit;
257135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
258135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
259135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // create effect in library
260e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->desc->create_effect(uuid, sessionId, ioId, &itfe);
261ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (ret != 0) {
262e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        LOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret);
263135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto exit;
264135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
265135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
266135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // add entry to effect list
267135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx = (effect_entry_t *)malloc(sizeof(effect_entry_t));
268135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx->subItfe = itfe;
269135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx->itfe = (struct effect_interface_s *)&gInterface;
270135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx->lib = l;
271135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
272135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e = (list_elem_t *)malloc(sizeof(list_elem_t));
273135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->object = fx;
274135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->next = gEffectList;
275135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gEffectList = e;
276135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
277e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    *pHandle = (effect_handle_t)fx;
278135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
279e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    LOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pHandle, itfe, l->name);
280135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
281135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit:
282135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
283135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
284135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
285135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
286e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint EffectRelease(effect_handle_t handle)
287135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
288135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx;
289135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e1;
290135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e2;
291135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
292135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
293135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
294135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
295135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
296135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
297135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // remove effect from effect list
298135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
299135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e1 = gEffectList;
300135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e2 = NULL;
301135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e1) {
302e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (e1->object == handle) {
303135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            if (e2) {
304135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                e2->next = e1->next;
305135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            } else {
306135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                gEffectList = e1->next;
307135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            }
308135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            fx = (effect_entry_t *)e1->object;
309135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            free(e1);
310135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
311135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
312135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e2 = e1;
313135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e1 = e1->next;
314135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
315135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (e1 == NULL) {
316135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ret = -ENOENT;
317135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto exit;
318135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
319135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
320135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // release effect in library
321135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
322e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        LOGW("EffectRelease() fx %p library already unloaded", handle);
323135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
324135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_lock(&fx->lib->lock);
325e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        fx->lib->desc->release_effect(fx->subItfe);
326135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&fx->lib->lock);
327135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
328135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    free(fx);
329135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
330135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit:
331135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
332135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
333135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
334135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
335135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint EffectLoadLibrary(const char *libPath, int *handle)
336135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
337e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    // TODO: see if this interface still makes sense with the use of config files
338e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return -ENOSYS;
339135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
340135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
341135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint EffectUnloadLibrary(int handle)
342135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
343e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    // TODO: see if this interface still makes sense with the use of config files
344e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return -ENOSYS;
345135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
346135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
347135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint EffectIsNullUuid(effect_uuid_t *uuid)
348135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
349135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (memcmp(uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t))) {
350135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
351135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
352135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 1;
353135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
354135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
355135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
356135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Local functions
357135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
358135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
359135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint init() {
360135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int hdl;
361135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
362135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (gInitDone) {
363135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
364135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
365135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
366135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_init(&gLibLock, NULL);
367135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
368e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
369e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadEffectConfigFile(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
370e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
371e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadEffectConfigFile(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
372135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
373e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
374ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    updateNumEffects();
375135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gInitDone = 1;
376135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    LOGV("init() done");
377135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
378135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
379135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
380e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffectConfigFile(const char *path)
381135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
382e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *root;
383e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    char *data;
384135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
385e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    data = load_file(path, NULL);
386e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (data == NULL) {
387e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENODEV;
388135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
389e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    root = config_node("", "");
390e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    config_load(root, data);
391e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    loadLibraries(root);
392e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    loadEffects(root);
393e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    config_free(root);
394e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    free(root);
395e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    free(data);
396135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
397e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
398e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
399135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
400e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibraries(cnode *root)
401e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
402e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
403135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
404e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, LIBRARIES_TAG);
405e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
406e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENOENT;
407135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
408e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = node->first_child;
409e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (node) {
410e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadLibrary(node, node->name);
411e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        node = node->next;
412135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
413e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
414e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
415e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
416e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadLibrary(cnode *root, const char *name)
417e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
418e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
419e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    void *hdl;
420e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    audio_effect_library_t *desc;
421e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
422e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    lib_entry_t *l;
423e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
424e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, PATH_TAG);
425e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
426e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
427135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
428e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
429e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    hdl = dlopen(node->value, RTLD_NOW);
430e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (hdl == NULL) {
431e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        LOGW("loadLibrary() failed to open %s", node->value);
432135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto error;
433135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
434135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
435e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    desc = (audio_effect_library_t *)dlsym(hdl, AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
436e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (desc == NULL) {
437e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        LOGW("loadLibrary() could not find symbol %s", AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR);
438135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto error;
439135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
440135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
441e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (AUDIO_EFFECT_LIBRARY_TAG != desc->tag) {
442e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        LOGW("getLibrary() bad tag %08x in lib info struct", desc->tag);
443e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        goto error;
444135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
445ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
446e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (EFFECT_API_VERSION_MAJOR(desc->version) !=
447e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            EFFECT_API_VERSION_MAJOR(EFFECT_LIBRARY_API_VERSION)) {
448e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        LOGW("loadLibrary() bad lib version %08x", desc->version);
449e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        goto error;
450e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
451ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
452135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // add entry for library in gLibraryList
453135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    l = malloc(sizeof(lib_entry_t));
454e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->name = strndup(name, PATH_MAX);
455e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->path = strndup(node->value, PATH_MAX);
456135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    l->handle = hdl;
457e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->desc = desc;
458e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->effects = NULL;
459135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_init(&l->lock, NULL);
460135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
461135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e = malloc(sizeof(list_elem_t));
462135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->object = l;
463e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&gLibLock);
464e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e->next = gLibraryList;
465135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gLibraryList = e;
466135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
467e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    LOGV("getLibrary() linked library %p for path %s", l, node->value);
468135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
469135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
470135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
471135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurenterror:
472e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (hdl != NULL) {
473e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        dlclose(hdl);
474e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
475e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return -EINVAL;
476135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
477135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
478e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffects(cnode *root)
479135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
480e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
481e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
482e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, EFFECTS_TAG);
483e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
484e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -ENOENT;
485e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
486e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = node->first_child;
487e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (node) {
488e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        loadEffect(node);
489e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        node = node->next;
490e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
491e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
492e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
493e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
494e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint loadEffect(cnode *root)
495e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
496e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    cnode *node;
497e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_uuid_t uuid;
498135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l;
499e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_descriptor_t *d;
500e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
501135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
502e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, LIBRARY_TAG);
503e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
504e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
505135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
506e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
507e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l = getLibrary(node->value);
508e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (l == NULL) {
509e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        LOGW("loadEffect() could not get library %s", node->value);
510e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
511135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
512135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
513e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    node = config_find(root, UUID_TAG);
514e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (node == NULL) {
515e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
516e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
517e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (stringToUuid(node->value, &uuid) != 0) {
518e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        LOGW("loadEffect() invalid uuid %s", node->value);
519e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
520e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
521e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
522e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    d = malloc(sizeof(effect_descriptor_t));
523e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (l->desc->get_descriptor(&uuid, d) != 0) {
524e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        char s[40];
525e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        uuidToString(&uuid, s, 40);
526e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        LOGW("Error querying effect %s on lib %s", s, l->name);
527e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        free(d);
528e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
529e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
530e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#if (LOG_NDEBUG==0)
531e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    char s[256];
532e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    dumpEffectDescriptor(d, s, 256);
533e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    LOGV("loadEffect() read descriptor %p:%s",d, s);
534e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent#endif
535e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (EFFECT_API_VERSION_MAJOR(d->apiVersion) !=
536e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            EFFECT_API_VERSION_MAJOR(EFFECT_CONTROL_API_VERSION)) {
537e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        LOGW("Bad API version %08x on lib %s", d->apiVersion, l->name);
538e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        free(d);
539e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
540135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
541e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e = malloc(sizeof(list_elem_t));
542e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e->object = d;
543e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e->next = l->effects;
544e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    l->effects = e;
545e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
546e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
547e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
548135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
549e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentlib_entry_t *getLibrary(const char *name)
550e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
551e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    list_elem_t *e;
552ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
553e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (gCachedLibrary &&
554e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            !strncmp(gCachedLibrary->name, name, PATH_MAX)) {
555e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return gCachedLibrary;
556e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
557e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
558e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    e = gLibraryList;
559e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    while (e) {
560e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        lib_entry_t *l = (lib_entry_t *)e->object;
561e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (!strcmp(l->name, name)) {
562e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            gCachedLibrary = l;
563e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            return l;
564135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
565e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        e = e->next;
566135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
567135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
568e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return NULL;
569135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
570135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
571e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
572ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentvoid resetEffectEnumeration()
573ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent{
574ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurLib = gLibraryList;
575ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurEffect = NULL;
576ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (gCurLib) {
577ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        gCurEffect = ((lib_entry_t *)gCurLib->object)->effects;
578ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
579ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurEffectIdx = 0;
580ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent}
581135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
582ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentuint32_t updateNumEffects() {
583ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    list_elem_t *e;
584be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    uint32_t cnt = 0;
585135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
586ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    resetEffectEnumeration();
587ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
588ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    e = gLibraryList;
589135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e) {
590135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        lib_entry_t *l = (lib_entry_t *)e->object;
591135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        list_elem_t *efx = l->effects;
592135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        while (efx) {
593135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            cnt++;
594135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            efx = efx->next;
595135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
596135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e = e->next;
597135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
598ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gNumEffects = cnt;
599ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCanQueryEffect = 0;
600135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return cnt;
601135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
602135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
603e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint findEffect(effect_uuid_t *type,
604e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               effect_uuid_t *uuid,
605e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               lib_entry_t **lib,
606e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent               effect_descriptor_t **desc)
607135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
608135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e = gLibraryList;
609135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
610135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
611135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int found = 0;
612135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = 0;
613135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
614135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e && !found) {
615135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        l = (lib_entry_t *)e->object;
616135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        list_elem_t *efx = l->effects;
617135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        while (efx) {
618135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            d = (effect_descriptor_t *)efx->object;
619e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            if (type != NULL && memcmp(&d->type, type, sizeof(effect_uuid_t)) == 0) {
620e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                found = 1;
621e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                break;
622e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            }
623e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            if (uuid != NULL && memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
624135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                found = 1;
625135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                break;
626135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            }
627135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            efx = efx->next;
628135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
629135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e = e->next;
630135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
631135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (!found) {
632135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        LOGV("findEffect() effect not found");
633135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ret = -ENOENT;
634135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
635e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        LOGV("findEffect() found effect: %s in lib %s", d->name, l->name);
636135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        *lib = l;
637e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (desc) {
638e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            *desc = d;
639e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        }
640135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
641135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
642135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
643135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
644135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
645135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentvoid dumpEffectDescriptor(effect_descriptor_t *desc, char *str, size_t len) {
646135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    char s[256];
647135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
648135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    snprintf(str, len, "\nEffect Descriptor %p:\n", desc);
649e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    strncat(str, "- TYPE: ", len);
650e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuidToString(&desc->uuid, s, 256);
651e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    snprintf(str, len, "- UUID: %s\n", s);
652e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuidToString(&desc->type, s, 256);
653e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    snprintf(str, len, "- TYPE: %s\n", s);
654e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    sprintf(s, "- apiVersion: %08X\n- flags: %08X\n",
655135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            desc->apiVersion, desc->flags);
656135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    strncat(str, s, len);
657135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    sprintf(s, "- name: %s\n", desc->name);
658135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    strncat(str, s, len);
659135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    sprintf(s, "- implementor: %s\n", desc->implementor);
660135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    strncat(str, s, len);
661135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
662135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
663e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint stringToUuid(const char *str, effect_uuid_t *uuid)
664e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
665e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    int tmp[10];
666e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
667e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
668e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
669e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
670e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
671e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeLow = (uint32_t)tmp[0];
672e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeMid = (uint16_t)tmp[1];
673e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->timeHiAndVersion = (uint16_t)tmp[2];
674e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->clockSeq = (uint16_t)tmp[3];
675e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[0] = (uint8_t)tmp[4];
676e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[1] = (uint8_t)tmp[5];
677e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[2] = (uint8_t)tmp[6];
678e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[3] = (uint8_t)tmp[7];
679e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[4] = (uint8_t)tmp[8];
680e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    uuid->node[5] = (uint8_t)tmp[9];
681e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
682e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
683e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
684e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
685e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint uuidToString(const effect_uuid_t *uuid, char *str, size_t maxLen)
686e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
687e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
688e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
689e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeLow,
690e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeMid,
691e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->timeHiAndVersion,
692e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->clockSeq,
693e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[0],
694e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[1],
695e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[2],
696e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[3],
697e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[4],
698e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            uuid->node[5]);
699e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
700e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return 0;
701e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
702e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
703