AudioPolicyEffects.cpp revision 138ed1796f8c8edd318488911a9b056877191778
1ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu/*
2ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * Copyright (C) 2014 The Android Open Source Project
3ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *
4ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * Licensed under the Apache License, Version 2.0 (the "License");
5ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * you may not use this file except in compliance with the License.
6ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * You may obtain a copy of the License at
7ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *
8ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *      http://www.apache.org/licenses/LICENSE-2.0
9ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *
10ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * Unless required by applicable law or agreed to in writing, software
11ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * distributed under the License is distributed on an "AS IS" BASIS,
12ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * See the License for the specific language governing permissions and
14ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu * limitations under the License.
15ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu */
16ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
17ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#define LOG_TAG "AudioPolicyEffects"
18897a408b3f9c893776d67214257ca6a6bc1751bdEric Laurent//#define LOG_NDEBUG 0
19ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
20ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <stdlib.h>
21ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <stdio.h>
22ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <string.h>
23ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <cutils/misc.h>
24ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <media/AudioEffect.h>
25ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <system/audio.h>
26ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <hardware/audio_effect.h>
27ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <audio_effects/audio_effects_conf.h>
28ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <utils/Vector.h>
29ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <utils/SortedVector.h>
30ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <cutils/config_utils.h>
31ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include "AudioPolicyEffects.h"
32ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include "ServiceUtilities.h"
33ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
34ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liunamespace android {
35ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
36ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ----------------------------------------------------------------------------
37ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// AudioPolicyEffects Implementation
38ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ----------------------------------------------------------------------------
39ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
40ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuAudioPolicyEffects::AudioPolicyEffects()
41ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
42ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // load automatic audio effect modules
43ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
44ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        loadAudioEffectConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
45ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
46ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        loadAudioEffectConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
47ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
48ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
49ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
50ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
51ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuAudioPolicyEffects::~AudioPolicyEffects()
52ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
53ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    size_t i = 0;
54ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // release audio input processing resources
55ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    for (i = 0; i < mInputSources.size(); i++) {
56ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        delete mInputSources.valueAt(i);
57ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
58ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    mInputSources.clear();
59ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
60fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    for (i = 0; i < mInputSessions.size(); i++) {
61fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        mInputSessions.valueAt(i)->mEffects.clear();
62fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        delete mInputSessions.valueAt(i);
63ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
64fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    mInputSessions.clear();
65ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
66ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // release audio output processing resources
67ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    for (i = 0; i < mOutputStreams.size(); i++) {
68ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        delete mOutputStreams.valueAt(i);
69ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
70ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    mOutputStreams.clear();
71ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
72ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    for (i = 0; i < mOutputSessions.size(); i++) {
73ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        mOutputSessions.valueAt(i)->mEffects.clear();
74ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        delete mOutputSessions.valueAt(i);
75ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
76ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    mOutputSessions.clear();
77ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
78ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
79ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
80ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input,
81ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                             audio_source_t inputSource,
82fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                             audio_session_t audioSession)
83ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
84ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t status = NO_ERROR;
85ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
86ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // create audio pre processors according to input source
87ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    audio_source_t aliasSource = (inputSource == AUDIO_SOURCE_HOTWORD) ?
88ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                    AUDIO_SOURCE_VOICE_RECOGNITION : inputSource;
89ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
908b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    Mutex::Autolock _l(mLock);
91ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    ssize_t index = mInputSources.indexOfKey(aliasSource);
92ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (index < 0) {
93ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGV("addInputEffects(): no processing needs to be attached to this source");
94ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return status;
95ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
96fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    ssize_t idx = mInputSessions.indexOfKey(audioSession);
97fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    EffectVector *sessionDesc;
98ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (idx < 0) {
99fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        sessionDesc = new EffectVector(audioSession);
100fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        mInputSessions.add(audioSession, sessionDesc);
101ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    } else {
102890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu        // EffectVector is existing and we just need to increase ref count
103fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        sessionDesc = mInputSessions.valueAt(idx);
104ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
105fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    sessionDesc->mRefCount++;
106890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu
107fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    ALOGV("addInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
108fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (sessionDesc->mRefCount == 1) {
1097de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent        Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
1107de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent        for (size_t i = 0; i < effects.size(); i++) {
1117de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            EffectDesc *effect = effects[i];
112be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov            sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, -1, 0,
113be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov                                                 0, audioSession, input);
1147de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            status_t status = fx->initCheck();
1157de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            if (status != NO_ERROR && status != ALREADY_EXISTS) {
1167de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent                ALOGW("addInputEffects(): failed to create Fx %s on source %d",
1177de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent                      effect->mName, (int32_t)aliasSource);
1187de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent                // fx goes out of scope and strong ref on AudioEffect is released
1197de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent                continue;
1207de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            }
1217de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            for (size_t j = 0; j < effect->mParams.size(); j++) {
1227de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent                fx->setParameter(effect->mParams[j]);
1237de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            }
1247de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            ALOGV("addInputEffects(): added Fx %s on source: %d",
125ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                  effect->mName, (int32_t)aliasSource);
126fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent            sessionDesc->mEffects.add(fx);
127ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
128fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        sessionDesc->setProcessorEnabled(true);
129ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
130ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return status;
131ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
132ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
133ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
134fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentstatus_t AudioPolicyEffects::releaseInputEffects(audio_io_handle_t input,
135fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                                                 audio_session_t audioSession)
136ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
137ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t status = NO_ERROR;
138ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
1398b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    Mutex::Autolock _l(mLock);
140fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    ssize_t index = mInputSessions.indexOfKey(audioSession);
141ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (index < 0) {
142ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return status;
143ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
144fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    EffectVector *sessionDesc = mInputSessions.valueAt(index);
145fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    sessionDesc->mRefCount--;
146fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    ALOGV("releaseInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount);
147fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (sessionDesc->mRefCount == 0) {
148fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        sessionDesc->setProcessorEnabled(false);
149fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        delete sessionDesc;
150fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        mInputSessions.removeItemsAt(index);
151890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu        ALOGV("releaseInputEffects(): all effects released");
152890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu    }
153ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return status;
154ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
155ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
156fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentstatus_t AudioPolicyEffects::queryDefaultInputEffects(audio_session_t audioSession,
157ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                                      effect_descriptor_t *descriptors,
158ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                                      uint32_t *count)
159ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
160ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t status = NO_ERROR;
161ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
1628b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    Mutex::Autolock _l(mLock);
163ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    size_t index;
164fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    for (index = 0; index < mInputSessions.size(); index++) {
165fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent        if (mInputSessions.valueAt(index)->mSessionId == audioSession) {
166ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            break;
167ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
168ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
169fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    if (index == mInputSessions.size()) {
170ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        *count = 0;
171ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return BAD_VALUE;
172ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
173fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent    Vector< sp<AudioEffect> > effects = mInputSessions.valueAt(index)->mEffects;
174ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
175ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    for (size_t i = 0; i < effects.size(); i++) {
176ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        effect_descriptor_t desc = effects[i]->descriptor();
177ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (i < *count) {
178ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            descriptors[i] = desc;
179ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
180ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
181ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (effects.size() > *count) {
182ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        status = NO_MEMORY;
183ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
184ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    *count = effects.size();
185ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return status;
186ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
187ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
188ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
189fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentstatus_t AudioPolicyEffects::queryDefaultOutputSessionEffects(audio_session_t audioSession,
190ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                         effect_descriptor_t *descriptors,
191ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                         uint32_t *count)
192ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
193ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t status = NO_ERROR;
194ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
1958b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    Mutex::Autolock _l(mLock);
196ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    size_t index;
197ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    for (index = 0; index < mOutputSessions.size(); index++) {
198ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (mOutputSessions.valueAt(index)->mSessionId == audioSession) {
199ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            break;
200ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
201ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
202ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (index == mOutputSessions.size()) {
203ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        *count = 0;
204ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return BAD_VALUE;
205ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
206ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    Vector< sp<AudioEffect> > effects = mOutputSessions.valueAt(index)->mEffects;
207ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
208ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    for (size_t i = 0; i < effects.size(); i++) {
209ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        effect_descriptor_t desc = effects[i]->descriptor();
210ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (i < *count) {
211ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            descriptors[i] = desc;
212ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
213ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
214ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (effects.size() > *count) {
215ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        status = NO_MEMORY;
216ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
217ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    *count = effects.size();
218ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return status;
219ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
220ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
221ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
222ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output,
223ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                         audio_stream_type_t stream,
224fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                         audio_session_t audioSession)
225ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
226ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t status = NO_ERROR;
227ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
2288b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    Mutex::Autolock _l(mLock);
229ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // create audio processors according to stream
230223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    // FIXME: should we have specific post processing settings for internal streams?
231223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    // default to media for now.
232223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    if (stream >= AUDIO_STREAM_PUBLIC_CNT) {
233223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent        stream = AUDIO_STREAM_MUSIC;
234223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    }
235ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    ssize_t index = mOutputStreams.indexOfKey(stream);
236ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (index < 0) {
237ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGV("addOutputSessionEffects(): no output processing needed for this stream");
238ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return NO_ERROR;
239ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
240ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
241ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    ssize_t idx = mOutputSessions.indexOfKey(audioSession);
242ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    EffectVector *procDesc;
243ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (idx < 0) {
244ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        procDesc = new EffectVector(audioSession);
245ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        mOutputSessions.add(audioSession, procDesc);
246ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    } else {
247890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu        // EffectVector is existing and we just need to increase ref count
248ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        procDesc = mOutputSessions.valueAt(idx);
249ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
250890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu    procDesc->mRefCount++;
251890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu
2527de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent    ALOGV("addOutputSessionEffects(): session: %d, refCount: %d",
2537de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent          audioSession, procDesc->mRefCount);
2547de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent    if (procDesc->mRefCount == 1) {
2557de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent        Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects;
2567de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent        for (size_t i = 0; i < effects.size(); i++) {
2577de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            EffectDesc *effect = effects[i];
258be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov            sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, 0, 0, 0,
2597de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent                                                 audioSession, output);
2607de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            status_t status = fx->initCheck();
2617de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            if (status != NO_ERROR && status != ALREADY_EXISTS) {
2627de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent                ALOGE("addOutputSessionEffects(): failed to create Fx  %s on session %d",
2637de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent                      effect->mName, audioSession);
2647de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent                // fx goes out of scope and strong ref on AudioEffect is released
2657de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent                continue;
2667de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            }
2677de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            ALOGV("addOutputSessionEffects(): added Fx %s on session: %d for stream: %d",
2687de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent                  effect->mName, audioSession, (int32_t)stream);
2697de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent            procDesc->mEffects.add(fx);
270ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
271ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
2727de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent        procDesc->setProcessorEnabled(true);
2737de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent    }
274ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return status;
275ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
276ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
277ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output,
278ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                         audio_stream_type_t stream,
279fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent                         audio_session_t audioSession)
280ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
281ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    status_t status = NO_ERROR;
282ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    (void) output; // argument not used for now
283ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    (void) stream; // argument not used for now
284ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
2858b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    Mutex::Autolock _l(mLock);
286ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    ssize_t index = mOutputSessions.indexOfKey(audioSession);
287ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (index < 0) {
288ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream");
289ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return NO_ERROR;
290ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
291ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
292ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    EffectVector *procDesc = mOutputSessions.valueAt(index);
293890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu    procDesc->mRefCount--;
2947de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent    ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d",
2957de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent          audioSession, procDesc->mRefCount);
296890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu    if (procDesc->mRefCount == 0) {
2978b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        procDesc->setProcessorEnabled(false);
298890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu        procDesc->mEffects.clear();
299890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu        delete procDesc;
300890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu        mOutputSessions.removeItemsAt(index);
301890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu        ALOGV("releaseOutputSessionEffects(): output processing released from session: %d",
302890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu              audioSession);
303890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu    }
304ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return status;
305ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
306ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
307ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
3088b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurentvoid AudioPolicyEffects::EffectVector::setProcessorEnabled(bool enabled)
309ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
3108b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent    for (size_t i = 0; i < mEffects.size(); i++) {
3118b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent        mEffects.itemAt(i)->setEnabled(enabled);
312ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
313ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
314ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
315ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
316ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ----------------------------------------------------------------------------
317ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// Audio processing configuration
318ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ----------------------------------------------------------------------------
319ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
320ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu/*static*/ const char * const AudioPolicyEffects::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
321ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    MIC_SRC_TAG,
322ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    VOICE_UL_SRC_TAG,
323ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    VOICE_DL_SRC_TAG,
324ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    VOICE_CALL_SRC_TAG,
325ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    CAMCORDER_SRC_TAG,
326ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    VOICE_REC_SRC_TAG,
3278a397d583a4f4cf24ad88facaf2fd33990cfb811rago    VOICE_COMM_SRC_TAG,
3288a397d583a4f4cf24ad88facaf2fd33990cfb811rago    UNPROCESSED_SRC_TAG
329ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu};
330ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
331ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// returns the audio_source_t enum corresponding to the input source name or
332ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// AUDIO_SOURCE_CNT is no match found
3338b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent/*static*/ audio_source_t AudioPolicyEffects::inputSourceNameToEnum(const char *name)
334ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
335ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    int i;
336ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
337ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
338ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            ALOGV("inputSourceNameToEnum found source %s %d", name, i);
339ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            break;
340ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
341ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
342ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return (audio_source_t)i;
343ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
344ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
345223fd5c9738e9665e495904d37d4632414b68c1eEric Laurentconst char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1] = {
346ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    AUDIO_STREAM_DEFAULT_TAG,
347ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    AUDIO_STREAM_VOICE_CALL_TAG,
348ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    AUDIO_STREAM_SYSTEM_TAG,
349ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    AUDIO_STREAM_RING_TAG,
350ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    AUDIO_STREAM_MUSIC_TAG,
351ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    AUDIO_STREAM_ALARM_TAG,
352ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    AUDIO_STREAM_NOTIFICATION_TAG,
353ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    AUDIO_STREAM_BLUETOOTH_SCO_TAG,
354ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    AUDIO_STREAM_ENFORCED_AUDIBLE_TAG,
355ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    AUDIO_STREAM_DTMF_TAG,
356ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    AUDIO_STREAM_TTS_TAG
357ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu};
358ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
359ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// returns the audio_stream_t enum corresponding to the output stream name or
360223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent// AUDIO_STREAM_PUBLIC_CNT is no match found
361ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuaudio_stream_type_t AudioPolicyEffects::streamNameToEnum(const char *name)
362ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
363ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    int i;
364223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent    for (i = AUDIO_STREAM_DEFAULT; i < AUDIO_STREAM_PUBLIC_CNT; i++) {
365ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (strcmp(name, kStreamNames[i - AUDIO_STREAM_DEFAULT]) == 0) {
366ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            ALOGV("streamNameToEnum found stream %s %d", name, i);
367ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            break;
368ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
369ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
370ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return (audio_stream_type_t)i;
371ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
372ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
373ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ----------------------------------------------------------------------------
374ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// Audio Effect Config parser
375ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ----------------------------------------------------------------------------
376ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
377138ed1796f8c8edd318488911a9b056877191778Eric Laurentsize_t AudioPolicyEffects::growParamSize(char **param,
378ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                         size_t size,
379ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                         size_t *curSize,
380ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                         size_t *totSize)
381ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
382ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
383ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    size_t pos = ((*curSize - 1 ) / size + 1) * size;
384ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
385ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (pos + size > *totSize) {
386ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        while (pos + size > *totSize) {
387ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            *totSize += ((*totSize + 7) / 8) * 4;
388ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
389138ed1796f8c8edd318488911a9b056877191778Eric Laurent        *param = (char *)realloc(*param, *totSize);
390138ed1796f8c8edd318488911a9b056877191778Eric Laurent        if (*param == NULL) {
391138ed1796f8c8edd318488911a9b056877191778Eric Laurent            ALOGE("%s realloc error for size %zu", __func__, *totSize);
392138ed1796f8c8edd318488911a9b056877191778Eric Laurent            return 0;
393138ed1796f8c8edd318488911a9b056877191778Eric Laurent        }
394ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
395ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    *curSize = pos + size;
396ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return pos;
397ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
398ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
399138ed1796f8c8edd318488911a9b056877191778Eric Laurent
400ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liusize_t AudioPolicyEffects::readParamValue(cnode *node,
401138ed1796f8c8edd318488911a9b056877191778Eric Laurent                                          char **param,
402ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                          size_t *curSize,
403ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                          size_t *totSize)
404ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
405138ed1796f8c8edd318488911a9b056877191778Eric Laurent    size_t len = 0;
406138ed1796f8c8edd318488911a9b056877191778Eric Laurent    size_t pos;
407138ed1796f8c8edd318488911a9b056877191778Eric Laurent
408ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
409138ed1796f8c8edd318488911a9b056877191778Eric Laurent        pos = growParamSize(param, sizeof(short), curSize, totSize);
410138ed1796f8c8edd318488911a9b056877191778Eric Laurent        if (pos == 0) {
411138ed1796f8c8edd318488911a9b056877191778Eric Laurent            goto exit;
412138ed1796f8c8edd318488911a9b056877191778Eric Laurent        }
413138ed1796f8c8edd318488911a9b056877191778Eric Laurent        *(short *)(*param + pos) = (short)atoi(node->value);
414138ed1796f8c8edd318488911a9b056877191778Eric Laurent        ALOGV("readParamValue() reading short %d", *(short *)(*param + pos));
415138ed1796f8c8edd318488911a9b056877191778Eric Laurent        len = sizeof(short);
416ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
417138ed1796f8c8edd318488911a9b056877191778Eric Laurent        pos = growParamSize(param, sizeof(int), curSize, totSize);
418138ed1796f8c8edd318488911a9b056877191778Eric Laurent        if (pos == 0) {
419138ed1796f8c8edd318488911a9b056877191778Eric Laurent            goto exit;
420138ed1796f8c8edd318488911a9b056877191778Eric Laurent        }
421138ed1796f8c8edd318488911a9b056877191778Eric Laurent        *(int *)(*param + pos) = atoi(node->value);
422138ed1796f8c8edd318488911a9b056877191778Eric Laurent        ALOGV("readParamValue() reading int %d", *(int *)(*param + pos));
423138ed1796f8c8edd318488911a9b056877191778Eric Laurent        len = sizeof(int);
424ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
425138ed1796f8c8edd318488911a9b056877191778Eric Laurent        pos = growParamSize(param, sizeof(float), curSize, totSize);
426138ed1796f8c8edd318488911a9b056877191778Eric Laurent        if (pos == 0) {
427138ed1796f8c8edd318488911a9b056877191778Eric Laurent            goto exit;
428138ed1796f8c8edd318488911a9b056877191778Eric Laurent        }
429138ed1796f8c8edd318488911a9b056877191778Eric Laurent        *(float *)(*param + pos) = (float)atof(node->value);
430138ed1796f8c8edd318488911a9b056877191778Eric Laurent        ALOGV("readParamValue() reading float %f",*(float *)(*param + pos));
431138ed1796f8c8edd318488911a9b056877191778Eric Laurent        len = sizeof(float);
432ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
433138ed1796f8c8edd318488911a9b056877191778Eric Laurent        pos = growParamSize(param, sizeof(bool), curSize, totSize);
434138ed1796f8c8edd318488911a9b056877191778Eric Laurent        if (pos == 0) {
435138ed1796f8c8edd318488911a9b056877191778Eric Laurent            goto exit;
436138ed1796f8c8edd318488911a9b056877191778Eric Laurent        }
437138ed1796f8c8edd318488911a9b056877191778Eric Laurent        if (strncmp(node->value, "true", strlen("true") + 1) == 0) {
438138ed1796f8c8edd318488911a9b056877191778Eric Laurent            *(bool *)(*param + pos) = true;
439ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        } else {
440138ed1796f8c8edd318488911a9b056877191778Eric Laurent            *(bool *)(*param + pos) = false;
441ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
442138ed1796f8c8edd318488911a9b056877191778Eric Laurent        ALOGV("readParamValue() reading bool %s",
443138ed1796f8c8edd318488911a9b056877191778Eric Laurent              *(bool *)(*param + pos) ? "true" : "false");
444138ed1796f8c8edd318488911a9b056877191778Eric Laurent        len = sizeof(bool);
445ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
446138ed1796f8c8edd318488911a9b056877191778Eric Laurent        len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
447ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (*curSize + len + 1 > *totSize) {
448ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            *totSize = *curSize + len + 1;
449138ed1796f8c8edd318488911a9b056877191778Eric Laurent            *param = (char *)realloc(*param, *totSize);
450138ed1796f8c8edd318488911a9b056877191778Eric Laurent            if (*param == NULL) {
451138ed1796f8c8edd318488911a9b056877191778Eric Laurent                len = 0;
452138ed1796f8c8edd318488911a9b056877191778Eric Laurent                ALOGE("%s realloc error for string len %zu", __func__, *totSize);
453138ed1796f8c8edd318488911a9b056877191778Eric Laurent                goto exit;
454138ed1796f8c8edd318488911a9b056877191778Eric Laurent            }
455ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
456138ed1796f8c8edd318488911a9b056877191778Eric Laurent        strncpy(*param + *curSize, node->value, len);
457ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        *curSize += len;
458138ed1796f8c8edd318488911a9b056877191778Eric Laurent        (*param)[*curSize] = '\0';
459138ed1796f8c8edd318488911a9b056877191778Eric Laurent        ALOGV("readParamValue() reading string %s", *param + *curSize - len);
460138ed1796f8c8edd318488911a9b056877191778Eric Laurent    } else {
461138ed1796f8c8edd318488911a9b056877191778Eric Laurent        ALOGW("readParamValue() unknown param type %s", node->name);
462ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
463138ed1796f8c8edd318488911a9b056877191778Eric Laurentexit:
464138ed1796f8c8edd318488911a9b056877191778Eric Laurent    return len;
465ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
466ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
467ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liueffect_param_t *AudioPolicyEffects::loadEffectParameter(cnode *root)
468ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
469ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    cnode *param;
470ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    cnode *value;
471ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    size_t curSize = sizeof(effect_param_t);
472ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
473ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
474ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
475138ed1796f8c8edd318488911a9b056877191778Eric Laurent    if (fx_param == NULL) {
476138ed1796f8c8edd318488911a9b056877191778Eric Laurent        ALOGE("%s malloc error for effect structure of size %zu",
477138ed1796f8c8edd318488911a9b056877191778Eric Laurent              __func__, totSize);
478138ed1796f8c8edd318488911a9b056877191778Eric Laurent        return NULL;
479138ed1796f8c8edd318488911a9b056877191778Eric Laurent    }
480138ed1796f8c8edd318488911a9b056877191778Eric Laurent
481ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    param = config_find(root, PARAM_TAG);
482ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    value = config_find(root, VALUE_TAG);
483ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (param == NULL && value == NULL) {
484ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        // try to parse simple parameter form {int int}
485ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        param = root->first_child;
486ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (param != NULL) {
487ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            // Note: that a pair of random strings is read as 0 0
488ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            int *ptr = (int *)fx_param->data;
489138ed1796f8c8edd318488911a9b056877191778Eric Laurent#if LOG_NDEBUG == 0
490ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
491138ed1796f8c8edd318488911a9b056877191778Eric Laurent            ALOGV("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
492138ed1796f8c8edd318488911a9b056877191778Eric Laurent#endif
493ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            *ptr++ = atoi(param->name);
494ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            *ptr = atoi(param->value);
495ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            fx_param->psize = sizeof(int);
496ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            fx_param->vsize = sizeof(int);
497ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            return fx_param;
498ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
499ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
500ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (param == NULL || value == NULL) {
501138ed1796f8c8edd318488911a9b056877191778Eric Laurent        ALOGW("loadEffectParameter() invalid parameter description %s",
502138ed1796f8c8edd318488911a9b056877191778Eric Laurent              root->name);
503ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        goto error;
504ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
505ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
506ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    fx_param->psize = 0;
507ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    param = param->first_child;
508ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    while (param) {
509ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGV("loadEffectParameter() reading param of type %s", param->name);
510138ed1796f8c8edd318488911a9b056877191778Eric Laurent        size_t size =
511138ed1796f8c8edd318488911a9b056877191778Eric Laurent                readParamValue(param, (char **)&fx_param, &curSize, &totSize);
512ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (size == 0) {
513ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            goto error;
514ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
515ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        fx_param->psize += size;
516ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        param = param->next;
517ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
518ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
519ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    // align start of value field on 32 bit boundary
520ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
521ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
522ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    fx_param->vsize = 0;
523ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    value = value->first_child;
524ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    while (value) {
525ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGV("loadEffectParameter() reading value of type %s", value->name);
526138ed1796f8c8edd318488911a9b056877191778Eric Laurent        size_t size =
527138ed1796f8c8edd318488911a9b056877191778Eric Laurent                readParamValue(value, (char **)&fx_param, &curSize, &totSize);
528ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (size == 0) {
529ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            goto error;
530ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
531ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        fx_param->vsize += size;
532ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        value = value->next;
533ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
534ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
535ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return fx_param;
536ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
537ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuerror:
538138ed1796f8c8edd318488911a9b056877191778Eric Laurent    free(fx_param);
539ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return NULL;
540ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
541ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
542ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuvoid AudioPolicyEffects::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
543ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
544ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    cnode *node = root->first_child;
545ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    while (node) {
546ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGV("loadEffectParameters() loading param %s", node->name);
547ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        effect_param_t *param = loadEffectParameter(node);
548138ed1796f8c8edd318488911a9b056877191778Eric Laurent        if (param != NULL) {
549138ed1796f8c8edd318488911a9b056877191778Eric Laurent            params.add(param);
550ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
551ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        node = node->next;
552ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
553ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
554ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
555ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
556ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuAudioPolicyEffects::EffectDescVector *AudioPolicyEffects::loadEffectConfig(
557ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                                            cnode *root,
558ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                                            const Vector <EffectDesc *>& effects)
559ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
560ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    cnode *node = root->first_child;
561ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (node == NULL) {
562ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGW("loadInputSource() empty element %s", root->name);
563ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return NULL;
564ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
565ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    EffectDescVector *desc = new EffectDescVector();
566ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    while (node) {
567ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        size_t i;
568138ed1796f8c8edd318488911a9b056877191778Eric Laurent
569ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        for (i = 0; i < effects.size(); i++) {
570ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
571ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                ALOGV("loadEffectConfig() found effect %s in list", node->name);
572ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                break;
573ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            }
574ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
575ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (i == effects.size()) {
576ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            ALOGV("loadEffectConfig() effect %s not in list", node->name);
577ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            node = node->next;
578ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            continue;
579ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
580ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        EffectDesc *effect = new EffectDesc(*effects[i]);   // deep copy
581ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        loadEffectParameters(node, effect->mParams);
582ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGV("loadEffectConfig() adding effect %s uuid %08x",
583ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu              effect->mName, effect->mUuid.timeLow);
584ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        desc->mEffects.add(effect);
585ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        node = node->next;
586ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
587ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (desc->mEffects.size() == 0) {
588ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGW("loadEffectConfig() no valid effects found in config %s", root->name);
589ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        delete desc;
590ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return NULL;
591ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
592ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return desc;
593ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
594ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
595ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadInputEffectConfigurations(cnode *root,
596ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                                           const Vector <EffectDesc *>& effects)
597ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
598ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    cnode *node = config_find(root, PREPROCESSING_TAG);
599ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (node == NULL) {
600ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return -ENOENT;
601ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
602ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    node = node->first_child;
603ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    while (node) {
604ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        audio_source_t source = inputSourceNameToEnum(node->name);
605ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (source == AUDIO_SOURCE_CNT) {
606ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            ALOGW("loadInputSources() invalid input source %s", node->name);
607ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            node = node->next;
608ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            continue;
609ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
610ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGV("loadInputSources() loading input source %s", node->name);
611ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        EffectDescVector *desc = loadEffectConfig(node, effects);
612ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (desc == NULL) {
613ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            node = node->next;
614ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            continue;
615ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
616ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        mInputSources.add(source, desc);
617ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        node = node->next;
618ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
619ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return NO_ERROR;
620ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
621ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
622ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadStreamEffectConfigurations(cnode *root,
623ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu                                                            const Vector <EffectDesc *>& effects)
624ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
625ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    cnode *node = config_find(root, OUTPUT_SESSION_PROCESSING_TAG);
626ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (node == NULL) {
627ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return -ENOENT;
628ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
629ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    node = node->first_child;
630ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    while (node) {
631ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        audio_stream_type_t stream = streamNameToEnum(node->name);
632223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent        if (stream == AUDIO_STREAM_PUBLIC_CNT) {
633ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            ALOGW("loadStreamEffectConfigurations() invalid output stream %s", node->name);
634ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            node = node->next;
635ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            continue;
636ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
637ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGV("loadStreamEffectConfigurations() loading output stream %s", node->name);
638ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        EffectDescVector *desc = loadEffectConfig(node, effects);
639ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (desc == NULL) {
640ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            node = node->next;
641ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            continue;
642ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
643ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        mOutputStreams.add(stream, desc);
644ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        node = node->next;
645ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
646ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return NO_ERROR;
647ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
648ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
649ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuAudioPolicyEffects::EffectDesc *AudioPolicyEffects::loadEffect(cnode *root)
650ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
651ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    cnode *node = config_find(root, UUID_TAG);
652ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (node == NULL) {
653ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return NULL;
654ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
655ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    effect_uuid_t uuid;
656ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
657ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGW("loadEffect() invalid uuid %s", node->value);
658ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return NULL;
659ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
660ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return new EffectDesc(root->name, uuid);
661ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
662ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
663ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
664ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
665ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    cnode *node = config_find(root, EFFECTS_TAG);
666ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (node == NULL) {
667ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return -ENOENT;
668ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
669ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    node = node->first_child;
670ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    while (node) {
671ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        ALOGV("loadEffects() loading effect %s", node->name);
672ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        EffectDesc *effect = loadEffect(node);
673ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        if (effect == NULL) {
674ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            node = node->next;
675ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu            continue;
676ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        }
677ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        effects.add(effect);
678ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        node = node->next;
679ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
680ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return NO_ERROR;
681ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
682ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
683ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadAudioEffectConfig(const char *path)
684ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{
685ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    cnode *root;
686ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    char *data;
687ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
688ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    data = (char *)load_file(path, NULL);
689ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    if (data == NULL) {
690ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu        return -ENODEV;
691ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    }
692ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    root = config_node("", "");
693ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    config_load(root, data);
694ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
695ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    Vector <EffectDesc *> effects;
696ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    loadEffects(root, effects);
697ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    loadInputEffectConfigurations(root, effects);
698ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    loadStreamEffectConfigurations(root, effects);
699ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
700182c2f5e48f46c11dbcb5eecb46268dff4ad4797Eric Laurent    for (size_t i = 0; i < effects.size(); i++) {
701182c2f5e48f46c11dbcb5eecb46268dff4ad4797Eric Laurent        delete effects[i];
702182c2f5e48f46c11dbcb5eecb46268dff4ad4797Eric Laurent    }
703182c2f5e48f46c11dbcb5eecb46268dff4ad4797Eric Laurent
704ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    config_free(root);
705ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    free(root);
706ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    free(data);
707ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
708ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu    return NO_ERROR;
709ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}
710ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
711ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu
712ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}; // namespace android
713