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 <system/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 */ 32static inline bool NO_BASSBOOST(IBassBoost* v) { 33 return (v->mBassBoostEffect == 0); 34} 35#endif 36 37 38static 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 61static 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 89static 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 117static 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 146static 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 177static const struct SLBassBoostItf_ IBassBoost_Itf = { 178 IBassBoost_SetEnabled, 179 IBassBoost_IsEnabled, 180 IBassBoost_SetStrength, 181 IBassBoost_GetRoundedStrength, 182 IBassBoost_IsStrengthSupported 183}; 184 185void 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 198void 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 207bool 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