EffectsFactory.cpp revision 10548295023bee99108e418499aff09fe578211e
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "EffectFactoryHAL" 18#include <media/EffectsFactoryApi.h> 19#include <system/audio_effects/effect_aec.h> 20#include <system/audio_effects/effect_agc.h> 21#include <system/audio_effects/effect_bassboost.h> 22#include <system/audio_effects/effect_downmix.h> 23#include <system/audio_effects/effect_environmentalreverb.h> 24#include <system/audio_effects/effect_equalizer.h> 25#include <system/audio_effects/effect_loudnessenhancer.h> 26#include <system/audio_effects/effect_ns.h> 27#include <system/audio_effects/effect_presetreverb.h> 28#include <system/audio_effects/effect_virtualizer.h> 29#include <system/audio_effects/effect_visualizer.h> 30#include <utils/Log.h> 31 32#include "AcousticEchoCancelerEffect.h" 33#include "AutomaticGainControlEffect.h" 34#include "BassBoostEffect.h" 35#include "Conversions.h" 36#include "EffectsFactory.h" 37#include "DownmixEffect.h" 38#include "Effect.h" 39#include "EffectMap.h" 40#include "EnvironmentalReverbEffect.h" 41#include "EqualizerEffect.h" 42#include "LoudnessEnhancerEffect.h" 43#include "NoiseSuppressionEffect.h" 44#include "PresetReverbEffect.h" 45#include "VirtualizerEffect.h" 46#include "VisualizerEffect.h" 47 48namespace android { 49namespace hardware { 50namespace audio { 51namespace effect { 52namespace V2_0 { 53namespace implementation { 54 55// static 56sp<IEffect> EffectsFactory::dispatchEffectInstanceCreation( 57 const effect_descriptor_t& halDescriptor, effect_handle_t handle) { 58 const effect_uuid_t *halUuid = &halDescriptor.type; 59 if (memcmp(halUuid, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) { 60 return new AcousticEchoCancelerEffect(handle); 61 } else if (memcmp(halUuid, FX_IID_AGC, sizeof(effect_uuid_t)) == 0) { 62 return new AutomaticGainControlEffect(handle); 63 } else if (memcmp(halUuid, SL_IID_BASSBOOST, sizeof(effect_uuid_t)) == 0) { 64 return new BassBoostEffect(handle); 65 } else if (memcmp(halUuid, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) { 66 return new DownmixEffect(handle); 67 } else if (memcmp(halUuid, SL_IID_ENVIRONMENTALREVERB, sizeof(effect_uuid_t)) == 0) { 68 return new EnvironmentalReverbEffect(handle); 69 } else if (memcmp(halUuid, SL_IID_EQUALIZER, sizeof(effect_uuid_t)) == 0) { 70 return new EqualizerEffect(handle); 71 } else if (memcmp(halUuid, FX_IID_LOUDNESS_ENHANCER, sizeof(effect_uuid_t)) == 0) { 72 return new LoudnessEnhancerEffect(handle); 73 } else if (memcmp(halUuid, FX_IID_NS, sizeof(effect_uuid_t)) == 0) { 74 return new NoiseSuppressionEffect(handle); 75 } else if (memcmp(halUuid, SL_IID_PRESETREVERB, sizeof(effect_uuid_t)) == 0) { 76 return new PresetReverbEffect(handle); 77 } else if (memcmp(halUuid, SL_IID_VIRTUALIZER, sizeof(effect_uuid_t)) == 0) { 78 return new VirtualizerEffect(handle); 79 } else if (memcmp(halUuid, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) { 80 return new VisualizerEffect(handle); 81 } 82 return new Effect(handle); 83} 84 85// Methods from ::android::hardware::audio::effect::V2_0::IEffectsFactory follow. 86Return<void> EffectsFactory::getAllDescriptors(getAllDescriptors_cb _hidl_cb) { 87 Result retval(Result::OK); 88 hidl_vec<EffectDescriptor> result; 89 uint32_t numEffects; 90 status_t status; 91 92restart: 93 numEffects = 0; 94 status = EffectQueryNumberEffects(&numEffects); 95 if (status != OK) { 96 retval = Result::NOT_INITIALIZED; 97 ALOGW("Error querying number of effects: %s", strerror(-status)); 98 goto exit; 99 } 100 result.resize(numEffects); 101 for (uint32_t i = 0; i < numEffects; ++i) { 102 effect_descriptor_t halDescriptor; 103 status = EffectQueryEffect(i, &halDescriptor); 104 if (status == OK) { 105 effectDescriptorFromHal(halDescriptor, &result[i]); 106 } else { 107 ALOGW("Error querying effect at position %d / %d: %s", 108 i, numEffects, strerror(-status)); 109 switch (status) { 110 case -ENOSYS: { 111 // Effect list has changed. 112 goto restart; 113 } 114 case -ENOENT: { 115 // No more effects available. 116 result.resize(i); 117 } 118 default: { 119 result.resize(0); 120 retval = Result::NOT_INITIALIZED; 121 } 122 } 123 break; 124 } 125 } 126 127exit: 128 _hidl_cb(retval, result); 129 return Void(); 130} 131 132Return<void> EffectsFactory::getDescriptor(const Uuid& uid, getDescriptor_cb _hidl_cb) { 133 effect_uuid_t halUuid; 134 uuidToHal(uid, &halUuid); 135 effect_descriptor_t halDescriptor; 136 status_t status = EffectGetDescriptor(&halUuid, &halDescriptor); 137 EffectDescriptor descriptor; 138 effectDescriptorFromHal(halDescriptor, &descriptor); 139 Result retval(Result::OK); 140 if (status != OK) { 141 ALOGW("Error querying effect descriptor for %s: %s", 142 uuidToString(halUuid).c_str(), strerror(-status)); 143 if (status == -ENOENT) { 144 retval = Result::INVALID_ARGUMENTS; 145 } else { 146 retval = Result::NOT_INITIALIZED; 147 } 148 } 149 _hidl_cb(retval, descriptor); 150 return Void(); 151} 152 153Return<void> EffectsFactory::createEffect( 154 const Uuid& uid, int32_t session, int32_t ioHandle, createEffect_cb _hidl_cb) { 155 effect_uuid_t halUuid; 156 uuidToHal(uid, &halUuid); 157 effect_handle_t handle; 158 Result retval(Result::OK); 159 status_t status = EffectCreate(&halUuid, session, ioHandle, &handle); 160 sp<IEffect> effect; 161 uint64_t effectId = EffectMap::INVALID_ID; 162 if (status == OK) { 163 effect_descriptor_t halDescriptor; 164 memset(&halDescriptor, 0, sizeof(effect_descriptor_t)); 165 status = (*handle)->get_descriptor(handle, &halDescriptor); 166 if (status == OK) { 167 effect = dispatchEffectInstanceCreation(halDescriptor, handle); 168 effectId = EffectMap::getInstance().add(handle); 169 } else { 170 EffectRelease(handle); 171 } 172 } 173 if (status != OK) { 174 ALOGW("Error creating effect %s: %s", uuidToString(halUuid).c_str(), strerror(-status)); 175 if (status == -ENOENT) { 176 retval = Result::INVALID_ARGUMENTS; 177 } else { 178 retval = Result::NOT_INITIALIZED; 179 } 180 } 181 _hidl_cb(retval, effect, effectId); 182 return Void(); 183} 184 185Return<void> EffectsFactory::debugDump(const native_handle_t* fd) { 186 if (fd->numFds == 1) { 187 EffectDumpEffects(fd->data[0]); 188 } 189 return Void(); 190} 191 192 193IEffectsFactory* HIDL_FETCH_IEffectsFactory(const char* /* name */) { 194 return new EffectsFactory(); 195} 196 197} // namespace implementation 198} // namespace V2_0 199} // namespace effect 200} // namespace audio 201} // namespace hardware 202} // namespace android 203