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