AudioPolicyEffects.cpp revision 897a408b3f9c893776d67214257ca6a6bc1751bd
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 60ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (i = 0; i < mInputs.size(); i++) { 61ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mInputs.valueAt(i)->mEffects.clear(); 62ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu delete mInputs.valueAt(i); 63ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 64ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mInputs.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, 82ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu int 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 90ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ssize_t index = mInputSources.indexOfKey(aliasSource); 91ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (index < 0) { 92ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("addInputEffects(): no processing needs to be attached to this source"); 93ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 94ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 95ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ssize_t idx = mInputs.indexOfKey(input); 96ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectVector *inputDesc; 97ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (idx < 0) { 98ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu inputDesc = new EffectVector(audioSession); 99ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mInputs.add(input, inputDesc); 100ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else { 101ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu inputDesc = mInputs.valueAt(idx); 102ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 103ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 104ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects; 105ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (size_t i = 0; i < effects.size(); i++) { 106ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDesc *effect = effects[i]; 107ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input); 108ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = fx->initCheck(); 109ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (status != NO_ERROR && status != ALREADY_EXISTS) { 110ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("addInputEffects(): failed to create Fx %s on source %d", 111ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect->mName, (int32_t)aliasSource); 112ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // fx goes out of scope and strong ref on AudioEffect is released 113ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 114ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 115ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (size_t j = 0; j < effect->mParams.size(); j++) { 116ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx->setParameter(effect->mParams[j]); 117ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 118ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("addInputEffects(): added Fx %s on source: %d", effect->mName, (int32_t)aliasSource); 119ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu inputDesc->mEffects.add(fx); 120ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 121ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu setProcessorEnabled(inputDesc, true); 122ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 123ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 124ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 125ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 126ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 127ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::releaseInputEffects(audio_io_handle_t input) 128ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 129ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = NO_ERROR; 130ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 131ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ssize_t index = mInputs.indexOfKey(input); 132ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (index < 0) { 133ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 134ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 135ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectVector *inputDesc = mInputs.valueAt(index); 136ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu setProcessorEnabled(inputDesc, false); 137ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu delete inputDesc; 138ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mInputs.removeItemsAt(index); 139ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("releaseInputEffects(): all effects released"); 140ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 141ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 142ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 143ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::queryDefaultInputEffects(int audioSession, 144ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_descriptor_t *descriptors, 145ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu uint32_t *count) 146ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 147ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = NO_ERROR; 148ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 149ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t index; 150ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (index = 0; index < mInputs.size(); index++) { 151ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (mInputs.valueAt(index)->mSessionId == audioSession) { 152ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu break; 153ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 154ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 155ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (index == mInputs.size()) { 156ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *count = 0; 157ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return BAD_VALUE; 158ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 159ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects; 160ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 161ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (size_t i = 0; i < effects.size(); i++) { 162ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_descriptor_t desc = effects[i]->descriptor(); 163ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (i < *count) { 164ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu descriptors[i] = desc; 165ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 166ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 167ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (effects.size() > *count) { 168ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status = NO_MEMORY; 169ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 170ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *count = effects.size(); 171ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 172ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 173ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 174ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 175ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::queryDefaultOutputSessionEffects(int audioSession, 176ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_descriptor_t *descriptors, 177ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu uint32_t *count) 178ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 179ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = NO_ERROR; 180ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 181ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t index; 182ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (index = 0; index < mOutputSessions.size(); index++) { 183ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (mOutputSessions.valueAt(index)->mSessionId == audioSession) { 184ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu break; 185ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 186ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 187ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (index == mOutputSessions.size()) { 188ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *count = 0; 189ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return BAD_VALUE; 190ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 191ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu Vector< sp<AudioEffect> > effects = mOutputSessions.valueAt(index)->mEffects; 192ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 193ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (size_t i = 0; i < effects.size(); i++) { 194ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_descriptor_t desc = effects[i]->descriptor(); 195ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (i < *count) { 196ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu descriptors[i] = desc; 197ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 198ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 199ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (effects.size() > *count) { 200ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status = NO_MEMORY; 201ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 202ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *count = effects.size(); 203ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 204ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 205ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 206ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 207ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, 208ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu audio_stream_type_t stream, 209ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu int audioSession) 210ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 211ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = NO_ERROR; 212ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 213ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // create audio processors according to stream 214ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ssize_t index = mOutputStreams.indexOfKey(stream); 215ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (index < 0) { 216ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("addOutputSessionEffects(): no output processing needed for this stream"); 217ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 218ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 219ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 220ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ssize_t idx = mOutputSessions.indexOfKey(audioSession); 221ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectVector *procDesc; 222ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (idx < 0) { 223ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu procDesc = new EffectVector(audioSession); 224ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mOutputSessions.add(audioSession, procDesc); 225ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else { 226ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu procDesc = mOutputSessions.valueAt(idx); 227ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 228ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 229ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects; 230ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (size_t i = 0; i < effects.size(); i++) { 231ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDesc *effect = effects[i]; 232ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, 0, 0, 0, audioSession, output); 233ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = fx->initCheck(); 234ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (status != NO_ERROR && status != ALREADY_EXISTS) { 235ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGE("addOutputSessionEffects(): failed to create Fx %s on session %d", 236ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect->mName, audioSession); 237ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // fx goes out of scope and strong ref on AudioEffect is released 238ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 239ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 240ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("addOutputSessionEffects(): added Fx %s on session: %d for stream: %d", 241ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect->mName, audioSession, (int32_t)stream); 242ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu procDesc->mEffects.add(fx); 243ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 244ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 245ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu setProcessorEnabled(procDesc, true); 246ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 247ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 248ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 249ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 250ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output, 251ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu audio_stream_type_t stream, 252ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu int audioSession) 253ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 254ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = NO_ERROR; 255ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu (void) output; // argument not used for now 256ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu (void) stream; // argument not used for now 257ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 258ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ssize_t index = mOutputSessions.indexOfKey(audioSession); 259ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (index < 0) { 260ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream"); 261ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 262ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 263ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 264ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectVector *procDesc = mOutputSessions.valueAt(index); 265ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu setProcessorEnabled(procDesc, false); 266ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu procDesc->mEffects.clear(); 267ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu delete procDesc; 268ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mOutputSessions.removeItemsAt(index); 269ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("releaseOutputSessionEffects(): output processing released from session: %d", 270ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu audioSession); 271ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 272ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 273ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 274ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 275ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuvoid AudioPolicyEffects::setProcessorEnabled(const EffectVector *effectVector, bool enabled) 276ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 277ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu const Vector<sp<AudioEffect> > &fxVector = effectVector->mEffects; 278ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (size_t i = 0; i < fxVector.size(); i++) { 279ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fxVector.itemAt(i)->setEnabled(enabled); 280ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 281ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 282ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 283ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 284ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ---------------------------------------------------------------------------- 285ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// Audio processing configuration 286ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ---------------------------------------------------------------------------- 287ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 288ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu/*static*/ const char * const AudioPolicyEffects::kInputSourceNames[AUDIO_SOURCE_CNT -1] = { 289ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu MIC_SRC_TAG, 290ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu VOICE_UL_SRC_TAG, 291ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu VOICE_DL_SRC_TAG, 292ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu VOICE_CALL_SRC_TAG, 293ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu CAMCORDER_SRC_TAG, 294ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu VOICE_REC_SRC_TAG, 295ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu VOICE_COMM_SRC_TAG 296ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}; 297ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 298ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// returns the audio_source_t enum corresponding to the input source name or 299ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// AUDIO_SOURCE_CNT is no match found 300ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuaudio_source_t AudioPolicyEffects::inputSourceNameToEnum(const char *name) 301ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 302ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu int i; 303ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) { 304ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) { 305ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("inputSourceNameToEnum found source %s %d", name, i); 306ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu break; 307ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 308ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 309ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return (audio_source_t)i; 310ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 311ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 312ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuconst char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_CNT+1] = { 313ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_DEFAULT_TAG, 314ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_VOICE_CALL_TAG, 315ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_SYSTEM_TAG, 316ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_RING_TAG, 317ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_MUSIC_TAG, 318ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_ALARM_TAG, 319ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_NOTIFICATION_TAG, 320ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_BLUETOOTH_SCO_TAG, 321ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_ENFORCED_AUDIBLE_TAG, 322ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_DTMF_TAG, 323ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_TTS_TAG 324ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}; 325ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 326ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// returns the audio_stream_t enum corresponding to the output stream name or 327ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// AUDIO_STREAM_CNT is no match found 328ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuaudio_stream_type_t AudioPolicyEffects::streamNameToEnum(const char *name) 329ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 330ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu int i; 331ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (i = AUDIO_STREAM_DEFAULT; i < AUDIO_STREAM_CNT; i++) { 332ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (strcmp(name, kStreamNames[i - AUDIO_STREAM_DEFAULT]) == 0) { 333ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("streamNameToEnum found stream %s %d", name, i); 334ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu break; 335ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 336ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 337ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return (audio_stream_type_t)i; 338ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 339ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 340ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ---------------------------------------------------------------------------- 341ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// Audio Effect Config parser 342ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ---------------------------------------------------------------------------- 343ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 344ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liusize_t AudioPolicyEffects::growParamSize(char *param, 345ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t size, 346ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t *curSize, 347ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t *totSize) 348ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 349ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int) 350ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t pos = ((*curSize - 1 ) / size + 1) * size; 351ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 352ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (pos + size > *totSize) { 353ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (pos + size > *totSize) { 354ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *totSize += ((*totSize + 7) / 8) * 4; 355ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 356ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu param = (char *)realloc(param, *totSize); 357ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 358ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *curSize = pos + size; 359ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return pos; 360ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 361ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 362ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liusize_t AudioPolicyEffects::readParamValue(cnode *node, 363ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu char *param, 364ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t *curSize, 365ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t *totSize) 366ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 367ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) { 368ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t pos = growParamSize(param, sizeof(short), curSize, totSize); 369ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *(short *)((char *)param + pos) = (short)atoi(node->value); 370ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("readParamValue() reading short %d", *(short *)((char *)param + pos)); 371ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return sizeof(short); 372ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) { 373ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t pos = growParamSize(param, sizeof(int), curSize, totSize); 374ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *(int *)((char *)param + pos) = atoi(node->value); 375ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("readParamValue() reading int %d", *(int *)((char *)param + pos)); 376ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return sizeof(int); 377ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) { 378ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t pos = growParamSize(param, sizeof(float), curSize, totSize); 379ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *(float *)((char *)param + pos) = (float)atof(node->value); 380ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("readParamValue() reading float %f",*(float *)((char *)param + pos)); 381ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return sizeof(float); 382ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) { 383ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t pos = growParamSize(param, sizeof(bool), curSize, totSize); 384ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (strncmp(node->value, "false", strlen("false") + 1) == 0) { 385ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *(bool *)((char *)param + pos) = false; 386ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else { 387ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *(bool *)((char *)param + pos) = true; 388ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 389ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("readParamValue() reading bool %s",*(bool *)((char *)param + pos) ? "true" : "false"); 390ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return sizeof(bool); 391ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) { 392ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t len = strnlen(node->value, EFFECT_STRING_LEN_MAX); 393ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (*curSize + len + 1 > *totSize) { 394ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *totSize = *curSize + len + 1; 395ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu param = (char *)realloc(param, *totSize); 396ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 397ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu strncpy(param + *curSize, node->value, len); 398ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *curSize += len; 399ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu param[*curSize] = '\0'; 400ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("readParamValue() reading string %s", param + *curSize - len); 401ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return len; 402ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 403ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("readParamValue() unknown param type %s", node->name); 404ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return 0; 405ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 406ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 407ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liueffect_param_t *AudioPolicyEffects::loadEffectParameter(cnode *root) 408ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 409ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *param; 410ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *value; 411ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t curSize = sizeof(effect_param_t); 412ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int); 413ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_param_t *fx_param = (effect_param_t *)malloc(totSize); 414ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 415ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu param = config_find(root, PARAM_TAG); 416ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu value = config_find(root, VALUE_TAG); 417ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (param == NULL && value == NULL) { 418ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // try to parse simple parameter form {int int} 419ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu param = root->first_child; 420ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (param != NULL) { 421ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // Note: that a pair of random strings is read as 0 0 422ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu int *ptr = (int *)fx_param->data; 423ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu int *ptr2 = (int *)((char *)param + sizeof(effect_param_t)); 424ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2); 425ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *ptr++ = atoi(param->name); 426ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *ptr = atoi(param->value); 427ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->psize = sizeof(int); 428ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->vsize = sizeof(int); 429ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return fx_param; 430ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 431ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 432ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (param == NULL || value == NULL) { 433ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadEffectParameter() invalid parameter description %s", root->name); 434ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu goto error; 435ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 436ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 437ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->psize = 0; 438ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu param = param->first_child; 439ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (param) { 440ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectParameter() reading param of type %s", param->name); 441ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t size = readParamValue(param, (char *)fx_param, &curSize, &totSize); 442ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (size == 0) { 443ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu goto error; 444ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 445ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->psize += size; 446ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu param = param->next; 447ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 448ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 449ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // align start of value field on 32 bit boundary 450ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int); 451ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 452ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->vsize = 0; 453ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu value = value->first_child; 454ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (value) { 455ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectParameter() reading value of type %s", value->name); 456ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t size = readParamValue(value, (char *)fx_param, &curSize, &totSize); 457ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (size == 0) { 458ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu goto error; 459ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 460ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->vsize += size; 461ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu value = value->next; 462ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 463ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 464ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return fx_param; 465ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 466ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuerror: 467ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu delete fx_param; 468ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NULL; 469ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 470ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 471ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuvoid AudioPolicyEffects::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params) 472ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 473ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = root->first_child; 474ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (node) { 475ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectParameters() loading param %s", node->name); 476ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_param_t *param = loadEffectParameter(node); 477ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (param == NULL) { 478ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 479ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 480ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 481ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu params.add(param); 482ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 483ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 484ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 485ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 486ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 487ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuAudioPolicyEffects::EffectDescVector *AudioPolicyEffects::loadEffectConfig( 488ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *root, 489ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu const Vector <EffectDesc *>& effects) 490ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 491ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = root->first_child; 492ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (node == NULL) { 493ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadInputSource() empty element %s", root->name); 494ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NULL; 495ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 496ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDescVector *desc = new EffectDescVector(); 497ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (node) { 498ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t i; 499ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (i = 0; i < effects.size(); i++) { 500ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) { 501ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectConfig() found effect %s in list", node->name); 502ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu break; 503ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 504ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 505ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (i == effects.size()) { 506ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectConfig() effect %s not in list", node->name); 507ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 508ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 509ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 510ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDesc *effect = new EffectDesc(*effects[i]); // deep copy 511ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu loadEffectParameters(node, effect->mParams); 512ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectConfig() adding effect %s uuid %08x", 513ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect->mName, effect->mUuid.timeLow); 514ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu desc->mEffects.add(effect); 515ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 516ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 517ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (desc->mEffects.size() == 0) { 518ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadEffectConfig() no valid effects found in config %s", root->name); 519ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu delete desc; 520ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NULL; 521ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 522ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return desc; 523ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 524ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 525ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadInputEffectConfigurations(cnode *root, 526ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu const Vector <EffectDesc *>& effects) 527ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 528ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = config_find(root, PREPROCESSING_TAG); 529ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (node == NULL) { 530ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return -ENOENT; 531ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 532ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->first_child; 533ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (node) { 534ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu audio_source_t source = inputSourceNameToEnum(node->name); 535ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (source == AUDIO_SOURCE_CNT) { 536ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadInputSources() invalid input source %s", node->name); 537ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 538ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 539ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 540ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadInputSources() loading input source %s", node->name); 541ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDescVector *desc = loadEffectConfig(node, effects); 542ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (desc == NULL) { 543ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 544ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 545ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 546ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mInputSources.add(source, desc); 547ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 548ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 549ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 550ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 551ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 552ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadStreamEffectConfigurations(cnode *root, 553ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu const Vector <EffectDesc *>& effects) 554ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 555ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = config_find(root, OUTPUT_SESSION_PROCESSING_TAG); 556ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (node == NULL) { 557ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return -ENOENT; 558ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 559ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->first_child; 560ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (node) { 561ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu audio_stream_type_t stream = streamNameToEnum(node->name); 562ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (stream == AUDIO_STREAM_CNT) { 563ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadStreamEffectConfigurations() invalid output stream %s", node->name); 564ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 565ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 566ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 567ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadStreamEffectConfigurations() loading output stream %s", node->name); 568ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDescVector *desc = loadEffectConfig(node, effects); 569ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (desc == NULL) { 570ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 571ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 572ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 573ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mOutputStreams.add(stream, desc); 574ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 575ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 576ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 577ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 578ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 579ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuAudioPolicyEffects::EffectDesc *AudioPolicyEffects::loadEffect(cnode *root) 580ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 581ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = config_find(root, UUID_TAG); 582ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (node == NULL) { 583ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NULL; 584ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 585ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_uuid_t uuid; 586ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) { 587ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadEffect() invalid uuid %s", node->value); 588ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NULL; 589ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 590ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return new EffectDesc(root->name, uuid); 591ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 592ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 593ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadEffects(cnode *root, Vector <EffectDesc *>& effects) 594ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 595ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = config_find(root, EFFECTS_TAG); 596ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (node == NULL) { 597ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return -ENOENT; 598ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 599ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->first_child; 600ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (node) { 601ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffects() loading effect %s", node->name); 602ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDesc *effect = loadEffect(node); 603ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (effect == NULL) { 604ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 605ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 606ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 607ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effects.add(effect); 608ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 609ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 610ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 611ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 612ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 613ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadAudioEffectConfig(const char *path) 614ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 615ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *root; 616ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu char *data; 617ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 618ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu data = (char *)load_file(path, NULL); 619ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (data == NULL) { 620ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return -ENODEV; 621ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 622ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu root = config_node("", ""); 623ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu config_load(root, data); 624ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 625ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu Vector <EffectDesc *> effects; 626ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu loadEffects(root, effects); 627ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu loadInputEffectConfigurations(root, effects); 628ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu loadStreamEffectConfigurations(root, effects); 629ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 630ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu config_free(root); 631ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu free(root); 632ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu free(data); 633ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 634ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 635ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 636ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 637ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 638ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}; // namespace android 639