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