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 /* Acoustic Echo Cancellation implementation */
18 #include "sles_allinclusive.h"
19 
20 #include <system/audio_effects/effect_aec.h>
21 
22 /**
23  * returns true if this interface is not associated with an initialized AEC effect
24  */
NO_ECHOCANCEL(IAndroidAcousticEchoCancellation * v)25 static inline bool NO_ECHOCANCEL(IAndroidAcousticEchoCancellation* v) {
26     return (v->mAECEffect == 0);
27 }
28 
IAndroidAcousticEchoCancellation_SetEnabled(SLAndroidAcousticEchoCancellationItf self,SLboolean enabled)29 static SLresult IAndroidAcousticEchoCancellation_SetEnabled(
30                                                      SLAndroidAcousticEchoCancellationItf self,
31                                                      SLboolean enabled)
32 {
33     SL_ENTER_INTERFACE
34 
35     IAndroidAcousticEchoCancellation *thiz = (IAndroidAcousticEchoCancellation *) self;
36     interface_lock_exclusive(thiz);
37     thiz->mEnabled = (SLboolean) enabled;
38     if (NO_ECHOCANCEL(thiz)) {
39         result = SL_RESULT_CONTROL_LOST;
40     } else {
41         android::status_t status = thiz->mAECEffect->setEnabled((bool) thiz->mEnabled);
42         result = android_fx_statusToResult(status);
43     }
44     interface_unlock_exclusive(thiz);
45 
46     SL_LEAVE_INTERFACE
47 }
48 
IAndroidAcousticEchoCancellation_IsEnabled(SLAndroidAcousticEchoCancellationItf self,SLboolean * pEnabled)49 static SLresult IAndroidAcousticEchoCancellation_IsEnabled(
50                                                     SLAndroidAcousticEchoCancellationItf self,
51                                                     SLboolean *pEnabled)
52 {
53     SL_ENTER_INTERFACE
54 
55     if (NULL == pEnabled) {
56         result = SL_RESULT_PARAMETER_INVALID;
57     } else {
58         IAndroidAcousticEchoCancellation *thiz = (IAndroidAcousticEchoCancellation *) self;
59         interface_lock_exclusive(thiz);
60         if (NO_ECHOCANCEL(thiz)) {
61             result = SL_RESULT_CONTROL_LOST;
62         } else {
63             *pEnabled = (SLboolean) thiz->mAECEffect->getEnabled();
64             result = SL_RESULT_SUCCESS;
65         }
66         interface_unlock_exclusive(thiz);
67     }
68 
69     SL_LEAVE_INTERFACE
70 }
71 
72 static const struct SLAndroidAcousticEchoCancellationItf_ IAndroidAcousticEchoCancellation_Itf = {
73     IAndroidAcousticEchoCancellation_SetEnabled,
74     IAndroidAcousticEchoCancellation_IsEnabled
75 };
76 
IAndroidAcousticEchoCancellation_init(void * self)77 void IAndroidAcousticEchoCancellation_init(void *self)
78 {
79     IAndroidAcousticEchoCancellation *thiz = (IAndroidAcousticEchoCancellation *) self;
80     thiz->mItf = &IAndroidAcousticEchoCancellation_Itf;
81     thiz->mEnabled = SL_BOOLEAN_FALSE;
82     memset(&thiz->mAECDescriptor, 0, sizeof(effect_descriptor_t));
83     // placement new (explicit constructor)
84     (void) new (&thiz->mAECEffect) android::sp<android::AudioEffect>();
85 }
86 
IAndroidAcousticEchoCancellation_deinit(void * self)87 void IAndroidAcousticEchoCancellation_deinit(void *self)
88 {
89     IAndroidAcousticEchoCancellation *thiz = (IAndroidAcousticEchoCancellation *) self;
90     // explicit destructor
91     thiz->mAECEffect.~sp();
92 }
93 
IAndroidAcousticEchoCancellation_Expose(void * self)94 bool IAndroidAcousticEchoCancellation_Expose(void *self)
95 {
96     IAndroidAcousticEchoCancellation *thiz = (IAndroidAcousticEchoCancellation *) self;
97     if (!android_fx_initEffectDescriptor(SL_IID_ANDROIDACOUSTICECHOCANCELLATION,
98                                          &thiz->mAECDescriptor)) {
99         SL_LOGE("Acoustic Echo Cancellation initialization failed.");
100         return false;
101     }
102     return true;
103 }
104