Home | History | Annotate | Download | only in itf
      1 /*
      2  * Copyright (C) 2014 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 /* Automatic Gain Control implementation */
     18 #include "sles_allinclusive.h"
     19 
     20 #include <media/EffectsFactoryApi.h>
     21 
     22 #include <audio_effects/effect_agc.h>
     23 
     24 /**
     25  * returns true if this interface is not associated with an initialized AGC effect
     26  */
     27 static inline bool NO_AUTOGAIN(IAndroidAutomaticGainControl* v) {
     28     return (v->mAGCEffect == 0);
     29 }
     30 
     31 SLresult IAndroidAutomaticGainControl_SetEnabled(SLAndroidAutomaticGainControlItf self, SLboolean enabled)
     32 {
     33     SL_ENTER_INTERFACE
     34 
     35     IAndroidAutomaticGainControl *thiz = (IAndroidAutomaticGainControl *) self;
     36     interface_lock_exclusive(thiz);
     37     thiz->mEnabled = (SLboolean) enabled;
     38     if (NO_AUTOGAIN(thiz)) {
     39         result = SL_RESULT_CONTROL_LOST;
     40     } else {
     41         android::status_t status = thiz->mAGCEffect->setEnabled((bool) thiz->mEnabled);
     42         result = android_fx_statusToResult(status);
     43     }
     44     interface_unlock_exclusive(thiz);
     45 
     46     SL_LEAVE_INTERFACE
     47 }
     48 
     49 SLresult IAndroidAutomaticGainControl_IsEnabled(SLAndroidAutomaticGainControlItf self, SLboolean *pEnabled)
     50 {
     51     SL_ENTER_INTERFACE
     52 
     53     if (NULL == pEnabled) {
     54         result = SL_RESULT_PARAMETER_INVALID;
     55     } else {
     56         IAndroidAutomaticGainControl *thiz = (IAndroidAutomaticGainControl *) self;
     57         interface_lock_exclusive(thiz);
     58         SLboolean enabled = thiz->mEnabled;
     59         if (NO_AUTOGAIN(thiz)) {
     60             result = SL_RESULT_CONTROL_LOST;
     61         } else {
     62             *pEnabled = (SLboolean) thiz->mAGCEffect->getEnabled();
     63             result = SL_RESULT_SUCCESS;
     64         }
     65         interface_unlock_exclusive(thiz);
     66     }
     67     SL_LEAVE_INTERFACE
     68 }
     69 
     70 SLresult IAndroidAutomaticGainControl_IsAvailable(SLAndroidAutomaticGainControlItf self,
     71                                                   SLboolean *pEnabled)
     72 {
     73     SL_ENTER_INTERFACE
     74 
     75    *pEnabled = false;
     76 
     77     uint32_t numEffects = 0;
     78     int ret = EffectQueryNumberEffects(&numEffects);
     79     if (ret != 0) {
     80         ALOGE("IAndroidAutomaticGainControl_IsAvailable() error %d querying number of effects",
     81               ret);
     82         result = SL_RESULT_FEATURE_UNSUPPORTED;
     83    } else {
     84         ALOGV("EffectQueryNumberEffects() numEffects=%d", numEffects);
     85 
     86         effect_descriptor_t fxDesc;
     87         for (uint32_t i = 0 ; i < numEffects ; i++) {
     88             if (EffectQueryEffect(i, &fxDesc) == 0) {
     89                 ALOGV("effect %d is called %s", i, fxDesc.name);
     90                 if (memcmp(&fxDesc.type, SL_IID_ANDROIDAUTOMATICGAINCONTROL,
     91                            sizeof(effect_uuid_t)) == 0) {
     92                     ALOGI("found effect \"%s\" from %s", fxDesc.name, fxDesc.implementor);
     93                     *pEnabled = true;
     94                     break;
     95                 }
     96             }
     97         }
     98         result = SL_RESULT_SUCCESS;
     99     }
    100     SL_LEAVE_INTERFACE
    101 }
    102 
    103 static const struct SLAndroidAutomaticGainControlItf_ IAndroidAutomaticGainControl_Itf = {
    104     IAndroidAutomaticGainControl_SetEnabled,
    105     IAndroidAutomaticGainControl_IsEnabled,
    106     IAndroidAutomaticGainControl_IsAvailable
    107 };
    108 
    109 void IAndroidAutomaticGainControl_init(void *self)
    110 {
    111     IAndroidAutomaticGainControl *thiz = (IAndroidAutomaticGainControl *) self;
    112     thiz->mItf = &IAndroidAutomaticGainControl_Itf;
    113     thiz->mEnabled = SL_BOOLEAN_FALSE;
    114     memset(&thiz->mAGCDescriptor, 0, sizeof(effect_descriptor_t));
    115     // placement new (explicit constructor)
    116     (void) new (&thiz->mAGCEffect) android::sp<android::AudioEffect>();
    117 }
    118 
    119 void IAndroidAutomaticGainControl_deinit(void *self)
    120 {
    121     IAndroidAutomaticGainControl *thiz = (IAndroidAutomaticGainControl *) self;
    122     // explicit destructor
    123     thiz->mAGCEffect.~sp();
    124 }
    125 
    126 bool IAndroidAutomaticGainControl_Expose(void *self)
    127 {
    128     IAndroidAutomaticGainControl *thiz = (IAndroidAutomaticGainControl *) self;
    129     if (!android_fx_initEffectDescriptor(SL_IID_ANDROIDAUTOMATICGAINCONTROL,
    130                                          &thiz->mAGCDescriptor)) {
    131         SL_LOGE("Automatic Gain Control initialization failed.");
    132         return false;
    133     }
    134     return true;
    135 }
    136