1 /*
2  * Copyright (C) 2010 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 /* BassBoost implementation */
18 
19 #include "sles_allinclusive.h"
20 #ifdef ANDROID
21 #include <audio_effects/effect_bassboost.h>
22 #endif
23 
24 #define BASSBOOST_STRENGTH_MIN 0
25 #define BASSBOOST_STRENGTH_MAX 1000
26 
27 
28 #if defined(ANDROID)
29 /**
30  * returns true if this interface is not associated with an initialized BassBoost effect
31  */
NO_BASSBOOST(IBassBoost * v)32 static inline bool NO_BASSBOOST(IBassBoost* v) {
33     return (v->mBassBoostEffect == 0);
34 }
35 #endif
36 
37 
IBassBoost_SetEnabled(SLBassBoostItf self,SLboolean enabled)38 static SLresult IBassBoost_SetEnabled(SLBassBoostItf self, SLboolean enabled)
39 {
40     SL_ENTER_INTERFACE
41 
42     IBassBoost *thiz = (IBassBoost *) self;
43     interface_lock_exclusive(thiz);
44     thiz->mEnabled = (SLboolean) enabled;
45 #if !defined(ANDROID)
46     result = SL_RESULT_SUCCESS;
47 #else
48     if (NO_BASSBOOST(thiz)) {
49         result = SL_RESULT_CONTROL_LOST;
50     } else {
51         android::status_t status = thiz->mBassBoostEffect->setEnabled((bool) thiz->mEnabled);
52         result = android_fx_statusToResult(status);
53     }
54 #endif
55     interface_unlock_exclusive(thiz);
56 
57     SL_LEAVE_INTERFACE
58 }
59 
60 
IBassBoost_IsEnabled(SLBassBoostItf self,SLboolean * pEnabled)61 static SLresult IBassBoost_IsEnabled(SLBassBoostItf self, SLboolean *pEnabled)
62 {
63     SL_ENTER_INTERFACE
64 
65     if (NULL == pEnabled) {
66         result = SL_RESULT_PARAMETER_INVALID;
67     } else {
68         IBassBoost *thiz = (IBassBoost *) self;
69         interface_lock_exclusive(thiz);
70 #if !defined(ANDROID)
71         SLboolean enabled = thiz->mEnabled;
72         *pEnabled = enabled;
73         result = SL_RESULT_SUCCESS;
74 #else
75         if (NO_BASSBOOST(thiz)) {
76             result = SL_RESULT_CONTROL_LOST;
77         } else {
78             *pEnabled = (SLboolean) thiz->mBassBoostEffect->getEnabled();
79             result = SL_RESULT_SUCCESS;
80         }
81 #endif
82         interface_unlock_exclusive(thiz);
83     }
84 
85     SL_LEAVE_INTERFACE
86 }
87 
88 
IBassBoost_SetStrength(SLBassBoostItf self,SLpermille strength)89 static SLresult IBassBoost_SetStrength(SLBassBoostItf self, SLpermille strength)
90 {
91     SL_ENTER_INTERFACE
92 
93     if ((BASSBOOST_STRENGTH_MIN > strength) || (BASSBOOST_STRENGTH_MAX < strength)) {
94         result = SL_RESULT_PARAMETER_INVALID;
95     } else {
96         IBassBoost *thiz = (IBassBoost *) self;
97         interface_lock_exclusive(thiz);
98 #if !defined(ANDROID)
99         thiz->mStrength = strength;
100         result = SL_RESULT_SUCCESS;
101 #else
102         if (NO_BASSBOOST(thiz)) {
103             result = SL_RESULT_CONTROL_LOST;
104         } else {
105             android::status_t status =
106                 android_bb_setParam(thiz->mBassBoostEffect, BASSBOOST_PARAM_STRENGTH, &strength);
107             result = android_fx_statusToResult(status);
108         }
109 #endif
110         interface_unlock_exclusive(thiz);
111     }
112 
113     SL_LEAVE_INTERFACE
114 }
115 
116 
IBassBoost_GetRoundedStrength(SLBassBoostItf self,SLpermille * pStrength)117 static SLresult IBassBoost_GetRoundedStrength(SLBassBoostItf self, SLpermille *pStrength)
118 {
119     SL_ENTER_INTERFACE
120 
121     if (NULL == pStrength) {
122         result = SL_RESULT_PARAMETER_INVALID;
123     } else {
124         IBassBoost *thiz = (IBassBoost *) self;
125         interface_lock_exclusive(thiz);
126         SLpermille strength = thiz->mStrength;;
127 #if !defined(ANDROID)
128         result = SL_RESULT_SUCCESS;
129 #else
130         if (NO_BASSBOOST(thiz)) {
131             result = SL_RESULT_CONTROL_LOST;
132         } else {
133             android::status_t status =
134                    android_bb_getParam(thiz->mBassBoostEffect, BASSBOOST_PARAM_STRENGTH, &strength);
135             result = android_fx_statusToResult(status);
136         }
137 #endif
138         interface_unlock_exclusive(thiz);
139         *pStrength = strength;
140     }
141 
142     SL_LEAVE_INTERFACE
143 }
144 
145 
IBassBoost_IsStrengthSupported(SLBassBoostItf self,SLboolean * pSupported)146 static SLresult IBassBoost_IsStrengthSupported(SLBassBoostItf self, SLboolean *pSupported)
147 {
148     SL_ENTER_INTERFACE
149 
150     if (NULL == pSupported) {
151         result = SL_RESULT_PARAMETER_INVALID;
152     } else {
153 #if !defined(ANDROID)
154         *pSupported = SL_BOOLEAN_TRUE;
155         result = SL_RESULT_SUCCESS;
156 #else
157         IBassBoost *thiz = (IBassBoost *) self;
158         int32_t supported = 0;
159         interface_lock_exclusive(thiz);
160         if (NO_BASSBOOST(thiz)) {
161             result = SL_RESULT_CONTROL_LOST;
162         } else {
163             android::status_t status =
164                 android_bb_getParam(thiz->mBassBoostEffect, BASSBOOST_PARAM_STRENGTH_SUPPORTED,
165                         &supported);
166             result = android_fx_statusToResult(status);
167         }
168         interface_unlock_exclusive(thiz);
169         *pSupported = (SLboolean) (supported != 0);
170 #endif
171     }
172 
173     SL_LEAVE_INTERFACE
174 }
175 
176 
177 static const struct SLBassBoostItf_ IBassBoost_Itf = {
178     IBassBoost_SetEnabled,
179     IBassBoost_IsEnabled,
180     IBassBoost_SetStrength,
181     IBassBoost_GetRoundedStrength,
182     IBassBoost_IsStrengthSupported
183 };
184 
IBassBoost_init(void * self)185 void IBassBoost_init(void *self)
186 {
187     IBassBoost *thiz = (IBassBoost *) self;
188     thiz->mItf = &IBassBoost_Itf;
189     thiz->mEnabled = SL_BOOLEAN_FALSE;
190     thiz->mStrength = 0;
191 #if defined(ANDROID)
192     memset(&thiz->mBassBoostDescriptor, 0, sizeof(effect_descriptor_t));
193     // placement new (explicit constructor)
194     (void) new (&thiz->mBassBoostEffect) android::sp<android::AudioEffect>();
195 #endif
196 }
197 
IBassBoost_deinit(void * self)198 void IBassBoost_deinit(void *self)
199 {
200 #if defined(ANDROID)
201     IBassBoost *thiz = (IBassBoost *) self;
202     // explicit destructor
203     thiz->mBassBoostEffect.~sp();
204 #endif
205 }
206 
IBassBoost_Expose(void * self)207 bool IBassBoost_Expose(void *self)
208 {
209 #if defined(ANDROID)
210     IBassBoost *thiz = (IBassBoost *) self;
211     if (!android_fx_initEffectDescriptor(SL_IID_BASSBOOST, &thiz->mBassBoostDescriptor)) {
212         SL_LOGE("BassBoost initialization failed.");
213         return false;
214     }
215 #endif
216     return true;
217 }
218