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
2060d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn#include <stdlib.h>
2160d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn#include <string.h>
2260d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn#include <unistd.h>
23135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2420569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi#include <cutils/properties.h>
25eb16561336e6445f7edae047998f2459e046cdfeMark Salyzyn#include <log/log.h>
2660d02077d86d2d1092443519290101f503aa6f7aMark Salyzyn
27007709c5eb305b1ac3fcaaf35fbd7eb5aa8e672aKevin Rocard#include <media/EffectsFactoryApi.h>
2897b544846bd781afdbae55a28025020cb5772ec2Kevin Rocard
2997b544846bd781afdbae55a28025020cb5772ec2Kevin Rocard#include "EffectsConfigLoader.h"
3097b544846bd781afdbae55a28025020cb5772ec2Kevin Rocard#include "EffectsFactoryState.h"
3141af42b44e5d47bc3a1ca90d170f8da7205cacb8Kevin Rocard#include "EffectsXmlConfigLoader.h"
3297b544846bd781afdbae55a28025020cb5772ec2Kevin Rocard
3397b544846bd781afdbae55a28025020cb5772ec2Kevin Rocard#include "EffectsFactory.h"
34135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
35135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gEffectList; // list of effect_entry_t: all currently created effects
36ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gNumEffects;         // total number number of effects
37135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurLib;    // current library in enumeration process
38135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic list_elem_t *gCurEffect; // current effect in enumeration process
39ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t gCurEffectIdx;       // current effect index in enumeration process
40f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard/** Number of elements skipped during the effects configuration loading.
41f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard *  -1 if the config loader failed
42f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard *  -2 if config load was skipped
43f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard */
44f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocardstatic ssize_t gConfigNbElemSkipped = -2;
45135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
46135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int gInitDone; // true is global initialization has been preformed
47ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic int gCanQueryEffect; // indicates that call to EffectQueryEffect() is valid, i.e. that the list of effects
48ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                          // was not modified since last call to EffectQueryNumberEffects()
49135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
50135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Local functions prototypes
51135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
52135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
53135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentstatic int init();
54ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic void resetEffectEnumeration();
55ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentstatic uint32_t updateNumEffects();
562eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// To search a subeffect in the gSubEffectList
57d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenstatic int findSubEffect(const effect_uuid_t *uuid,
582eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               lib_entry_t **lib,
592eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               effect_descriptor_t **desc);
60135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
61135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
62135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Effect Control Interface functions
63135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
64135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
65e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Process(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
66135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
67135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
68135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
69135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
70135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
71135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
72135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
73135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
74135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&gLibLock);
75135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EPIPE;
76135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
77135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
78135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
79135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
80135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = (*fx->subItfe)->process(fx->subItfe, inBuffer, outBuffer);
81135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
82135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
83135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
84135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
85e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_Command(effect_handle_t self,
8625f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t cmdCode,
8725f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t cmdSize,
8825f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   void *pCmdData,
8925f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   uint32_t *replySize,
9025f4395b932fa9859a6e91ba77c5d20d009da64aEric Laurent                   void *pReplyData)
91135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
92135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
93135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
94135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
95135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
96135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
97135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
98135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
99135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&gLibLock);
100135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EPIPE;
101135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
102135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
103135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
104135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
105135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = (*fx->subItfe)->command(fx->subItfe, cmdCode, cmdSize, pCmdData, replySize, pReplyData);
106135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
107135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
108135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
109135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
110e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint Effect_GetDescriptor(effect_handle_t self,
111e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                         effect_descriptor_t *desc)
112e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent{
113e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    int ret = init();
114e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (ret < 0) {
115e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return ret;
116e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
117e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
118e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&gLibLock);
119e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (fx->lib == NULL) {
120e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        pthread_mutex_unlock(&gLibLock);
121e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EPIPE;
122e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
123e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_lock(&fx->lib->lock);
124e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_unlock(&gLibLock);
125e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
126e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = (*fx->subItfe)->get_descriptor(fx->subItfe, desc);
127e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    pthread_mutex_unlock(&fx->lib->lock);
128e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return ret;
129e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent}
130e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
131ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentint Effect_ProcessReverse(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer)
132ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent{
133ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    int ret = init();
134ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if (ret < 0) {
135ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        return ret;
136ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
137ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    effect_entry_t *fx = (effect_entry_t *)self;
138ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_lock(&gLibLock);
139ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if (fx->lib == NULL) {
140ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        pthread_mutex_unlock(&gLibLock);
141ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        return -EPIPE;
142ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
143ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_lock(&fx->lib->lock);
144ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_unlock(&gLibLock);
145ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
146ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if ((*fx->subItfe)->process_reverse != NULL) {
147ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        ret = (*fx->subItfe)->process_reverse(fx->subItfe, inBuffer, outBuffer);
148ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    } else {
149ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        ret = -ENOSYS;
150ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
151ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    pthread_mutex_unlock(&fx->lib->lock);
152ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    return ret;
153ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent}
154ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
155ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
156135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentconst struct effect_interface_s gInterface = {
157135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        Effect_Process,
158e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        Effect_Command,
159ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_GetDescriptor,
160ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        NULL
161ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent};
162ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent
163ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurentconst struct effect_interface_s gInterfaceWithReverse = {
164ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_Process,
165ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_Command,
166ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_GetDescriptor,
167ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        Effect_ProcessReverse
168135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent};
169135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
170135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
171135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Effect Factory Interface functions
172135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
173135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
174be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentint EffectQueryNumberEffects(uint32_t *pNumEffects)
175135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
176135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
177135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
178135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
179135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
180135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pNumEffects == NULL) {
181135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
182135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
183135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
184135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
185ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    *pNumEffects = gNumEffects;
186ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCanQueryEffect = 1;
187135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
1883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectQueryNumberEffects(): %d", *pNumEffects);
189135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
190135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
191135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
192ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentint EffectQueryEffect(uint32_t index, effect_descriptor_t *pDescriptor)
193135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
194135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
195135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
196135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
197135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
198ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (pDescriptor == NULL ||
199ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        index >= gNumEffects) {
200135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
201135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
202ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (gCanQueryEffect == 0) {
203ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        return -ENOSYS;
204ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
205135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
206135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
207135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = -ENOENT;
208ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (index < gCurEffectIdx) {
209ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        resetEffectEnumeration();
210ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
211135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (gCurLib) {
212135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        if (gCurEffect) {
213ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            if (index == gCurEffectIdx) {
214a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten                *pDescriptor = *(effect_descriptor_t *)gCurEffect->object;
215ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                ret = 0;
216ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                break;
217ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            } else {
218ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                gCurEffect = gCurEffect->next;
219ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent                gCurEffectIdx++;
220ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent            }
221135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        } else {
222135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            gCurLib = gCurLib->next;
223135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            gCurEffect = ((lib_entry_t *)gCurLib->object)->effects;
224135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
225135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
226ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
227ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#if (LOG_NDEBUG == 0)
228d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char str[512];
229d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    dumpEffectDescriptor(pDescriptor, str, sizeof(str), 0 /* indent */);
2303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectQueryEffect() desc:%s", str);
231ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent#endif
232135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
233135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
234135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
235135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2365e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectGetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t *pDescriptor)
237135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
238135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
239135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
240135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
241135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
242135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
243135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
244135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
245135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (pDescriptor == NULL || uuid == NULL) {
246135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
247135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
248135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
249e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = findEffect(NULL, uuid, &l, &d);
250135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret == 0) {
251a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten        *pDescriptor = *d;
252135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
253135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
254135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
255135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
256135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2575e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectCreate(const effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_handle_t *pHandle)
258135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
259135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e = gLibraryList;
260135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    lib_entry_t *l = NULL;
261135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_descriptor_t *d = NULL;
262e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    effect_handle_t itfe;
263135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx;
264135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret;
265135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
266e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (uuid == NULL || pHandle == NULL) {
267135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return -EINVAL;
268135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
269135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
2703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectCreate() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n",
271135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
272135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2],
273135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            uuid->node[3],uuid->node[4],uuid->node[5]);
274135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
275135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    ret = init();
276135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
277135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
2785ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectCreate() init error: %d", ret);
279135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
280135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
281135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
282135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
283135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
284e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ret = findEffect(NULL, uuid, &l, &d);
285135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0){
2862eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        // Sub effects are not associated with the library->effects,
2872eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        // so, findEffect will fail. Search for the effect in gSubEffectList.
2882eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ret = findSubEffect(uuid, &l, &d);
2892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        if (ret < 0 ) {
2902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            goto exit;
2912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
292135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
293135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
294135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // create effect in library
295342484f01824ab45af953c7c9193b1e5ad6326deEric Laurent    ret = l->desc->create_effect(uuid, sessionId, ioId, &itfe);
296ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (ret != 0) {
2975ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret);
298135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto exit;
299135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
300135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
301135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // add entry to effect list
302135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx = (effect_entry_t *)malloc(sizeof(effect_entry_t));
303135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx->subItfe = itfe;
304ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    if ((*itfe)->process_reverse != NULL) {
305ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        fx->itfe = (struct effect_interface_s *)&gInterfaceWithReverse;
3063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EffectCreate() gInterfaceWithReverse");
307ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }   else {
308ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent        fx->itfe = (struct effect_interface_s *)&gInterface;
3093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EffectCreate() gInterface");
310ba7b8f881a9b6b21803752326d2932a3bd42d7cfEric Laurent    }
311135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    fx->lib = l;
312135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
313135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e = (list_elem_t *)malloc(sizeof(list_elem_t));
314135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->object = fx;
315135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e->next = gEffectList;
316135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gEffectList = e;
317135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
318e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    *pHandle = (effect_handle_t)fx;
319135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("EffectCreate() created entry %p with sub itfe %p in library %s", *pHandle, itfe, l->name);
321135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
322135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit:
323135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_unlock(&gLibLock);
324135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
325135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
326135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
327e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentint EffectRelease(effect_handle_t handle)
328135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
329135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    effect_entry_t *fx;
330135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e1;
331135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    list_elem_t *e2;
332135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
333135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    int ret = init();
334135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (ret < 0) {
335135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return ret;
336135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
337135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
338135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // remove effect from effect list
339135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_lock(&gLibLock);
340135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e1 = gEffectList;
341135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    e2 = NULL;
342135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e1) {
343e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (e1->object == handle) {
344135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            if (e2) {
345135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                e2->next = e1->next;
346135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            } else {
347135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent                gEffectList = e1->next;
348135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            }
349135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            fx = (effect_entry_t *)e1->object;
350135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            free(e1);
351135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            break;
352135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
353135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e2 = e1;
354135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e1 = e1->next;
355135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
356135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (e1 == NULL) {
357135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        ret = -ENOENT;
358135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        goto exit;
359135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
360135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
361135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    // release effect in library
362135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (fx->lib == NULL) {
3635ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("EffectRelease() fx %p library already unloaded", handle);
364135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    } else {
365135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_lock(&fx->lib->lock);
366e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        fx->lib->desc->release_effect(fx->subItfe);
367135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        pthread_mutex_unlock(&fx->lib->lock);
368135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
369135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    free(fx);
370135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
371135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentexit:
372f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana    pthread_mutex_unlock(&gLibLock);
373135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return ret;
374135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
375135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3765e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenint EffectIsNullUuid(const effect_uuid_t *uuid)
377135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent{
378135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (memcmp(uuid, EFFECT_UUID_NULL, sizeof(effect_uuid_t))) {
379135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
380135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
381135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 1;
382135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
383135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
3842eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Function to get the sub effect descriptors of the effect whose uuid
3852eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// is pointed by the first argument. It searches the gSubEffectList for the
3862eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// matching uuid and then copies the corresponding sub effect descriptors
3872eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// to the inout param
388f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmanaint EffectGetSubEffects(const effect_uuid_t *uuid, sub_effect_entry_t **pSube,
389f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana                        size_t size)
3902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{
3912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   ALOGV("EffectGetSubEffects() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X"
3922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          "%02X\n",uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
3932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          uuid->clockSeq, uuid->node[0], uuid->node[1],uuid->node[2],
3942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana          uuid->node[3],uuid->node[4],uuid->node[5]);
3952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
3962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   // Check if the size of the desc buffer is large enough for 2 subeffects
397f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana   if ((uuid == NULL) || (pSube == NULL) || (size < 2)) {
3982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       ALOGW("NULL pointer or insufficient memory. Cannot query subeffects");
3992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       return -EINVAL;
4002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   }
4012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   int ret = init();
4022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   if (ret < 0)
4032eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana      return ret;
4042eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   list_sub_elem_t *e = gSubEffectList;
4052eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   sub_effect_entry_t *subeffect;
4062eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   effect_descriptor_t *d;
4072eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   int count = 0;
4082eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   while (e != NULL) {
4092eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       d = (effect_descriptor_t*)e->object;
4102eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       if (memcmp(uuid, &d->uuid, sizeof(effect_uuid_t)) == 0) {
4112eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           ALOGV("EffectGetSubEffects: effect found in the list");
4122eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           list_elem_t *subefx = e->sub_elem;
4132eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           while (subefx != NULL) {
4142eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               subeffect = (sub_effect_entry_t*)subefx->object;
415f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana               pSube[count++] = subeffect;
4162eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               subefx = subefx->next;
4172eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           }
418f90c7e0bb8d83d8b7f733bdf430d331ea3f221e8jpadmana           ALOGV("EffectGetSubEffects end - copied the sub effect structures");
4192eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana           return count;
4202eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       }
4212eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana       e = e->next;
4222eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   }
4232eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana   return -ENOENT;
4242eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana}
425135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
426135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent//      Local functions
427135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent/////////////////////////////////////////////////
428135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
429135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurentint init() {
430135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    if (gInitDone) {
431135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        return 0;
432135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
433135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
43420569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    // ignore effects or not?
43520569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    const bool ignoreFxConfFiles = property_get_bool(PROPERTY_IGNORE_EFFECTS, false);
43620569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi
437135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    pthread_mutex_init(&gLibLock, NULL);
438135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
43920569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    if (ignoreFxConfFiles) {
44020569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi        ALOGI("Audio effects in configuration files will be ignored");
44120569262fce8b047bfc253d91ccb0f455863fde1Jean-Michel Trivi    } else {
442f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard        gConfigNbElemSkipped = EffectLoadXmlEffectConfig(NULL);
443f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard        if (gConfigNbElemSkipped < 0) {
4448f5520a7378e7af0fcc6a8b693f29a6ddffbbbcdKevin Rocard            ALOGW("Failed to load XML effect configuration, fallback to .conf");
44541af42b44e5d47bc3a1ca90d170f8da7205cacb8Kevin Rocard            EffectLoadEffectConfig();
446f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard        } else if (gConfigNbElemSkipped > 0) {
447f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard            ALOGE("Effect config is partially invalid, skipped %zd elements", gConfigNbElemSkipped);
4488f5520a7378e7af0fcc6a8b693f29a6ddffbbbcdKevin Rocard        }
449135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
450e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
451ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    updateNumEffects();
452135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    gInitDone = 1;
4533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("init() done");
454135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return 0;
455135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
456135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
4572eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// Searches the sub effect matching to the specified uuid
4582eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// in the gSubEffectList. It gets the lib_entry_t for
4592eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana// the matched sub_effect . Used in EffectCreate of sub effects
4602eab94f7dfd41a65e13aca379a1aed97447f8884jpadmanaint findSubEffect(const effect_uuid_t *uuid,
4612eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               lib_entry_t **lib,
4622eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana               effect_descriptor_t **desc)
4632eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana{
4642eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_sub_elem_t *e = gSubEffectList;
4652eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    list_elem_t *subefx;
4662eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    sub_effect_entry_t *effect;
4672eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    lib_entry_t *l = NULL;
4682eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    effect_descriptor_t *d = NULL;
4692eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    int found = 0;
4702eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    int ret = 0;
4712eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
4722eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (uuid == NULL)
4732eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        return -EINVAL;
4742eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
4752eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    while (e != NULL && !found) {
4762eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        subefx = (list_elem_t*)(e->sub_elem);
4772eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        while (subefx != NULL) {
4782eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            effect = (sub_effect_entry_t*)subefx->object;
4792eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            l = (lib_entry_t *)effect->lib;
4802eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            d = (effect_descriptor_t *)effect->object;
4812eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            if (memcmp(&d->uuid, uuid, sizeof(effect_uuid_t)) == 0) {
4822eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                ALOGV("uuid matched");
4832eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                found = 1;
4842eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana                break;
4852eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            }
4862eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            subefx = subefx->next;
4872eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
4882eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        e = e->next;
4892eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
4902eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    if (!found) {
4912eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGV("findSubEffect() effect not found");
4922eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ret = -ENOENT;
4932eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    } else {
4942eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        ALOGV("findSubEffect() found effect: %s in lib %s", d->name, l->name);
4952eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        *lib = l;
4962eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        if (desc != NULL) {
4972eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana            *desc = d;
4982eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana        }
4992eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    }
5002eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana    return ret;
5012eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana}
5022eab94f7dfd41a65e13aca379a1aed97447f8884jpadmana
503ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentvoid resetEffectEnumeration()
504ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent{
505ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurLib = gLibraryList;
506ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurEffect = NULL;
507ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    if (gCurLib) {
508ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent        gCurEffect = ((lib_entry_t *)gCurLib->object)->effects;
509ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    }
510ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCurEffectIdx = 0;
511ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent}
512135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
513ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurentuint32_t updateNumEffects() {
514ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    list_elem_t *e;
515be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    uint32_t cnt = 0;
516135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
517ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    resetEffectEnumeration();
518ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent
519ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    e = gLibraryList;
520135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    while (e) {
521135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        lib_entry_t *l = (lib_entry_t *)e->object;
522135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        list_elem_t *efx = l->effects;
523135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        while (efx) {
524135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            cnt++;
525135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent            efx = efx->next;
526135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        }
527135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent        e = e->next;
528135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    }
529ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gNumEffects = cnt;
530ffe9c25ce85e1af55d58ec025adc6367d70db7e8Eric Laurent    gCanQueryEffect = 0;
531135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent    return cnt;
532135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent}
533135ad07e33d30e5202deb21061a0e3ecf0ffad35Eric Laurent
534d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissenint EffectDumpEffects(int fd) {
535d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    char s[512];
536090eb09be1600b101b6d6e4e092f30763776bc80rago
537090eb09be1600b101b6d6e4e092f30763776bc80rago    list_elem_t *fe = gLibraryFailedList;
538090eb09be1600b101b6d6e4e092f30763776bc80rago    lib_failed_entry_t *fl = NULL;
539090eb09be1600b101b6d6e4e092f30763776bc80rago
540090eb09be1600b101b6d6e4e092f30763776bc80rago    dprintf(fd, "Libraries NOT loaded:\n");
541090eb09be1600b101b6d6e4e092f30763776bc80rago
542090eb09be1600b101b6d6e4e092f30763776bc80rago    while (fe) {
543090eb09be1600b101b6d6e4e092f30763776bc80rago        fl = (lib_failed_entry_t *)fe->object;
544090eb09be1600b101b6d6e4e092f30763776bc80rago        dprintf(fd, " Library %s\n", fl->name);
545090eb09be1600b101b6d6e4e092f30763776bc80rago        dprintf(fd, "  path: %s\n", fl->path);
546090eb09be1600b101b6d6e4e092f30763776bc80rago        fe = fe->next;
547090eb09be1600b101b6d6e4e092f30763776bc80rago    }
548090eb09be1600b101b6d6e4e092f30763776bc80rago
549d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    list_elem_t *e = gLibraryList;
550d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    lib_entry_t *l = NULL;
551d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    effect_descriptor_t *d = NULL;
552d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    int ret = 0;
553d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
554090eb09be1600b101b6d6e4e092f30763776bc80rago    dprintf(fd, "Libraries loaded:\n");
555d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    while (e) {
556d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        l = (lib_entry_t *)e->object;
557d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        list_elem_t *efx = l->effects;
558090eb09be1600b101b6d6e4e092f30763776bc80rago        dprintf(fd, " Library %s\n", l->name);
559090eb09be1600b101b6d6e4e092f30763776bc80rago        dprintf(fd, "  path: %s\n", l->path);
560d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        if (!efx) {
561d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dprintf(fd, "  (no effects)\n");
562d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        }
563d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        while (efx) {
564d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            d = (effect_descriptor_t *)efx->object;
565d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dumpEffectDescriptor(d, s, sizeof(s), 2);
566d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dprintf(fd, "%s", s);
567d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            efx = efx->next;
568d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        }
569d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        e = e->next;
570d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    }
571d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
572d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    e = gSkippedEffects;
573d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    if (e) {
574d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        dprintf(fd, "Skipped effects\n");
575d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        while(e) {
576d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            d = (effect_descriptor_t *)e->object;
577d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dumpEffectDescriptor(d, s, sizeof(s), 2 /* indent */);
578d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            dprintf(fd, "%s", s);
579d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen            e = e->next;
580d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen        }
581d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    }
582f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard    switch (gConfigNbElemSkipped) {
583f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard    case -2:
584f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard        dprintf(fd, "Effect configuration loading skipped.\n");
585f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard        break;
586f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard    case -1:
587f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard        dprintf(fd, "XML effect configuration failed to load.\n");
588f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard        break;
589f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard    case 0:
590f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard        dprintf(fd, "XML effect configuration loaded successfully.\n");
591f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard        break;
592f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard    default:
593f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard        dprintf(fd, "XML effect configuration partially loaded, skipped %zd elements.\n",
594f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard                gConfigNbElemSkipped);
595f34e3f272d9ca267b73188ec7cb6c40ef27682ecKevin Rocard    }
596d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen    return ret;
597d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen}
598d89eaddd1544dc9f6665e2578583e8083cac00daMarco Nelissen
599