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> 234fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard#include <memory> 24ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <cutils/misc.h> 25ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <media/AudioEffect.h> 264fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard#include <media/EffectsConfig.h> 27ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <system/audio.h> 28c2f710f89ec1a3ea8e448bfafcc02b03529cc681Mikhail Naganov#include <system/audio_effects/audio_effects_conf.h> 29ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <utils/Vector.h> 30ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <utils/SortedVector.h> 31ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include <cutils/config_utils.h> 32b643627a557e44b9ab5879cf71e162af2d514ce3Eric Laurent#include <binder/IPCThreadState.h> 33ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include "AudioPolicyEffects.h" 34ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu#include "ServiceUtilities.h" 35ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 36ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liunamespace android { 37ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 38ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ---------------------------------------------------------------------------- 39ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// AudioPolicyEffects Implementation 40ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ---------------------------------------------------------------------------- 41ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 42ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuAudioPolicyEffects::AudioPolicyEffects() 43ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 444fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard status_t loadResult = loadAudioEffectXmlConfig(); 454fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard if (loadResult < 0) { 464fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard ALOGW("Failed to load XML effect configuration, fallback to .conf"); 474fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard // load automatic audio effect modules 484fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) { 494fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard loadAudioEffectConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE); 504fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) { 514fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard loadAudioEffectConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE); 524fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard } 534fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard } else if (loadResult > 0) { 544fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard ALOGE("Effect config is partially invalid, skipped %d elements", loadResult); 55ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 56ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 57ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 58ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 59ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuAudioPolicyEffects::~AudioPolicyEffects() 60ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 61ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t i = 0; 62ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // release audio input processing resources 63ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (i = 0; i < mInputSources.size(); i++) { 64ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu delete mInputSources.valueAt(i); 65ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 66ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mInputSources.clear(); 67ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 68fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent for (i = 0; i < mInputSessions.size(); i++) { 69fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent mInputSessions.valueAt(i)->mEffects.clear(); 70fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent delete mInputSessions.valueAt(i); 71ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 72fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent mInputSessions.clear(); 73ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 74ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // release audio output processing resources 75ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (i = 0; i < mOutputStreams.size(); i++) { 76ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu delete mOutputStreams.valueAt(i); 77ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 78ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mOutputStreams.clear(); 79ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 80ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (i = 0; i < mOutputSessions.size(); i++) { 81ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mOutputSessions.valueAt(i)->mEffects.clear(); 82ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu delete mOutputSessions.valueAt(i); 83ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 84ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mOutputSessions.clear(); 85ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 86ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 87ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 88ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::addInputEffects(audio_io_handle_t input, 89ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu audio_source_t inputSource, 90fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent audio_session_t audioSession) 91ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 92ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = NO_ERROR; 93ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 94ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // create audio pre processors according to input source 95ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu audio_source_t aliasSource = (inputSource == AUDIO_SOURCE_HOTWORD) ? 96ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_SOURCE_VOICE_RECOGNITION : inputSource; 97ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 988b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 99ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ssize_t index = mInputSources.indexOfKey(aliasSource); 100ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (index < 0) { 101ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("addInputEffects(): no processing needs to be attached to this source"); 102ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 103ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 104fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent ssize_t idx = mInputSessions.indexOfKey(audioSession); 105fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent EffectVector *sessionDesc; 106ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (idx < 0) { 107fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent sessionDesc = new EffectVector(audioSession); 108fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent mInputSessions.add(audioSession, sessionDesc); 109ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else { 110890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu // EffectVector is existing and we just need to increase ref count 111fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent sessionDesc = mInputSessions.valueAt(idx); 112ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 113fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent sessionDesc->mRefCount++; 114890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu 115fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent ALOGV("addInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount); 116fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent if (sessionDesc->mRefCount == 1) { 117b643627a557e44b9ab5879cf71e162af2d514ce3Eric Laurent int64_t token = IPCThreadState::self()->clearCallingIdentity(); 1187de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects; 1197de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent for (size_t i = 0; i < effects.size(); i++) { 1207de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent EffectDesc *effect = effects[i]; 121be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, -1, 0, 122be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov 0, audioSession, input); 1237de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent status_t status = fx->initCheck(); 1247de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent if (status != NO_ERROR && status != ALREADY_EXISTS) { 1257de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent ALOGW("addInputEffects(): failed to create Fx %s on source %d", 1267de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent effect->mName, (int32_t)aliasSource); 1277de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent // fx goes out of scope and strong ref on AudioEffect is released 1287de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent continue; 1297de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent } 1307de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent for (size_t j = 0; j < effect->mParams.size(); j++) { 1317de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent fx->setParameter(effect->mParams[j]); 1327de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent } 1337de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent ALOGV("addInputEffects(): added Fx %s on source: %d", 134ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect->mName, (int32_t)aliasSource); 135fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent sessionDesc->mEffects.add(fx); 136ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 137fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent sessionDesc->setProcessorEnabled(true); 138b643627a557e44b9ab5879cf71e162af2d514ce3Eric Laurent IPCThreadState::self()->restoreCallingIdentity(token); 139ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 140ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 141ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 142ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 143ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 144fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentstatus_t AudioPolicyEffects::releaseInputEffects(audio_io_handle_t input, 145fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent audio_session_t audioSession) 146ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 147ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = NO_ERROR; 148ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 1498b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 150fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent ssize_t index = mInputSessions.indexOfKey(audioSession); 151ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (index < 0) { 152ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 153ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 154fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent EffectVector *sessionDesc = mInputSessions.valueAt(index); 155fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent sessionDesc->mRefCount--; 156fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent ALOGV("releaseInputEffects(): input: %d, refCount: %d", input, sessionDesc->mRefCount); 157fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent if (sessionDesc->mRefCount == 0) { 158fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent sessionDesc->setProcessorEnabled(false); 159fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent delete sessionDesc; 160fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent mInputSessions.removeItemsAt(index); 161890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu ALOGV("releaseInputEffects(): all effects released"); 162890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu } 163ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 164ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 165ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 166fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentstatus_t AudioPolicyEffects::queryDefaultInputEffects(audio_session_t audioSession, 167ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_descriptor_t *descriptors, 168ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu uint32_t *count) 169ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 170ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = NO_ERROR; 171ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 1728b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 173ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t index; 174fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent for (index = 0; index < mInputSessions.size(); index++) { 175fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent if (mInputSessions.valueAt(index)->mSessionId == audioSession) { 176ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu break; 177ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 178ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 179fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent if (index == mInputSessions.size()) { 180ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *count = 0; 181ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return BAD_VALUE; 182ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 183fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent Vector< sp<AudioEffect> > effects = mInputSessions.valueAt(index)->mEffects; 184ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 185ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (size_t i = 0; i < effects.size(); i++) { 186ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_descriptor_t desc = effects[i]->descriptor(); 187ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (i < *count) { 188ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu descriptors[i] = desc; 189ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 190ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 191ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (effects.size() > *count) { 192ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status = NO_MEMORY; 193ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 194ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *count = effects.size(); 195ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 196ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 197ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 198ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 199fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurentstatus_t AudioPolicyEffects::queryDefaultOutputSessionEffects(audio_session_t audioSession, 200ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_descriptor_t *descriptors, 201ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu uint32_t *count) 202ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 203ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = NO_ERROR; 204ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 2058b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 206ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t index; 207ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (index = 0; index < mOutputSessions.size(); index++) { 208ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (mOutputSessions.valueAt(index)->mSessionId == audioSession) { 209ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu break; 210ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 211ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 212ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (index == mOutputSessions.size()) { 213ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *count = 0; 214ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return BAD_VALUE; 215ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 216ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu Vector< sp<AudioEffect> > effects = mOutputSessions.valueAt(index)->mEffects; 217ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 218ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (size_t i = 0; i < effects.size(); i++) { 219ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_descriptor_t desc = effects[i]->descriptor(); 220ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (i < *count) { 221ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu descriptors[i] = desc; 222ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 223ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 224ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (effects.size() > *count) { 225ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status = NO_MEMORY; 226ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 227ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *count = effects.size(); 228ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 229ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 230ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 231ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 232ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::addOutputSessionEffects(audio_io_handle_t output, 233ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu audio_stream_type_t stream, 234fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent audio_session_t audioSession) 235ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 236ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = NO_ERROR; 237ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 2388b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 239ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // create audio processors according to stream 240223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent // FIXME: should we have specific post processing settings for internal streams? 241223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent // default to media for now. 242223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if (stream >= AUDIO_STREAM_PUBLIC_CNT) { 243223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent stream = AUDIO_STREAM_MUSIC; 244223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent } 245ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ssize_t index = mOutputStreams.indexOfKey(stream); 246ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (index < 0) { 247ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("addOutputSessionEffects(): no output processing needed for this stream"); 248ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 249ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 250ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 251ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ssize_t idx = mOutputSessions.indexOfKey(audioSession); 252ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectVector *procDesc; 253ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (idx < 0) { 254ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu procDesc = new EffectVector(audioSession); 255ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mOutputSessions.add(audioSession, procDesc); 256ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else { 257890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu // EffectVector is existing and we just need to increase ref count 258ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu procDesc = mOutputSessions.valueAt(idx); 259ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 260890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu procDesc->mRefCount++; 261890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu 2627de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent ALOGV("addOutputSessionEffects(): session: %d, refCount: %d", 2637de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent audioSession, procDesc->mRefCount); 2647de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent if (procDesc->mRefCount == 1) { 265b643627a557e44b9ab5879cf71e162af2d514ce3Eric Laurent // make sure effects are associated to audio server even if we are executing a binder call 266b643627a557e44b9ab5879cf71e162af2d514ce3Eric Laurent int64_t token = IPCThreadState::self()->clearCallingIdentity(); 2677de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent Vector <EffectDesc *> effects = mOutputStreams.valueAt(index)->mEffects; 2687de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent for (size_t i = 0; i < effects.size(); i++) { 2697de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent EffectDesc *effect = effects[i]; 270be71aa29a3c86d2e01cd17839d2a72ab09a1bce5Svet Ganov sp<AudioEffect> fx = new AudioEffect(NULL, String16("android"), &effect->mUuid, 0, 0, 0, 2717de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent audioSession, output); 2727de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent status_t status = fx->initCheck(); 2737de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent if (status != NO_ERROR && status != ALREADY_EXISTS) { 2747de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent ALOGE("addOutputSessionEffects(): failed to create Fx %s on session %d", 2757de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent effect->mName, audioSession); 2767de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent // fx goes out of scope and strong ref on AudioEffect is released 2777de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent continue; 2787de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent } 2797de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent ALOGV("addOutputSessionEffects(): added Fx %s on session: %d for stream: %d", 2807de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent effect->mName, audioSession, (int32_t)stream); 2817de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent procDesc->mEffects.add(fx); 282ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 283ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 2847de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent procDesc->setProcessorEnabled(true); 285b643627a557e44b9ab5879cf71e162af2d514ce3Eric Laurent IPCThreadState::self()->restoreCallingIdentity(token); 2867de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent } 287ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 288ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 289ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 290ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::releaseOutputSessionEffects(audio_io_handle_t output, 291ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu audio_stream_type_t stream, 292fb66dd9f95a1168698f072c4e5c2a2cf8c49a80fEric Laurent audio_session_t audioSession) 293ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 294ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu status_t status = NO_ERROR; 295ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu (void) output; // argument not used for now 296ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu (void) stream; // argument not used for now 297ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 2988b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent Mutex::Autolock _l(mLock); 299ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ssize_t index = mOutputSessions.indexOfKey(audioSession); 300ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (index < 0) { 301ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("releaseOutputSessionEffects: no output processing was attached to this stream"); 302ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 303ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 304ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 305ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectVector *procDesc = mOutputSessions.valueAt(index); 306890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu procDesc->mRefCount--; 3077de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent ALOGV("releaseOutputSessionEffects(): session: %d, refCount: %d", 3087de5ac1f067ec61f7ea424d5534cfd40987b11faEric Laurent audioSession, procDesc->mRefCount); 309890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu if (procDesc->mRefCount == 0) { 3108b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent procDesc->setProcessorEnabled(false); 311890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu procDesc->mEffects.clear(); 312890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu delete procDesc; 313890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu mOutputSessions.removeItemsAt(index); 314890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu ALOGV("releaseOutputSessionEffects(): output processing released from session: %d", 315890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu audioSession); 316890a5637b3e3eb197fd2c7f5deec816c7feb13fcbryant_liu } 317ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return status; 318ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 319ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 320ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 3218b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurentvoid AudioPolicyEffects::EffectVector::setProcessorEnabled(bool enabled) 322ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 3238b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent for (size_t i = 0; i < mEffects.size(); i++) { 3248b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent mEffects.itemAt(i)->setEnabled(enabled); 325ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 326ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 327ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 328ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 329ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ---------------------------------------------------------------------------- 330ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// Audio processing configuration 331ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ---------------------------------------------------------------------------- 332ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 333ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu/*static*/ const char * const AudioPolicyEffects::kInputSourceNames[AUDIO_SOURCE_CNT -1] = { 334ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu MIC_SRC_TAG, 335ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu VOICE_UL_SRC_TAG, 336ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu VOICE_DL_SRC_TAG, 337ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu VOICE_CALL_SRC_TAG, 338ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu CAMCORDER_SRC_TAG, 339ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu VOICE_REC_SRC_TAG, 3408a397d583a4f4cf24ad88facaf2fd33990cfb811rago VOICE_COMM_SRC_TAG, 3418a397d583a4f4cf24ad88facaf2fd33990cfb811rago UNPROCESSED_SRC_TAG 342ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}; 343ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 344ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// returns the audio_source_t enum corresponding to the input source name or 345ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// AUDIO_SOURCE_CNT is no match found 3468b1e80bf1e9f214feea219cfe981ba533b806003Eric Laurent/*static*/ audio_source_t AudioPolicyEffects::inputSourceNameToEnum(const char *name) 347ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 348ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu int i; 349ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) { 350ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) { 351ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("inputSourceNameToEnum found source %s %d", name, i); 352ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu break; 353ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 354ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 355ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return (audio_source_t)i; 356ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 357ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 358223fd5c9738e9665e495904d37d4632414b68c1eEric Laurentconst char *AudioPolicyEffects::kStreamNames[AUDIO_STREAM_PUBLIC_CNT+1] = { 359ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_DEFAULT_TAG, 360ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_VOICE_CALL_TAG, 361ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_SYSTEM_TAG, 362ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_RING_TAG, 363ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_MUSIC_TAG, 364ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_ALARM_TAG, 365ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_NOTIFICATION_TAG, 366ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_BLUETOOTH_SCO_TAG, 367ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_ENFORCED_AUDIBLE_TAG, 368ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_DTMF_TAG, 369ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu AUDIO_STREAM_TTS_TAG 370ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu}; 371ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 372ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// returns the audio_stream_t enum corresponding to the output stream name or 373223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent// AUDIO_STREAM_PUBLIC_CNT is no match found 374ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuaudio_stream_type_t AudioPolicyEffects::streamNameToEnum(const char *name) 375ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 376ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu int i; 377223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent for (i = AUDIO_STREAM_DEFAULT; i < AUDIO_STREAM_PUBLIC_CNT; i++) { 378ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (strcmp(name, kStreamNames[i - AUDIO_STREAM_DEFAULT]) == 0) { 379ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("streamNameToEnum found stream %s %d", name, i); 380ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu break; 381ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 382ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 383ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return (audio_stream_type_t)i; 384ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 385ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 386ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ---------------------------------------------------------------------------- 387ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// Audio Effect Config parser 388ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu// ---------------------------------------------------------------------------- 389ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 390138ed1796f8c8edd318488911a9b056877191778Eric Laurentsize_t AudioPolicyEffects::growParamSize(char **param, 391ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t size, 392ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t *curSize, 393ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t *totSize) 394ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 395ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int) 396ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t pos = ((*curSize - 1 ) / size + 1) * size; 397ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 398ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (pos + size > *totSize) { 399ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (pos + size > *totSize) { 400ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *totSize += ((*totSize + 7) / 8) * 4; 401ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 40231225688b7b09ad15f5b1fb8ab2868cecc551f15George Burgess IV char *newParam = (char *)realloc(*param, *totSize); 40331225688b7b09ad15f5b1fb8ab2868cecc551f15George Burgess IV if (newParam == NULL) { 404138ed1796f8c8edd318488911a9b056877191778Eric Laurent ALOGE("%s realloc error for size %zu", __func__, *totSize); 405138ed1796f8c8edd318488911a9b056877191778Eric Laurent return 0; 406138ed1796f8c8edd318488911a9b056877191778Eric Laurent } 40731225688b7b09ad15f5b1fb8ab2868cecc551f15George Burgess IV *param = newParam; 408ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 409ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *curSize = pos + size; 410ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return pos; 411ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 412ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 413138ed1796f8c8edd318488911a9b056877191778Eric Laurent 414ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liusize_t AudioPolicyEffects::readParamValue(cnode *node, 415138ed1796f8c8edd318488911a9b056877191778Eric Laurent char **param, 416ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t *curSize, 417ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t *totSize) 418ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 419138ed1796f8c8edd318488911a9b056877191778Eric Laurent size_t len = 0; 420138ed1796f8c8edd318488911a9b056877191778Eric Laurent size_t pos; 421138ed1796f8c8edd318488911a9b056877191778Eric Laurent 422ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) { 423138ed1796f8c8edd318488911a9b056877191778Eric Laurent pos = growParamSize(param, sizeof(short), curSize, totSize); 424138ed1796f8c8edd318488911a9b056877191778Eric Laurent if (pos == 0) { 425138ed1796f8c8edd318488911a9b056877191778Eric Laurent goto exit; 426138ed1796f8c8edd318488911a9b056877191778Eric Laurent } 427138ed1796f8c8edd318488911a9b056877191778Eric Laurent *(short *)(*param + pos) = (short)atoi(node->value); 428138ed1796f8c8edd318488911a9b056877191778Eric Laurent ALOGV("readParamValue() reading short %d", *(short *)(*param + pos)); 429138ed1796f8c8edd318488911a9b056877191778Eric Laurent len = sizeof(short); 430ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) { 431138ed1796f8c8edd318488911a9b056877191778Eric Laurent pos = growParamSize(param, sizeof(int), curSize, totSize); 432138ed1796f8c8edd318488911a9b056877191778Eric Laurent if (pos == 0) { 433138ed1796f8c8edd318488911a9b056877191778Eric Laurent goto exit; 434138ed1796f8c8edd318488911a9b056877191778Eric Laurent } 435138ed1796f8c8edd318488911a9b056877191778Eric Laurent *(int *)(*param + pos) = atoi(node->value); 436138ed1796f8c8edd318488911a9b056877191778Eric Laurent ALOGV("readParamValue() reading int %d", *(int *)(*param + pos)); 437138ed1796f8c8edd318488911a9b056877191778Eric Laurent len = sizeof(int); 438ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) { 439138ed1796f8c8edd318488911a9b056877191778Eric Laurent pos = growParamSize(param, sizeof(float), curSize, totSize); 440138ed1796f8c8edd318488911a9b056877191778Eric Laurent if (pos == 0) { 441138ed1796f8c8edd318488911a9b056877191778Eric Laurent goto exit; 442138ed1796f8c8edd318488911a9b056877191778Eric Laurent } 443138ed1796f8c8edd318488911a9b056877191778Eric Laurent *(float *)(*param + pos) = (float)atof(node->value); 444138ed1796f8c8edd318488911a9b056877191778Eric Laurent ALOGV("readParamValue() reading float %f",*(float *)(*param + pos)); 445138ed1796f8c8edd318488911a9b056877191778Eric Laurent len = sizeof(float); 446ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) { 447138ed1796f8c8edd318488911a9b056877191778Eric Laurent pos = growParamSize(param, sizeof(bool), curSize, totSize); 448138ed1796f8c8edd318488911a9b056877191778Eric Laurent if (pos == 0) { 449138ed1796f8c8edd318488911a9b056877191778Eric Laurent goto exit; 450138ed1796f8c8edd318488911a9b056877191778Eric Laurent } 451138ed1796f8c8edd318488911a9b056877191778Eric Laurent if (strncmp(node->value, "true", strlen("true") + 1) == 0) { 452138ed1796f8c8edd318488911a9b056877191778Eric Laurent *(bool *)(*param + pos) = true; 453ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else { 454138ed1796f8c8edd318488911a9b056877191778Eric Laurent *(bool *)(*param + pos) = false; 455ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 456138ed1796f8c8edd318488911a9b056877191778Eric Laurent ALOGV("readParamValue() reading bool %s", 457138ed1796f8c8edd318488911a9b056877191778Eric Laurent *(bool *)(*param + pos) ? "true" : "false"); 458138ed1796f8c8edd318488911a9b056877191778Eric Laurent len = sizeof(bool); 459ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) { 460138ed1796f8c8edd318488911a9b056877191778Eric Laurent len = strnlen(node->value, EFFECT_STRING_LEN_MAX); 461ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (*curSize + len + 1 > *totSize) { 462ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *totSize = *curSize + len + 1; 463138ed1796f8c8edd318488911a9b056877191778Eric Laurent *param = (char *)realloc(*param, *totSize); 464138ed1796f8c8edd318488911a9b056877191778Eric Laurent if (*param == NULL) { 465138ed1796f8c8edd318488911a9b056877191778Eric Laurent len = 0; 466138ed1796f8c8edd318488911a9b056877191778Eric Laurent ALOGE("%s realloc error for string len %zu", __func__, *totSize); 467138ed1796f8c8edd318488911a9b056877191778Eric Laurent goto exit; 468138ed1796f8c8edd318488911a9b056877191778Eric Laurent } 469ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 470138ed1796f8c8edd318488911a9b056877191778Eric Laurent strncpy(*param + *curSize, node->value, len); 471ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *curSize += len; 472138ed1796f8c8edd318488911a9b056877191778Eric Laurent (*param)[*curSize] = '\0'; 473138ed1796f8c8edd318488911a9b056877191778Eric Laurent ALOGV("readParamValue() reading string %s", *param + *curSize - len); 474138ed1796f8c8edd318488911a9b056877191778Eric Laurent } else { 475138ed1796f8c8edd318488911a9b056877191778Eric Laurent ALOGW("readParamValue() unknown param type %s", node->name); 476ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 477138ed1796f8c8edd318488911a9b056877191778Eric Laurentexit: 478138ed1796f8c8edd318488911a9b056877191778Eric Laurent return len; 479ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 480ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 481ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liueffect_param_t *AudioPolicyEffects::loadEffectParameter(cnode *root) 482ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 483ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *param; 484ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *value; 485ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t curSize = sizeof(effect_param_t); 486ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int); 487ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_param_t *fx_param = (effect_param_t *)malloc(totSize); 488ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 489138ed1796f8c8edd318488911a9b056877191778Eric Laurent if (fx_param == NULL) { 490138ed1796f8c8edd318488911a9b056877191778Eric Laurent ALOGE("%s malloc error for effect structure of size %zu", 491138ed1796f8c8edd318488911a9b056877191778Eric Laurent __func__, totSize); 492138ed1796f8c8edd318488911a9b056877191778Eric Laurent return NULL; 493138ed1796f8c8edd318488911a9b056877191778Eric Laurent } 494138ed1796f8c8edd318488911a9b056877191778Eric Laurent 495ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu param = config_find(root, PARAM_TAG); 496ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu value = config_find(root, VALUE_TAG); 497ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (param == NULL && value == NULL) { 498ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // try to parse simple parameter form {int int} 499ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu param = root->first_child; 500ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (param != NULL) { 501ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // Note: that a pair of random strings is read as 0 0 502ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu int *ptr = (int *)fx_param->data; 503138ed1796f8c8edd318488911a9b056877191778Eric Laurent#if LOG_NDEBUG == 0 504ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu int *ptr2 = (int *)((char *)param + sizeof(effect_param_t)); 505138ed1796f8c8edd318488911a9b056877191778Eric Laurent ALOGV("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2); 506138ed1796f8c8edd318488911a9b056877191778Eric Laurent#endif 507ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *ptr++ = atoi(param->name); 508ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu *ptr = atoi(param->value); 509ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->psize = sizeof(int); 510ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->vsize = sizeof(int); 511ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return fx_param; 512ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 513ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 514ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (param == NULL || value == NULL) { 515138ed1796f8c8edd318488911a9b056877191778Eric Laurent ALOGW("loadEffectParameter() invalid parameter description %s", 516138ed1796f8c8edd318488911a9b056877191778Eric Laurent root->name); 517ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu goto error; 518ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 519ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 520ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->psize = 0; 521ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu param = param->first_child; 522ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (param) { 523ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectParameter() reading param of type %s", param->name); 524138ed1796f8c8edd318488911a9b056877191778Eric Laurent size_t size = 525138ed1796f8c8edd318488911a9b056877191778Eric Laurent readParamValue(param, (char **)&fx_param, &curSize, &totSize); 526ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (size == 0) { 527ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu goto error; 528ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 529ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->psize += size; 530ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu param = param->next; 531ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 532ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 533ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu // align start of value field on 32 bit boundary 534ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int); 535ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 536ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->vsize = 0; 537ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu value = value->first_child; 538ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (value) { 539ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectParameter() reading value of type %s", value->name); 540138ed1796f8c8edd318488911a9b056877191778Eric Laurent size_t size = 541138ed1796f8c8edd318488911a9b056877191778Eric Laurent readParamValue(value, (char **)&fx_param, &curSize, &totSize); 542ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (size == 0) { 543ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu goto error; 544ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 545ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu fx_param->vsize += size; 546ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu value = value->next; 547ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 548ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 549ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return fx_param; 550ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 551ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuerror: 552138ed1796f8c8edd318488911a9b056877191778Eric Laurent free(fx_param); 553ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NULL; 554ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 555ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 556ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuvoid AudioPolicyEffects::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params) 557ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 558ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = root->first_child; 559ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (node) { 560ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectParameters() loading param %s", node->name); 561ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_param_t *param = loadEffectParameter(node); 562138ed1796f8c8edd318488911a9b056877191778Eric Laurent if (param != NULL) { 563138ed1796f8c8edd318488911a9b056877191778Eric Laurent params.add(param); 564ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 565ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 566ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 567ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 568ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 569ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 570ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuAudioPolicyEffects::EffectDescVector *AudioPolicyEffects::loadEffectConfig( 571ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *root, 572ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu const Vector <EffectDesc *>& effects) 573ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 574ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = root->first_child; 575ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (node == NULL) { 576ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadInputSource() empty element %s", root->name); 577ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NULL; 578ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 579ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDescVector *desc = new EffectDescVector(); 580ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (node) { 581ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu size_t i; 582138ed1796f8c8edd318488911a9b056877191778Eric Laurent 583ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu for (i = 0; i < effects.size(); i++) { 584ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) { 585ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectConfig() found effect %s in list", node->name); 586ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu break; 587ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 588ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 589ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (i == effects.size()) { 590ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectConfig() effect %s not in list", node->name); 591ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 592ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 593ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 594ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDesc *effect = new EffectDesc(*effects[i]); // deep copy 595ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu loadEffectParameters(node, effect->mParams); 596ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffectConfig() adding effect %s uuid %08x", 597ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect->mName, effect->mUuid.timeLow); 598ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu desc->mEffects.add(effect); 599ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 600ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 601ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (desc->mEffects.size() == 0) { 602ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadEffectConfig() no valid effects found in config %s", root->name); 603ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu delete desc; 604ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NULL; 605ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 606ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return desc; 607ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 608ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 609ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadInputEffectConfigurations(cnode *root, 610ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu const Vector <EffectDesc *>& effects) 611ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 612ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = config_find(root, PREPROCESSING_TAG); 613ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (node == NULL) { 614ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return -ENOENT; 615ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 616ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->first_child; 617ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (node) { 618ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu audio_source_t source = inputSourceNameToEnum(node->name); 619ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (source == AUDIO_SOURCE_CNT) { 620ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadInputSources() invalid input source %s", node->name); 621ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 622ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 623ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 624ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadInputSources() loading input source %s", node->name); 625ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDescVector *desc = loadEffectConfig(node, effects); 626ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (desc == NULL) { 627ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 628ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 629ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 630ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mInputSources.add(source, desc); 631ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 632ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 633ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 634ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 635ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 636ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadStreamEffectConfigurations(cnode *root, 637ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu const Vector <EffectDesc *>& effects) 638ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 639ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = config_find(root, OUTPUT_SESSION_PROCESSING_TAG); 640ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (node == NULL) { 641ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return -ENOENT; 642ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 643ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->first_child; 644ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (node) { 645ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu audio_stream_type_t stream = streamNameToEnum(node->name); 646223fd5c9738e9665e495904d37d4632414b68c1eEric Laurent if (stream == AUDIO_STREAM_PUBLIC_CNT) { 647ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadStreamEffectConfigurations() invalid output stream %s", node->name); 648ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 649ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 650ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 651ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadStreamEffectConfigurations() loading output stream %s", node->name); 652ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDescVector *desc = loadEffectConfig(node, effects); 653ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (desc == NULL) { 654ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 655ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 656ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 657ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu mOutputStreams.add(stream, desc); 658ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 659ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 660ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 661ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 662ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 663ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liuAudioPolicyEffects::EffectDesc *AudioPolicyEffects::loadEffect(cnode *root) 664ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 665ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = config_find(root, UUID_TAG); 666ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (node == NULL) { 667ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NULL; 668ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 669ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effect_uuid_t uuid; 670ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) { 671ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGW("loadEffect() invalid uuid %s", node->value); 672ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NULL; 673ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 674ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return new EffectDesc(root->name, uuid); 675ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 676ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 677ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadEffects(cnode *root, Vector <EffectDesc *>& effects) 678ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 679ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *node = config_find(root, EFFECTS_TAG); 680ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (node == NULL) { 681ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return -ENOENT; 682ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 683ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->first_child; 684ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu while (node) { 685ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu ALOGV("loadEffects() loading effect %s", node->name); 686ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu EffectDesc *effect = loadEffect(node); 687ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (effect == NULL) { 688ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 689ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu continue; 690ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 691ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu effects.add(effect); 692ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu node = node->next; 693ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 694ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 695ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 696ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 6974fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocardstatus_t AudioPolicyEffects::loadAudioEffectXmlConfig() { 6984fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard auto result = effectsConfig::parse(); 6994fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard if (result.parsedConfig == nullptr) { 7004fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard return -ENOENT; 7014fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard } 7024fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard 7034fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard auto loadProcessingChain = [](auto& processingChain, auto& streams) { 7044fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard for (auto& stream : processingChain) { 7054fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard auto effectDescs = std::make_unique<EffectDescVector>(); 7064fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard for (auto& effect : stream.effects) { 7074fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard effectDescs->mEffects.add( 7084fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard new EffectDesc{effect.get().name.c_str(), effect.get().uuid}); 7094fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard } 7104fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard streams.add(stream.type, effectDescs.release()); 7114fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard } 7124fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard }; 7134fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard loadProcessingChain(result.parsedConfig->preprocess, mInputSources); 7144fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard loadProcessingChain(result.parsedConfig->postprocess, mOutputStreams); 7154fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard // Casting from ssize_t to status_t is probably safe, there should not be more than 2^31 errors 7164fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard return result.nbSkippedElement; 7174fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard} 7184fb615c2774c04b4d36d8f9d88dd4aa291296288Kevin Rocard 719ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liustatus_t AudioPolicyEffects::loadAudioEffectConfig(const char *path) 720ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu{ 721ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu cnode *root; 722ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu char *data; 723ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 724ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu data = (char *)load_file(path, NULL); 725ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu if (data == NULL) { 726ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return -ENODEV; 727ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu } 728ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu root = config_node("", ""); 729ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu config_load(root, data); 730ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 731ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu Vector <EffectDesc *> effects; 732ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu loadEffects(root, effects); 733ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu loadInputEffectConfigurations(root, effects); 734ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu loadStreamEffectConfigurations(root, effects); 735ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 736182c2f5e48f46c11dbcb5eecb46268dff4ad4797Eric Laurent for (size_t i = 0; i < effects.size(); i++) { 737182c2f5e48f46c11dbcb5eecb46268dff4ad4797Eric Laurent delete effects[i]; 738182c2f5e48f46c11dbcb5eecb46268dff4ad4797Eric Laurent } 739182c2f5e48f46c11dbcb5eecb46268dff4ad4797Eric Laurent 740ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu config_free(root); 741ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu free(root); 742ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu free(data); 743ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 744ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu return NO_ERROR; 745ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu} 746ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 747ba2b43990a7b4f0f2c425cf6cdfc63376a45772cbryant_liu 7481b2a794a27caab3a1320d22b872b04ef73e96555Mikhail Naganov} // namespace android 749