Home | History | Annotate | Download | only in default
      1 /*
      2  * Copyright (C) 2018 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 "EffectsFactory.h"
     19 #include "AcousticEchoCancelerEffect.h"
     20 #include "AutomaticGainControlEffect.h"
     21 #include "BassBoostEffect.h"
     22 #include "Conversions.h"
     23 #include "DownmixEffect.h"
     24 #include "Effect.h"
     25 #include "EnvironmentalReverbEffect.h"
     26 #include "EqualizerEffect.h"
     27 #include "HidlUtils.h"
     28 #include "LoudnessEnhancerEffect.h"
     29 #include "NoiseSuppressionEffect.h"
     30 #include "PresetReverbEffect.h"
     31 #include "VirtualizerEffect.h"
     32 #include "VisualizerEffect.h"
     33 #include "common/all-versions/default/EffectMap.h"
     34 
     35 #include <android/log.h>
     36 #include <media/EffectsFactoryApi.h>
     37 #include <system/audio_effects/effect_aec.h>
     38 #include <system/audio_effects/effect_agc.h>
     39 #include <system/audio_effects/effect_bassboost.h>
     40 #include <system/audio_effects/effect_downmix.h>
     41 #include <system/audio_effects/effect_environmentalreverb.h>
     42 #include <system/audio_effects/effect_equalizer.h>
     43 #include <system/audio_effects/effect_loudnessenhancer.h>
     44 #include <system/audio_effects/effect_ns.h>
     45 #include <system/audio_effects/effect_presetreverb.h>
     46 #include <system/audio_effects/effect_virtualizer.h>
     47 #include <system/audio_effects/effect_visualizer.h>
     48 
     49 namespace android {
     50 namespace hardware {
     51 namespace audio {
     52 namespace effect {
     53 namespace CPP_VERSION {
     54 namespace implementation {
     55 
     56 using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
     57 
     58 // static
     59 sp<IEffect> EffectsFactory::dispatchEffectInstanceCreation(const effect_descriptor_t& halDescriptor,
     60                                                            effect_handle_t handle) {
     61     const effect_uuid_t* halUuid = &halDescriptor.type;
     62     if (memcmp(halUuid, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) {
     63         return new AcousticEchoCancelerEffect(handle);
     64     } else if (memcmp(halUuid, FX_IID_AGC, sizeof(effect_uuid_t)) == 0) {
     65         return new AutomaticGainControlEffect(handle);
     66     } else if (memcmp(halUuid, SL_IID_BASSBOOST, sizeof(effect_uuid_t)) == 0) {
     67         return new BassBoostEffect(handle);
     68     } else if (memcmp(halUuid, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0) {
     69         return new DownmixEffect(handle);
     70     } else if (memcmp(halUuid, SL_IID_ENVIRONMENTALREVERB, sizeof(effect_uuid_t)) == 0) {
     71         return new EnvironmentalReverbEffect(handle);
     72     } else if (memcmp(halUuid, SL_IID_EQUALIZER, sizeof(effect_uuid_t)) == 0) {
     73         return new EqualizerEffect(handle);
     74     } else if (memcmp(halUuid, FX_IID_LOUDNESS_ENHANCER, sizeof(effect_uuid_t)) == 0) {
     75         return new LoudnessEnhancerEffect(handle);
     76     } else if (memcmp(halUuid, FX_IID_NS, sizeof(effect_uuid_t)) == 0) {
     77         return new NoiseSuppressionEffect(handle);
     78     } else if (memcmp(halUuid, SL_IID_PRESETREVERB, sizeof(effect_uuid_t)) == 0) {
     79         return new PresetReverbEffect(handle);
     80     } else if (memcmp(halUuid, SL_IID_VIRTUALIZER, sizeof(effect_uuid_t)) == 0) {
     81         return new VirtualizerEffect(handle);
     82     } else if (memcmp(halUuid, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) {
     83         return new VisualizerEffect(handle);
     84     }
     85     return new Effect(handle);
     86 }
     87 
     88 // Methods from ::android::hardware::audio::effect::CPP_VERSION::IEffectsFactory follow.
     89 Return<void> EffectsFactory::getAllDescriptors(getAllDescriptors_cb _hidl_cb) {
     90     Result retval(Result::OK);
     91     hidl_vec<EffectDescriptor> result;
     92     uint32_t numEffects;
     93     status_t status;
     94 
     95 restart:
     96     numEffects = 0;
     97     status = EffectQueryNumberEffects(&numEffects);
     98     if (status != OK) {
     99         retval = Result::NOT_INITIALIZED;
    100         ALOGE("Error querying number of effects: %s", strerror(-status));
    101         goto exit;
    102     }
    103     result.resize(numEffects);
    104     for (uint32_t i = 0; i < numEffects; ++i) {
    105         effect_descriptor_t halDescriptor;
    106         status = EffectQueryEffect(i, &halDescriptor);
    107         if (status == OK) {
    108             effectDescriptorFromHal(halDescriptor, &result[i]);
    109         } else {
    110             ALOGE("Error querying effect at position %d / %d: %s", i, numEffects,
    111                   strerror(-status));
    112             switch (status) {
    113                 case -ENOSYS: {
    114                     // Effect list has changed.
    115                     goto restart;
    116                 }
    117                 case -ENOENT: {
    118                     // No more effects available.
    119                     result.resize(i);
    120                     break;
    121                 }
    122                 default: {
    123                     result.resize(0);
    124                     retval = Result::NOT_INITIALIZED;
    125                 }
    126             }
    127             break;
    128         }
    129     }
    130 
    131 exit:
    132     _hidl_cb(retval, result);
    133     return Void();
    134 }
    135 
    136 Return<void> EffectsFactory::getDescriptor(const Uuid& uid, getDescriptor_cb _hidl_cb) {
    137     effect_uuid_t halUuid;
    138     HidlUtils::uuidToHal(uid, &halUuid);
    139     effect_descriptor_t halDescriptor;
    140     status_t status = EffectGetDescriptor(&halUuid, &halDescriptor);
    141     EffectDescriptor descriptor;
    142     effectDescriptorFromHal(halDescriptor, &descriptor);
    143     Result retval(Result::OK);
    144     if (status != OK) {
    145         ALOGE("Error querying effect descriptor for %s: %s", uuidToString(halUuid).c_str(),
    146               strerror(-status));
    147         if (status == -ENOENT) {
    148             retval = Result::INVALID_ARGUMENTS;
    149         } else {
    150             retval = Result::NOT_INITIALIZED;
    151         }
    152     }
    153     _hidl_cb(retval, descriptor);
    154     return Void();
    155 }
    156 
    157 Return<void> EffectsFactory::createEffect(const Uuid& uid, int32_t session, int32_t ioHandle,
    158                                           createEffect_cb _hidl_cb) {
    159     effect_uuid_t halUuid;
    160     HidlUtils::uuidToHal(uid, &halUuid);
    161     effect_handle_t handle;
    162     Result retval(Result::OK);
    163     status_t status = EffectCreate(&halUuid, session, ioHandle, &handle);
    164     sp<IEffect> effect;
    165     uint64_t effectId = EffectMap::INVALID_ID;
    166     if (status == OK) {
    167         effect_descriptor_t halDescriptor;
    168         memset(&halDescriptor, 0, sizeof(effect_descriptor_t));
    169         status = (*handle)->get_descriptor(handle, &halDescriptor);
    170         if (status == OK) {
    171             effect = dispatchEffectInstanceCreation(halDescriptor, handle);
    172             effectId = EffectMap::getInstance().add(handle);
    173         } else {
    174             ALOGE("Error querying effect descriptor for %s: %s", uuidToString(halUuid).c_str(),
    175                   strerror(-status));
    176             EffectRelease(handle);
    177         }
    178     }
    179     if (status != OK) {
    180         ALOGE("Error creating effect %s: %s", uuidToString(halUuid).c_str(), strerror(-status));
    181         if (status == -ENOENT) {
    182             retval = Result::INVALID_ARGUMENTS;
    183         } else {
    184             retval = Result::NOT_INITIALIZED;
    185         }
    186     }
    187     _hidl_cb(retval, effect, effectId);
    188     return Void();
    189 }
    190 
    191 Return<void> EffectsFactory::debugDump(const hidl_handle& fd) {
    192     return debug(fd, {} /* options */);
    193 }
    194 
    195 Return<void> EffectsFactory::debug(const hidl_handle& fd,
    196                                    const hidl_vec<hidl_string>& /* options */) {
    197     if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
    198         EffectDumpEffects(fd->data[0]);
    199     }
    200     return Void();
    201 }
    202 
    203 IEffectsFactory* HIDL_FETCH_IEffectsFactory(const char* name) {
    204     return strcmp(name, "default") == 0 ? new EffectsFactory() : nullptr;
    205 }
    206 
    207 }  // namespace implementation
    208 }  // namespace CPP_VERSION
    209 }  // namespace effect
    210 }  // namespace audio
    211 }  // namespace hardware
    212 }  // namespace android
    213