1 /*
2  * Copyright (C) 2010-2010 NXP Software
3  * Copyright (C) 2009 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #ifndef LVM_FLOAT
18 typedef float LVM_FLOAT;
19 #endif
20 #define LOG_TAG "EffectBundle"
21 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array)[0])
22 //#define LOG_NDEBUG 0
23 
24 #include <assert.h>
25 #include <inttypes.h>
26 #include <new>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include <audio_utils/primitives.h>
31 #include <log/log.h>
32 
33 #include "EffectBundle.h"
34 #include "math.h"
35 
36 // effect_handle_t interface implementation for bass boost
37 extern "C" const struct effect_interface_s gLvmEffectInterface;
38 
39 // Turn on VERY_VERY_VERBOSE_LOGGING to log parameter get and set for effects.
40 
41 //#define VERY_VERY_VERBOSE_LOGGING
42 #ifdef VERY_VERY_VERBOSE_LOGGING
43 #define ALOGVV ALOGV
44 #else
45 #define ALOGVV(a...) \
46     do {             \
47     } while (false)
48 #endif
49 
50 #define LVM_ERROR_CHECK(LvmStatus, callingFunc, calledFunc)             \
51     {                                                                   \
52         if ((LvmStatus) == LVM_NULLADDRESS) {                           \
53             ALOGV("\tLVM_ERROR : Parameter error - "                    \
54                   "null pointer returned by %s in %s\n\n\n\n",          \
55                   callingFunc, calledFunc);                             \
56         }                                                               \
57         if ((LvmStatus) == LVM_ALIGNMENTERROR) {                        \
58             ALOGV("\tLVM_ERROR : Parameter error - "                    \
59                   "bad alignment returned by %s in %s\n\n\n\n",         \
60                   callingFunc, calledFunc);                             \
61         }                                                               \
62         if ((LvmStatus) == LVM_INVALIDNUMSAMPLES) {                     \
63             ALOGV("\tLVM_ERROR : Parameter error - "                    \
64                   "bad number of samples returned by %s in %s\n\n\n\n", \
65                   callingFunc, calledFunc);                             \
66         }                                                               \
67         if ((LvmStatus) == LVM_OUTOFRANGE) {                            \
68             ALOGV("\tLVM_ERROR : Parameter error - "                    \
69                   "out of range returned by %s in %s\n",                \
70                   callingFunc, calledFunc);                             \
71         }                                                               \
72     }
73 
74 // Namespaces
75 namespace android {
76 namespace {
77 
78 // Flag to allow a one time init of global memory, only happens on first call ever
79 int LvmInitFlag = LVM_FALSE;
80 SessionContext GlobalSessionMemory[LVM_MAX_SESSIONS];
81 int SessionIndex[LVM_MAX_SESSIONS];
82 
83 /* local functions */
84 #define CHECK_ARG(cond)                                      \
85     {                                                        \
86         if (!(cond)) {                                       \
87             ALOGV("\tLVM_ERROR : Invalid argument: " #cond); \
88             return -EINVAL;                                  \
89         }                                                    \
90     }
91 
92 // NXP SW BassBoost UUID
93 const effect_descriptor_t gBassBoostDescriptor = {
94         {0x0634f220, 0xddd4, 0x11db, 0xa0fc, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
95         {0x8631f300, 0x72e2, 0x11df, 0xb57e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // uuid
96         EFFECT_CONTROL_API_VERSION,
97         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_DEVICE_IND |
98          EFFECT_FLAG_VOLUME_CTRL),
99         BASS_BOOST_CUP_LOAD_ARM9E,
100         BUNDLE_MEM_USAGE,
101         "Dynamic Bass Boost",
102         "NXP Software Ltd.",
103 };
104 
105 // NXP SW Virtualizer UUID
106 const effect_descriptor_t gVirtualizerDescriptor = {
107         {0x37cc2c00, 0xdddd, 0x11db, 0x8577, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
108         {0x1d4033c0, 0x8557, 0x11df, 0x9f2d, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
109         EFFECT_CONTROL_API_VERSION,
110         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_DEVICE_IND |
111          EFFECT_FLAG_VOLUME_CTRL),
112         VIRTUALIZER_CUP_LOAD_ARM9E,
113         BUNDLE_MEM_USAGE,
114         "Virtualizer",
115         "NXP Software Ltd.",
116 };
117 
118 // NXP SW Equalizer UUID
119 const effect_descriptor_t gEqualizerDescriptor = {
120         {0x0bed4300, 0xddd6, 0x11db, 0x8f34, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // type
121         {0xce772f20, 0x847d, 0x11df, 0xbb17, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // uuid Eq NXP
122         EFFECT_CONTROL_API_VERSION,
123         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL),
124         EQUALIZER_CUP_LOAD_ARM9E,
125         BUNDLE_MEM_USAGE,
126         "Equalizer",
127         "NXP Software Ltd.",
128 };
129 
130 // NXP SW Volume UUID
131 const effect_descriptor_t gVolumeDescriptor = {
132         {0x09e8ede0, 0xddde, 0x11db, 0xb4f6, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
133         {0x119341a0, 0x8469, 0x11df, 0x81f9, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},  // uuid VOL NXP
134         EFFECT_CONTROL_API_VERSION,
135         (EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_LAST | EFFECT_FLAG_VOLUME_CTRL),
136         VOLUME_CUP_LOAD_ARM9E,
137         BUNDLE_MEM_USAGE,
138         "Volume",
139         "NXP Software Ltd.",
140 };
141 
142 //--- local function prototypes
143 void LvmGlobalBundle_init(void);
144 int LvmBundle_init(EffectContext* pContext);
145 int LvmEffect_enable(EffectContext* pContext);
146 int LvmEffect_disable(EffectContext* pContext);
147 int Effect_setConfig(EffectContext* pContext, effect_config_t* pConfig);
148 void Effect_getConfig(EffectContext* pContext, effect_config_t* pConfig);
149 int BassBoost_setParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
150                            uint32_t valueSize, void* pValue);
151 int BassBoost_getParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
152                            uint32_t* pValueSize, void* pValue);
153 int Virtualizer_setParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
154                              uint32_t valueSize, void* pValue);
155 int Virtualizer_getParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
156                              uint32_t* pValueSize, void* pValue);
157 int Equalizer_setParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
158                            uint32_t valueSize, void* pValue);
159 int Equalizer_getParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
160                            uint32_t* pValueSize, void* pValue);
161 int Volume_setParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
162                         uint32_t valueSize, void* pValue);
163 int Volume_getParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
164                         uint32_t* pValueSize, void* pValue);
165 int Effect_setEnabled(EffectContext* pContext, bool enabled);
166 
167 /* Effect Library Interface Implementation */
168 
EffectCreate(const effect_uuid_t * uuid,int32_t sessionId,int32_t,effect_handle_t * pHandle)169 extern "C" int EffectCreate(const effect_uuid_t* uuid, int32_t sessionId,
170                             int32_t /* ioId __unused */, effect_handle_t* pHandle) {
171     int ret = 0;
172     int sessionNo = -1;
173     int i;
174     EffectContext* pContext = NULL;
175     bool newBundle = false;
176     SessionContext* pSessionContext;
177 
178     ALOGV("\n\tEffectCreate start session %d", sessionId);
179 
180     if (pHandle == NULL || uuid == NULL) {
181         ALOGV("\tLVM_ERROR : EffectCreate() called with NULL pointer");
182         ret = -EINVAL;
183         goto exit;
184     }
185 
186     if (LvmInitFlag == LVM_FALSE) {
187         LvmInitFlag = LVM_TRUE;
188         ALOGV("\tEffectCreate - Initializing all global memory");
189         LvmGlobalBundle_init();
190     }
191 
192     // Find sessionNo: if one already exists for the sessionId use it,
193     // otherwise choose the first available empty slot.
194     for (i = 0; i < LVM_MAX_SESSIONS; i++) {
195         if (SessionIndex[i] == sessionId) {
196             sessionNo = i;
197             break;
198         }
199         if (sessionNo < 0 && SessionIndex[i] == LVM_UNUSED_SESSION) {
200             sessionNo = i;
201             // do not break; allow loop to continue to search for a sessionId match.
202         }
203     }
204     if (sessionNo < 0) {
205         ALOGV("\tLVM_ERROR : Cannot find memory to allocate for current session");
206         ret = -EINVAL;
207         goto exit;
208     }
209 
210     SessionIndex[sessionNo] = sessionId;
211     ALOGV("\tEffectCreate: Allocating sessionNo %d for sessionId %d\n", sessionNo, sessionId);
212 
213     pContext = new EffectContext;
214 
215     // If this is the first create in this session
216     if (GlobalSessionMemory[sessionNo].bBundledEffectsEnabled == LVM_FALSE) {
217         ALOGV("\tEffectCreate - This is the first effect in current sessionId %d sessionNo %d",
218               sessionId, sessionNo);
219 
220         GlobalSessionMemory[sessionNo].bBundledEffectsEnabled = LVM_TRUE;
221         GlobalSessionMemory[sessionNo].pBundledContext = new BundledEffectContext;
222         newBundle = true;
223 
224         pContext->pBundledContext = GlobalSessionMemory[sessionNo].pBundledContext;
225         pContext->pBundledContext->SessionNo = sessionNo;
226         pContext->pBundledContext->SessionId = sessionId;
227         pContext->pBundledContext->hInstance = NULL;
228         pContext->pBundledContext->bVolumeEnabled = LVM_FALSE;
229         pContext->pBundledContext->bEqualizerEnabled = LVM_FALSE;
230         pContext->pBundledContext->bBassEnabled = LVM_FALSE;
231         pContext->pBundledContext->bBassTempDisabled = LVM_FALSE;
232         pContext->pBundledContext->bVirtualizerEnabled = LVM_FALSE;
233         pContext->pBundledContext->bVirtualizerTempDisabled = LVM_FALSE;
234         pContext->pBundledContext->nOutputDevice = AUDIO_DEVICE_NONE;
235         pContext->pBundledContext->nVirtualizerForcedDevice = AUDIO_DEVICE_NONE;
236         pContext->pBundledContext->NumberEffectsEnabled = 0;
237         pContext->pBundledContext->NumberEffectsCalled = 0;
238         pContext->pBundledContext->firstVolume = LVM_TRUE;
239         pContext->pBundledContext->volume = 0;
240 
241         /* Saved strength is used to return the exact strength that was used in the set to the get
242          * because we map the original strength range of 0:1000 to 1:15, and this will avoid
243          * quantisation like effect when returning
244          */
245         pContext->pBundledContext->BassStrengthSaved = 0;
246         pContext->pBundledContext->VirtStrengthSaved = 0;
247         pContext->pBundledContext->CurPreset = PRESET_CUSTOM;
248         pContext->pBundledContext->levelSaved = 0;
249         pContext->pBundledContext->bMuteEnabled = LVM_FALSE;
250         pContext->pBundledContext->bStereoPositionEnabled = LVM_FALSE;
251         pContext->pBundledContext->positionSaved = 0;
252         pContext->pBundledContext->workBuffer = NULL;
253         pContext->pBundledContext->frameCount = -1;
254         pContext->pBundledContext->SamplesToExitCountVirt = 0;
255         pContext->pBundledContext->SamplesToExitCountBb = 0;
256         pContext->pBundledContext->SamplesToExitCountEq = 0;
257         for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
258             pContext->pBundledContext->bandGaindB[i] = EQNB_5BandSoftPresets[i];
259         }
260         pContext->pBundledContext->effectProcessCalled = 0;
261         pContext->pBundledContext->effectInDrain = 0;
262 
263         ALOGV("\tEffectCreate - Calling LvmBundle_init");
264         ret = LvmBundle_init(pContext);
265 
266         if (ret < 0) {
267             ALOGV("\tLVM_ERROR : EffectCreate() Bundle init failed");
268             goto exit;
269         }
270     } else {
271         ALOGV("\tEffectCreate - Assigning memory for previously created effect on sessionNo %d",
272               sessionNo);
273         pContext->pBundledContext = GlobalSessionMemory[sessionNo].pBundledContext;
274     }
275     ALOGV("\tEffectCreate - pBundledContext is %p", pContext->pBundledContext);
276 
277     pSessionContext = &GlobalSessionMemory[pContext->pBundledContext->SessionNo];
278 
279     // Create each Effect
280     if (memcmp(uuid, &gBassBoostDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
281         // Create Bass Boost
282         ALOGV("\tEffectCreate - Effect to be created is LVM_BASS_BOOST");
283         pSessionContext->bBassInstantiated = LVM_TRUE;
284         pContext->pBundledContext->SamplesToExitCountBb = 0;
285 
286         pContext->itfe = &gLvmEffectInterface;
287         pContext->EffectType = LVM_BASS_BOOST;
288     } else if (memcmp(uuid, &gVirtualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
289         // Create Virtualizer
290         ALOGV("\tEffectCreate - Effect to be created is LVM_VIRTUALIZER");
291         pSessionContext->bVirtualizerInstantiated = LVM_TRUE;
292         pContext->pBundledContext->SamplesToExitCountVirt = 0;
293 
294         pContext->itfe = &gLvmEffectInterface;
295         pContext->EffectType = LVM_VIRTUALIZER;
296     } else if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
297         // Create Equalizer
298         ALOGV("\tEffectCreate - Effect to be created is LVM_EQUALIZER");
299         pSessionContext->bEqualizerInstantiated = LVM_TRUE;
300         pContext->pBundledContext->SamplesToExitCountEq = 0;
301 
302         pContext->itfe = &gLvmEffectInterface;
303         pContext->EffectType = LVM_EQUALIZER;
304     } else if (memcmp(uuid, &gVolumeDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
305         // Create Volume
306         ALOGV("\tEffectCreate - Effect to be created is LVM_VOLUME");
307         pSessionContext->bVolumeInstantiated = LVM_TRUE;
308 
309         pContext->itfe = &gLvmEffectInterface;
310         pContext->EffectType = LVM_VOLUME;
311     } else {
312         ALOGV("\tLVM_ERROR : EffectCreate() invalid UUID");
313         ret = -EINVAL;
314         goto exit;
315     }
316 
317 exit:
318     if (ret != 0) {
319         if (pContext != NULL) {
320             if (newBundle) {
321                 GlobalSessionMemory[sessionNo].bBundledEffectsEnabled = LVM_FALSE;
322                 SessionIndex[sessionNo] = LVM_UNUSED_SESSION;
323                 delete pContext->pBundledContext;
324             }
325             delete pContext;
326         }
327         if (pHandle != NULL) *pHandle = (effect_handle_t)NULL;
328     } else {
329         if (pHandle != NULL) *pHandle = (effect_handle_t)pContext;
330     }
331     ALOGV("\tEffectCreate end..\n\n");
332     return ret;
333 } /* end EffectCreate */
334 
EffectRelease(effect_handle_t handle)335 extern "C" int EffectRelease(effect_handle_t handle) {
336     ALOGV("\n\tEffectRelease start %p", handle);
337     EffectContext* pContext = (EffectContext*)handle;
338 
339     ALOGV("\tEffectRelease start handle: %p, context %p", handle, pContext->pBundledContext);
340     if (pContext == NULL) {
341         ALOGV("\tLVM_ERROR : EffectRelease called with NULL pointer");
342         return -EINVAL;
343     }
344 
345     SessionContext* pSessionContext = &GlobalSessionMemory[pContext->pBundledContext->SessionNo];
346 
347     // Clear the instantiated flag for the effect
348     // protect agains the case where an effect is un-instantiated without being disabled
349 
350     int& effectInDrain = pContext->pBundledContext->effectInDrain;
351     if (pContext->EffectType == LVM_BASS_BOOST) {
352         ALOGV("\tEffectRelease LVM_BASS_BOOST Clearing global intstantiated flag");
353         pSessionContext->bBassInstantiated = LVM_FALSE;
354         if (pContext->pBundledContext->SamplesToExitCountBb > 0) {
355             pContext->pBundledContext->NumberEffectsEnabled--;
356         }
357         pContext->pBundledContext->SamplesToExitCountBb = 0;
358     } else if (pContext->EffectType == LVM_VIRTUALIZER) {
359         ALOGV("\tEffectRelease LVM_VIRTUALIZER Clearing global intstantiated flag");
360         pSessionContext->bVirtualizerInstantiated = LVM_FALSE;
361         if (pContext->pBundledContext->SamplesToExitCountVirt > 0) {
362             pContext->pBundledContext->NumberEffectsEnabled--;
363         }
364         pContext->pBundledContext->SamplesToExitCountVirt = 0;
365     } else if (pContext->EffectType == LVM_EQUALIZER) {
366         ALOGV("\tEffectRelease LVM_EQUALIZER Clearing global intstantiated flag");
367         pSessionContext->bEqualizerInstantiated = LVM_FALSE;
368         if (pContext->pBundledContext->SamplesToExitCountEq > 0) {
369             pContext->pBundledContext->NumberEffectsEnabled--;
370         }
371         pContext->pBundledContext->SamplesToExitCountEq = 0;
372     } else if (pContext->EffectType == LVM_VOLUME) {
373         ALOGV("\tEffectRelease LVM_VOLUME Clearing global intstantiated flag");
374         pSessionContext->bVolumeInstantiated = LVM_FALSE;
375         // There is no samplesToExitCount for volume so we also use the drain flag to check
376         // if we should decrement the effects enabled.
377         if (pContext->pBundledContext->bVolumeEnabled == LVM_TRUE ||
378             (effectInDrain & 1 << LVM_VOLUME) != 0) {
379             pContext->pBundledContext->NumberEffectsEnabled--;
380         }
381     } else {
382         ALOGV("\tLVM_ERROR : EffectRelease : Unsupported effect\n\n\n\n\n\n\n");
383     }
384     effectInDrain &= ~(1 << pContext->EffectType);  // no need to drain if released
385 
386     // Disable effect, in this case ignore errors (return codes)
387     // if an effect has already been disabled
388     Effect_setEnabled(pContext, LVM_FALSE);
389 
390     // if all effects are no longer instantiaed free the lvm memory and delete BundledEffectContext
391     if ((pSessionContext->bBassInstantiated == LVM_FALSE) &&
392         (pSessionContext->bVolumeInstantiated == LVM_FALSE) &&
393         (pSessionContext->bEqualizerInstantiated == LVM_FALSE) &&
394         (pSessionContext->bVirtualizerInstantiated == LVM_FALSE)) {
395         // Clear the SessionIndex
396         for (int i = 0; i < LVM_MAX_SESSIONS; i++) {
397             if (SessionIndex[i] == pContext->pBundledContext->SessionId) {
398                 SessionIndex[i] = LVM_UNUSED_SESSION;
399                 ALOGV("\tEffectRelease: Clearing SessionIndex SessionNo %d for SessionId %d\n", i,
400                       pContext->pBundledContext->SessionId);
401                 break;
402             }
403         }
404 
405         ALOGV("\tEffectRelease: All effects are no longer instantiated\n");
406         pSessionContext->bBundledEffectsEnabled = LVM_FALSE;
407         pSessionContext->pBundledContext = LVM_NULL;
408         ALOGV("\tEffectRelease: Freeing LVM Bundle memory\n");
409         LVM_DelInstanceHandle(&pContext->pBundledContext->hInstance);
410         ALOGV("\tEffectRelease: Deleting LVM Bundle context %p\n", pContext->pBundledContext);
411         if (pContext->pBundledContext->workBuffer != NULL) {
412             free(pContext->pBundledContext->workBuffer);
413         }
414         delete pContext->pBundledContext;
415         pContext->pBundledContext = LVM_NULL;
416     }
417     // free the effect context for current effect
418     delete pContext;
419 
420     ALOGV("\tEffectRelease end\n");
421     return 0;
422 
423 } /* end EffectRelease */
424 
EffectGetDescriptor(const effect_uuid_t * uuid,effect_descriptor_t * pDescriptor)425 extern "C" int EffectGetDescriptor(const effect_uuid_t* uuid, effect_descriptor_t* pDescriptor) {
426     const effect_descriptor_t* desc = NULL;
427 
428     if (pDescriptor == NULL || uuid == NULL) {
429         ALOGV("EffectGetDescriptor() called with NULL pointer");
430         return -EINVAL;
431     }
432 
433     if (memcmp(uuid, &gBassBoostDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
434         desc = &gBassBoostDescriptor;
435     } else if (memcmp(uuid, &gVirtualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
436         desc = &gVirtualizerDescriptor;
437     } else if (memcmp(uuid, &gEqualizerDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
438         desc = &gEqualizerDescriptor;
439     } else if (memcmp(uuid, &gVolumeDescriptor.uuid, sizeof(effect_uuid_t)) == 0) {
440         desc = &gVolumeDescriptor;
441     }
442 
443     if (desc == NULL) {
444         return -EINVAL;
445     }
446 
447     *pDescriptor = *desc;
448 
449     return 0;
450 } /* end EffectGetDescriptor */
451 
LvmGlobalBundle_init()452 void LvmGlobalBundle_init() {
453     ALOGV("\tLvmGlobalBundle_init start");
454     for (int i = 0; i < LVM_MAX_SESSIONS; i++) {
455         GlobalSessionMemory[i].bBundledEffectsEnabled = LVM_FALSE;
456         GlobalSessionMemory[i].bVolumeInstantiated = LVM_FALSE;
457         GlobalSessionMemory[i].bEqualizerInstantiated = LVM_FALSE;
458         GlobalSessionMemory[i].bBassInstantiated = LVM_FALSE;
459         GlobalSessionMemory[i].bVirtualizerInstantiated = LVM_FALSE;
460         GlobalSessionMemory[i].pBundledContext = LVM_NULL;
461 
462         SessionIndex[i] = LVM_UNUSED_SESSION;
463     }
464     return;
465 }
466 //----------------------------------------------------------------------------
467 // LvmBundle_init()
468 //----------------------------------------------------------------------------
469 // Purpose: Initialize engine with default configuration, creates instance
470 // with all effects disabled.
471 //
472 // Inputs:
473 //  pContext:   effect engine context
474 //
475 // Outputs:
476 //
477 //----------------------------------------------------------------------------
478 
LvmBundle_init(EffectContext * pContext)479 int LvmBundle_init(EffectContext* pContext) {
480     ALOGV("\tLvmBundle_init start");
481 
482     pContext->config.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
483     pContext->config.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
484     pContext->config.inputCfg.format = EFFECT_BUFFER_FORMAT;
485     pContext->config.inputCfg.samplingRate = 44100;
486     pContext->config.inputCfg.bufferProvider.getBuffer = NULL;
487     pContext->config.inputCfg.bufferProvider.releaseBuffer = NULL;
488     pContext->config.inputCfg.bufferProvider.cookie = NULL;
489     pContext->config.inputCfg.mask = EFFECT_CONFIG_ALL;
490     pContext->config.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE;
491     pContext->config.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
492     pContext->config.outputCfg.format = EFFECT_BUFFER_FORMAT;
493     pContext->config.outputCfg.samplingRate = 44100;
494     pContext->config.outputCfg.bufferProvider.getBuffer = NULL;
495     pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
496     pContext->config.outputCfg.bufferProvider.cookie = NULL;
497     pContext->config.outputCfg.mask = EFFECT_CONFIG_ALL;
498 
499     CHECK_ARG(pContext != NULL);
500 
501     if (pContext->pBundledContext->hInstance != NULL) {
502         ALOGV("\tLvmBundle_init pContext->pBassBoost != NULL "
503               "-> Calling pContext->pBassBoost->free()");
504         LVM_DelInstanceHandle(&pContext->pBundledContext->hInstance);
505 
506         ALOGV("\tLvmBundle_init pContext->pBassBoost != NULL "
507               "-> Called pContext->pBassBoost->free()");
508     }
509 
510     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
511     LVM_ControlParams_t params;                  /* Control Parameters */
512     LVM_InstParams_t InstParams;                 /* Instance parameters */
513     LVM_EQNB_BandDef_t BandDefs[MAX_NUM_BANDS];  /* Equaliser band definitions */
514     LVM_HeadroomParams_t HeadroomParams;         /* Headroom parameters */
515     LVM_HeadroomBandDef_t HeadroomBandDef[LVM_HEADROOM_MAX_NBANDS];
516 
517     /* Set the capabilities */
518     InstParams.BufferMode = LVM_UNMANAGED_BUFFERS;
519     InstParams.MaxBlockSize = MAX_CALL_SIZE;
520     InstParams.EQNB_NumBands = MAX_NUM_BANDS;
521     InstParams.PSA_Included = LVM_PSA_ON;
522 
523     LvmStatus = LVM_GetInstanceHandle(&pContext->pBundledContext->hInstance, &InstParams);
524 
525     LVM_ERROR_CHECK(LvmStatus, "LVM_GetInstanceHandle", "LvmBundle_init")
526     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
527 
528     ALOGV("\tLvmBundle_init CreateInstance Successfully called LVM_GetInstanceHandle\n");
529 
530     /* Set the initial process parameters */
531     /* General parameters */
532     params.OperatingMode = LVM_MODE_ON;
533     params.SampleRate = LVM_FS_44100;
534     params.SourceFormat = LVM_STEREO;
535     params.SpeakerType = LVM_HEADPHONES;
536 
537     pContext->pBundledContext->SampleRate = LVM_FS_44100;
538     pContext->pBundledContext->ChMask = AUDIO_CHANNEL_OUT_STEREO;
539 
540     /* Concert Sound parameters */
541     params.VirtualizerOperatingMode = LVM_MODE_OFF;
542     params.VirtualizerType = LVM_CONCERTSOUND;
543     params.VirtualizerReverbLevel = 100;
544     params.CS_EffectLevel = LVM_CS_EFFECT_NONE;
545 
546     /* N-Band Equaliser parameters */
547     params.EQNB_OperatingMode = LVM_EQNB_OFF;
548     params.EQNB_NBands = FIVEBAND_NUMBANDS;
549     params.pEQNB_BandDefinition = &BandDefs[0];
550 
551     for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
552         BandDefs[i].Frequency = EQNB_5BandPresetsFrequencies[i];
553         BandDefs[i].QFactor = EQNB_5BandPresetsQFactors[i];
554         BandDefs[i].Gain = EQNB_5BandSoftPresets[i];
555     }
556 
557     /* Volume Control parameters */
558     params.VC_EffectLevel = 0;
559     params.VC_Balance = 0;
560 
561     /* Treble Enhancement parameters */
562     params.TE_OperatingMode = LVM_TE_OFF;
563     params.TE_EffectLevel = 0;
564 
565     /* PSA Control parameters */
566     params.PSA_Enable = LVM_PSA_OFF;
567     params.PSA_PeakDecayRate = (LVM_PSA_DecaySpeed_en)0;
568 
569     /* Bass Enhancement parameters */
570     params.BE_OperatingMode = LVM_BE_OFF;
571     params.BE_EffectLevel = 0;
572     params.BE_CentreFreq = LVM_BE_CENTRE_90Hz;
573     params.BE_HPF = LVM_BE_HPF_ON;
574 
575     /* PSA Control parameters */
576     params.PSA_Enable = LVM_PSA_OFF;
577     params.PSA_PeakDecayRate = LVM_PSA_SPEED_MEDIUM;
578 
579     /* TE Control parameters */
580     params.TE_OperatingMode = LVM_TE_OFF;
581     params.TE_EffectLevel = 0;
582 
583     params.NrChannels = audio_channel_count_from_out_mask(AUDIO_CHANNEL_OUT_STEREO);
584     params.ChMask = AUDIO_CHANNEL_OUT_STEREO;
585     /* Activate the initial settings */
586     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &params);
587 
588     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "LvmBundle_init")
589     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
590 
591     ALOGV("\tLvmBundle_init CreateInstance Successfully called LVM_SetControlParameters\n");
592 
593     /* Set the headroom parameters */
594     HeadroomBandDef[0].Limit_Low = 20;
595     HeadroomBandDef[0].Limit_High = 4999;
596     HeadroomBandDef[0].Headroom_Offset = 0;
597     HeadroomBandDef[1].Limit_Low = 5000;
598     HeadroomBandDef[1].Limit_High = 24000;
599     HeadroomBandDef[1].Headroom_Offset = 0;
600     HeadroomParams.pHeadroomDefinition = &HeadroomBandDef[0];
601     HeadroomParams.Headroom_OperatingMode = LVM_HEADROOM_ON;
602     HeadroomParams.NHeadroomBands = 2;
603 
604     LvmStatus = LVM_SetHeadroomParams(pContext->pBundledContext->hInstance, &HeadroomParams);
605 
606     LVM_ERROR_CHECK(LvmStatus, "LVM_SetHeadroomParams", "LvmBundle_init")
607     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
608 
609     ALOGV("\tLvmBundle_init CreateInstance Successfully called LVM_SetHeadroomParams\n");
610     ALOGV("\tLvmBundle_init End");
611     return 0;
612 } /* end LvmBundle_init */
613 
614 //----------------------------------------------------------------------------
615 // LvmBundle_process()
616 //----------------------------------------------------------------------------
617 // Purpose:
618 // Apply LVM Bundle effects
619 //
620 // Inputs:
621 //  pIn:        pointer to stereo float or 16 bit input data
622 //  pOut:       pointer to stereo float or 16 bit output data
623 //  frameCount: Frames to process
624 //  pContext:   effect engine context
625 //  strength    strength to be applied
626 //
627 //  Outputs:
628 //  pOut:       pointer to updated stereo 16 bit output data
629 //
630 //----------------------------------------------------------------------------
LvmBundle_process(effect_buffer_t * pIn,effect_buffer_t * pOut,int frameCount,EffectContext * pContext)631 int LvmBundle_process(effect_buffer_t* pIn, effect_buffer_t* pOut, int frameCount,
632                       EffectContext* pContext) {
633     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
634     effect_buffer_t* pOutTmp;
635     const LVM_INT32 NrChannels =
636             audio_channel_count_from_out_mask(pContext->config.inputCfg.channels);
637 
638     if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE) {
639         pOutTmp = pOut;
640     } else if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
641         if (pContext->pBundledContext->frameCount != frameCount) {
642             if (pContext->pBundledContext->workBuffer != NULL) {
643                 free(pContext->pBundledContext->workBuffer);
644             }
645             pContext->pBundledContext->workBuffer =
646                     (effect_buffer_t*)calloc(frameCount, sizeof(effect_buffer_t) * NrChannels);
647             if (pContext->pBundledContext->workBuffer == NULL) {
648                 return -ENOMEM;
649             }
650             pContext->pBundledContext->frameCount = frameCount;
651         }
652         pOutTmp = pContext->pBundledContext->workBuffer;
653     } else {
654         ALOGV("LVM_ERROR : LvmBundle_process invalid access mode");
655         return -EINVAL;
656     }
657 
658     /* Process the samples */
659     LvmStatus = LVM_Process(pContext->pBundledContext->hInstance, /* Instance handle */
660                             pIn,                                  /* Input buffer */
661                             pOutTmp,                              /* Output buffer */
662                             (LVM_UINT16)frameCount,               /* Number of samples to read */
663                             0);                                   /* Audio Time */
664     LVM_ERROR_CHECK(LvmStatus, "LVM_Process", "LvmBundle_process")
665     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
666 
667     if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
668         for (int i = 0; i < frameCount * NrChannels; i++) {
669             pOut[i] = pOut[i] + pOutTmp[i];
670         }
671     }
672     return 0;
673 } /* end LvmBundle_process */
674 
675 //----------------------------------------------------------------------------
676 // EqualizerUpdateActiveParams()
677 //----------------------------------------------------------------------------
678 // Purpose: Update ActiveParams for Equalizer
679 //
680 // Inputs:
681 //  pContext:   effect engine context
682 //
683 // Outputs:
684 //
685 //----------------------------------------------------------------------------
EqualizerUpdateActiveParams(EffectContext * pContext)686 void EqualizerUpdateActiveParams(EffectContext* pContext) {
687     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
688     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
689 
690     /* Get the current settings */
691     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
692     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "EqualizerUpdateActiveParams")
693     // ALOGV("\tEqualizerUpdateActiveParams Successfully returned from LVM_GetControlParameters\n");
694     // ALOGV("\tEqualizerUpdateActiveParams just Got -> %d\n",
695     //          ActiveParams.pEQNB_BandDefinition[band].Gain);
696 
697     for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
698         ActiveParams.pEQNB_BandDefinition[i].Frequency = EQNB_5BandPresetsFrequencies[i];
699         ActiveParams.pEQNB_BandDefinition[i].QFactor = EQNB_5BandPresetsQFactors[i];
700         ActiveParams.pEQNB_BandDefinition[i].Gain = pContext->pBundledContext->bandGaindB[i];
701     }
702 
703     /* Activate the initial settings */
704     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
705     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "EqualizerUpdateActiveParams")
706     // ALOGV("\tEqualizerUpdateActiveParams just Set -> %d\n",
707     //          ActiveParams.pEQNB_BandDefinition[band].Gain);
708 }
709 
710 //----------------------------------------------------------------------------
711 // LvmEffect_limitLevel()
712 //----------------------------------------------------------------------------
713 // Purpose: limit the overall level to a value less than 0 dB preserving
714 //          the overall EQ band gain and BassBoost relative levels.
715 //
716 // Inputs:
717 //  pContext:   effect engine context
718 //
719 // Outputs:
720 //
721 //----------------------------------------------------------------------------
LvmEffect_limitLevel(EffectContext * pContext)722 void LvmEffect_limitLevel(EffectContext* pContext) {
723     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
724     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
725 
726     /* Get the current settings */
727     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
728     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "LvmEffect_limitLevel")
729     // ALOGV("\tLvmEffect_limitLevel Successfully returned from LVM_GetControlParameters\n");
730     // ALOGV("\tLvmEffect_limitLevel just Got -> %d\n",
731     //          ActiveParams.pEQNB_BandDefinition[band].Gain);
732 
733     int gainCorrection = 0;
734     // Count the energy contribution per band for EQ and BassBoost only if they are active.
735     float energyContribution = 0;
736     float energyCross = 0;
737     float energyBassBoost = 0;
738     float crossCorrection = 0;
739 
740     bool eqEnabled = pContext->pBundledContext->bEqualizerEnabled == LVM_TRUE;
741     bool bbEnabled = pContext->pBundledContext->bBassEnabled == LVM_TRUE;
742     bool viEnabled = pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE;
743 
744     // EQ contribution
745     if (eqEnabled) {
746         for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
747             float bandFactor = pContext->pBundledContext->bandGaindB[i] / 15.0;
748             float bandCoefficient = LimitLevel_bandEnergyCoefficient[i];
749             float bandEnergy = bandFactor * bandCoefficient * bandCoefficient;
750             if (bandEnergy > 0) energyContribution += bandEnergy;
751         }
752 
753         // cross EQ coefficients
754         float bandFactorSum = 0;
755         for (int i = 0; i < FIVEBAND_NUMBANDS - 1; i++) {
756             float bandFactor1 = pContext->pBundledContext->bandGaindB[i] / 15.0;
757             float bandFactor2 = pContext->pBundledContext->bandGaindB[i + 1] / 15.0;
758 
759             if (bandFactor1 > 0 && bandFactor2 > 0) {
760                 float crossEnergy =
761                         bandFactor1 * bandFactor2 * LimitLevel_bandEnergyCrossCoefficient[i];
762                 bandFactorSum += bandFactor1 * bandFactor2;
763 
764                 if (crossEnergy > 0) energyCross += crossEnergy;
765             }
766         }
767         bandFactorSum -= 1.0;
768         if (bandFactorSum > 0) crossCorrection = bandFactorSum * 0.7;
769     }
770 
771     // BassBoost contribution
772     if (bbEnabled) {
773         float boostFactor = (pContext->pBundledContext->BassStrengthSaved) / 1000.0;
774         float boostCoefficient = LimitLevel_bassBoostEnergyCoefficient;
775 
776         energyContribution += boostFactor * boostCoefficient * boostCoefficient;
777 
778         if (eqEnabled) {
779             for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
780                 float bandFactor = pContext->pBundledContext->bandGaindB[i] / 15.0;
781                 float bandCrossCoefficient = LimitLevel_bassBoostEnergyCrossCoefficient[i];
782                 float bandEnergy = boostFactor * bandFactor * bandCrossCoefficient;
783                 if (bandEnergy > 0) energyBassBoost += bandEnergy;
784             }
785         }
786     }
787 
788     // Virtualizer contribution
789     if (viEnabled) {
790         energyContribution +=
791                 LimitLevel_virtualizerContribution * LimitLevel_virtualizerContribution;
792     }
793 
794     double totalEnergyEstimation =
795             sqrt(energyContribution + energyCross + energyBassBoost) - crossCorrection;
796     ALOGV(" TOTAL energy estimation: %0.2f dB", totalEnergyEstimation);
797 
798     // roundoff
799     int maxLevelRound = (int)(totalEnergyEstimation + 0.99);
800     if (maxLevelRound + pContext->pBundledContext->volume > 0) {
801         gainCorrection = maxLevelRound + pContext->pBundledContext->volume;
802     }
803 
804     ActiveParams.VC_EffectLevel = pContext->pBundledContext->volume - gainCorrection;
805     if (ActiveParams.VC_EffectLevel < -96) {
806         ActiveParams.VC_EffectLevel = -96;
807     }
808     ALOGV("\tVol:%d, GainCorrection: %d, Actual vol: %d", pContext->pBundledContext->volume,
809           gainCorrection, ActiveParams.VC_EffectLevel);
810 
811     /* Activate the initial settings */
812     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
813     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "LvmEffect_limitLevel")
814 
815     ALOGV("LVM_SetControlParameters return:%d", (int)LvmStatus);
816     // ALOGV("\tLvmEffect_limitLevel just Set -> %d\n",
817     //          ActiveParams.pEQNB_BandDefinition[band].Gain);
818 
819     // ALOGV("\tLvmEffect_limitLevel just set (-96dB -> 0dB) -> %d\n",ActiveParams.VC_EffectLevel );
820     if (pContext->pBundledContext->firstVolume == LVM_TRUE) {
821         LvmStatus = LVM_SetVolumeNoSmoothing(pContext->pBundledContext->hInstance, &ActiveParams);
822         LVM_ERROR_CHECK(LvmStatus, "LVM_SetVolumeNoSmoothing", "LvmBundle_process")
823         ALOGV("\tLVM_VOLUME: Disabling Smoothing for first volume change to remove spikes/clicks");
824         pContext->pBundledContext->firstVolume = LVM_FALSE;
825     }
826 }
827 
828 //----------------------------------------------------------------------------
829 // LvmEffect_enable()
830 //----------------------------------------------------------------------------
831 // Purpose: Enable the effect in the bundle
832 //
833 // Inputs:
834 //  pContext:   effect engine context
835 //
836 // Outputs:
837 //
838 //----------------------------------------------------------------------------
839 
LvmEffect_enable(EffectContext * pContext)840 int LvmEffect_enable(EffectContext* pContext) {
841     // ALOGV("\tLvmEffect_enable start");
842 
843     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
844     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
845 
846     /* Get the current settings */
847     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
848 
849     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "LvmEffect_enable")
850     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
851     // ALOGV("\tLvmEffect_enable Successfully called LVM_GetControlParameters\n");
852 
853     if (pContext->EffectType == LVM_BASS_BOOST) {
854         ALOGV("\tLvmEffect_enable : Enabling LVM_BASS_BOOST");
855         ActiveParams.BE_OperatingMode = LVM_BE_ON;
856     }
857     if (pContext->EffectType == LVM_VIRTUALIZER) {
858         ALOGV("\tLvmEffect_enable : Enabling LVM_VIRTUALIZER");
859         ActiveParams.VirtualizerOperatingMode = LVM_MODE_ON;
860     }
861     if (pContext->EffectType == LVM_EQUALIZER) {
862         ALOGV("\tLvmEffect_enable : Enabling LVM_EQUALIZER");
863         ActiveParams.EQNB_OperatingMode = LVM_EQNB_ON;
864     }
865     if (pContext->EffectType == LVM_VOLUME) {
866         ALOGV("\tLvmEffect_enable : Enabling LVM_VOLUME");
867     }
868 
869     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
870     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "LvmEffect_enable")
871     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
872 
873     // ALOGV("\tLvmEffect_enable Successfully called LVM_SetControlParameters\n");
874     // ALOGV("\tLvmEffect_enable end");
875     LvmEffect_limitLevel(pContext);
876     return 0;
877 }
878 
879 //----------------------------------------------------------------------------
880 // LvmEffect_disable()
881 //----------------------------------------------------------------------------
882 // Purpose: Disable the effect in the bundle
883 //
884 // Inputs:
885 //  pContext:   effect engine context
886 //
887 // Outputs:
888 //
889 //----------------------------------------------------------------------------
890 
LvmEffect_disable(EffectContext * pContext)891 int LvmEffect_disable(EffectContext* pContext) {
892     // ALOGV("\tLvmEffect_disable start");
893 
894     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
895     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
896     /* Get the current settings */
897     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
898 
899     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "LvmEffect_disable")
900     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
901     // ALOGV("\tLvmEffect_disable Successfully called LVM_GetControlParameters\n");
902 
903     if (pContext->EffectType == LVM_BASS_BOOST) {
904         ALOGV("\tLvmEffect_disable : Disabling LVM_BASS_BOOST");
905         ActiveParams.BE_OperatingMode = LVM_BE_OFF;
906     }
907     if (pContext->EffectType == LVM_VIRTUALIZER) {
908         ALOGV("\tLvmEffect_disable : Disabling LVM_VIRTUALIZER");
909         ActiveParams.VirtualizerOperatingMode = LVM_MODE_OFF;
910     }
911     if (pContext->EffectType == LVM_EQUALIZER) {
912         ALOGV("\tLvmEffect_disable : Disabling LVM_EQUALIZER");
913         ActiveParams.EQNB_OperatingMode = LVM_EQNB_OFF;
914     }
915     if (pContext->EffectType == LVM_VOLUME) {
916         ALOGV("\tLvmEffect_disable : Disabling LVM_VOLUME");
917     }
918 
919     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
920     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "LvmEffect_disable")
921     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
922 
923     // ALOGV("\tLvmEffect_disable Successfully called LVM_SetControlParameters\n");
924     // ALOGV("\tLvmEffect_disable end");
925     LvmEffect_limitLevel(pContext);
926     return 0;
927 }
928 
929 //----------------------------------------------------------------------------
930 // Effect_setConfig()
931 //----------------------------------------------------------------------------
932 // Purpose: Set input and output audio configuration.
933 //
934 // Inputs:
935 //  pContext:   effect engine context
936 //  pConfig:    pointer to effect_config_t structure holding input and output
937 //      configuration parameters
938 //
939 // Outputs:
940 //
941 //----------------------------------------------------------------------------
942 
Effect_setConfig(EffectContext * pContext,effect_config_t * pConfig)943 int Effect_setConfig(EffectContext* pContext, effect_config_t* pConfig) {
944     LVM_Fs_en SampleRate;
945     // ALOGV("\tEffect_setConfig start");
946 
947     CHECK_ARG(pContext != NULL);
948     CHECK_ARG(pConfig != NULL);
949 
950     CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
951     CHECK_ARG(pConfig->inputCfg.channels == pConfig->outputCfg.channels);
952     CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
953     CHECK_ARG(audio_channel_count_from_out_mask(pConfig->inputCfg.channels) <= LVM_MAX_CHANNELS);
954     CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE ||
955               pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
956     CHECK_ARG(pConfig->inputCfg.format == EFFECT_BUFFER_FORMAT);
957     pContext->config = *pConfig;
958     const LVM_INT16 NrChannels = audio_channel_count_from_out_mask(pConfig->inputCfg.channels);
959 
960     SampleRate = lvmFsForSampleRate(pConfig->inputCfg.samplingRate);
961     if (SampleRate == LVM_FS_INVALID) {
962         ALOGV("Effect_setConfig invalid sampling rate %d", pConfig->inputCfg.samplingRate);
963         return -EINVAL;
964     }
965     pContext->pBundledContext->SamplesPerSecond = pConfig->inputCfg.samplingRate * NrChannels;
966 
967     if (pContext->pBundledContext->SampleRate != SampleRate ||
968         pContext->pBundledContext->ChMask != pConfig->inputCfg.channels) {
969         LVM_ControlParams_t ActiveParams;
970         LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS;
971 
972         ALOGV("\tEffect_setConfig change sampling rate to %d", SampleRate);
973 
974         /* Get the current settings */
975         LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
976 
977         LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "Effect_setConfig")
978         if (LvmStatus != LVM_SUCCESS) return -EINVAL;
979 
980         ActiveParams.SampleRate = SampleRate;
981 
982         ActiveParams.NrChannels = NrChannels;
983         ActiveParams.ChMask = pConfig->inputCfg.channels;
984 
985         if (NrChannels == 1) {
986             ActiveParams.SourceFormat = LVM_MONO;
987         } else if (NrChannels == 2) {
988             ActiveParams.SourceFormat = LVM_STEREO;
989         } else if (NrChannels > 2 && NrChannels <= LVM_MAX_CHANNELS) {
990             ActiveParams.SourceFormat = LVM_MULTICHANNEL;
991         } else {
992             return -EINVAL;
993         }
994 
995         LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
996 
997         LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "Effect_setConfig")
998         ALOGV("\tEffect_setConfig Successfully called LVM_SetControlParameters\n");
999         pContext->pBundledContext->SampleRate = SampleRate;
1000         pContext->pBundledContext->ChMask = pConfig->inputCfg.channels;
1001 
1002         LvmEffect_limitLevel(pContext);
1003 
1004     } else {
1005         // ALOGV("\tEffect_setConfig keep sampling rate at %d", SampleRate);
1006     }
1007 
1008     // ALOGV("\tEffect_setConfig End....");
1009     return 0;
1010 } /* end Effect_setConfig */
1011 
1012 //----------------------------------------------------------------------------
1013 // Effect_getConfig()
1014 //----------------------------------------------------------------------------
1015 // Purpose: Get input and output audio configuration.
1016 //
1017 // Inputs:
1018 //  pContext:   effect engine context
1019 //  pConfig:    pointer to effect_config_t structure holding input and output
1020 //      configuration parameters
1021 //
1022 // Outputs:
1023 //
1024 //----------------------------------------------------------------------------
1025 
Effect_getConfig(EffectContext * pContext,effect_config_t * pConfig)1026 void Effect_getConfig(EffectContext* pContext, effect_config_t* pConfig) {
1027     *pConfig = pContext->config;
1028 } /* end Effect_getConfig */
1029 
1030 //----------------------------------------------------------------------------
1031 // BassGetStrength()
1032 //----------------------------------------------------------------------------
1033 // Purpose:
1034 // get the effect strength currently being used, what is actually returned is the strengh that was
1035 // previously used in the set, this is because the app uses a strength in the range 0-1000 while
1036 // the bassboost uses 1-15, so to avoid a quantisation the original set value is used. However the
1037 // actual used value is checked to make sure it corresponds to the one being returned
1038 //
1039 // Inputs:
1040 //  pContext:   effect engine context
1041 //
1042 //----------------------------------------------------------------------------
1043 
BassGetStrength(EffectContext * pContext)1044 uint32_t BassGetStrength(EffectContext* pContext) {
1045     // ALOGV("\tBassGetStrength() (0-1000) -> %d\n", pContext->pBundledContext->BassStrengthSaved);
1046 
1047     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
1048     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
1049     /* Get the current settings */
1050     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1051 
1052     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "BassGetStrength")
1053     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
1054 
1055     // ALOGV("\tBassGetStrength Successfully returned from LVM_GetControlParameters\n");
1056 
1057     /* Check that the strength returned matches the strength that was set earlier */
1058     if (ActiveParams.BE_EffectLevel !=
1059         (LVM_INT16)((15 * pContext->pBundledContext->BassStrengthSaved) / 1000)) {
1060         ALOGV("\tLVM_ERROR : BassGetStrength module strength does not match savedStrength %d %d\n",
1061               ActiveParams.BE_EffectLevel, pContext->pBundledContext->BassStrengthSaved);
1062         return -EINVAL;
1063     }
1064 
1065     // ALOGV("\tBassGetStrength() (0-15)   -> %d\n", ActiveParams.BE_EffectLevel );
1066     // ALOGV("\tBassGetStrength() (saved)  -> %d\n", pContext->pBundledContext->BassStrengthSaved );
1067     return pContext->pBundledContext->BassStrengthSaved;
1068 } /* end BassGetStrength */
1069 
1070 //----------------------------------------------------------------------------
1071 // BassSetStrength()
1072 //----------------------------------------------------------------------------
1073 // Purpose:
1074 // Apply the strength to the BassBosst. Must first be converted from the range 0-1000 to 1-15
1075 //
1076 // Inputs:
1077 //  pContext:   effect engine context
1078 //  strength    strength to be applied
1079 //
1080 //----------------------------------------------------------------------------
1081 
BassSetStrength(EffectContext * pContext,uint32_t strength)1082 void BassSetStrength(EffectContext* pContext, uint32_t strength) {
1083     // ALOGV("\tBassSetStrength(%d)", strength);
1084 
1085     pContext->pBundledContext->BassStrengthSaved = (int)strength;
1086 
1087     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
1088     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
1089 
1090     /* Get the current settings */
1091     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1092 
1093     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "BassSetStrength")
1094     // ALOGV("\tBassSetStrength Successfully returned from LVM_GetControlParameters\n");
1095 
1096     /* Bass Enhancement parameters */
1097     ActiveParams.BE_EffectLevel = (LVM_INT16)((15 * strength) / 1000);
1098     ActiveParams.BE_CentreFreq = LVM_BE_CENTRE_90Hz;
1099 
1100     // ALOGV("\tBassSetStrength() (0-15)   -> %d\n", ActiveParams.BE_EffectLevel );
1101 
1102     /* Activate the initial settings */
1103     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1104 
1105     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "BassSetStrength")
1106     // ALOGV("\tBassSetStrength Successfully called LVM_SetControlParameters\n");
1107 
1108     LvmEffect_limitLevel(pContext);
1109 } /* end BassSetStrength */
1110 
1111 //----------------------------------------------------------------------------
1112 // VirtualizerGetStrength()
1113 //----------------------------------------------------------------------------
1114 // Purpose:
1115 // get the effect strength currently being used, what is actually returned is the strengh that was
1116 // previously used in the set, this is because the app uses a strength in the range 0-1000 while
1117 // the Virtualizer uses 1-100, so to avoid a quantisation the original set value is used.However the
1118 // actual used value is checked to make sure it corresponds to the one being returned
1119 //
1120 // Inputs:
1121 //  pContext:   effect engine context
1122 //
1123 //----------------------------------------------------------------------------
1124 
VirtualizerGetStrength(EffectContext * pContext)1125 uint32_t VirtualizerGetStrength(EffectContext* pContext) {
1126     // ALOGV("\tVirtualizerGetStrength (0-1000) ->
1127     // %d\n",pContext->pBundledContext->VirtStrengthSaved);
1128 
1129     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
1130     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
1131 
1132     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1133 
1134     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VirtualizerGetStrength")
1135     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
1136 
1137     // ALOGV("\tVirtualizerGetStrength Successfully returned from LVM_GetControlParameters\n");
1138     // ALOGV("\tVirtualizerGetStrength() (0-100)   -> %d\n",
1139     // ActiveParams.VirtualizerReverbLevel*10);
1140     return pContext->pBundledContext->VirtStrengthSaved;
1141 } /* end getStrength */
1142 
1143 //----------------------------------------------------------------------------
1144 // VirtualizerSetStrength()
1145 //----------------------------------------------------------------------------
1146 // Purpose:
1147 // Apply the strength to the Virtualizer. Must first be converted from the range 0-1000 to 1-15
1148 //
1149 // Inputs:
1150 //  pContext:   effect engine context
1151 //  strength    strength to be applied
1152 //
1153 //----------------------------------------------------------------------------
1154 
VirtualizerSetStrength(EffectContext * pContext,uint32_t strength)1155 void VirtualizerSetStrength(EffectContext* pContext, uint32_t strength) {
1156     // ALOGV("\tVirtualizerSetStrength(%d)", strength);
1157     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
1158     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
1159 
1160     pContext->pBundledContext->VirtStrengthSaved = (int)strength;
1161 
1162     /* Get the current settings */
1163     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1164 
1165     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VirtualizerSetStrength")
1166     // ALOGV("\tVirtualizerSetStrength Successfully returned from LVM_GetControlParameters\n");
1167 
1168     /* Virtualizer parameters */
1169     ActiveParams.CS_EffectLevel = (int)((strength * 32767) / 1000);
1170 
1171     ALOGV("\tVirtualizerSetStrength() (0-1000)   -> %d\n", strength);
1172     ALOGV("\tVirtualizerSetStrength() (0- 100)   -> %d\n", ActiveParams.CS_EffectLevel);
1173 
1174     /* Activate the initial settings */
1175     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1176     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "VirtualizerSetStrength")
1177     // ALOGV("\tVirtualizerSetStrength Successfully called LVM_SetControlParameters\n\n");
1178     LvmEffect_limitLevel(pContext);
1179 } /* end setStrength */
1180 
1181 //----------------------------------------------------------------------------
1182 // VirtualizerIsDeviceSupported()
1183 //----------------------------------------------------------------------------
1184 // Purpose:
1185 // Check if an audio device type is supported by this implementation
1186 //
1187 // Inputs:
1188 //  deviceType   the type of device that affects the processing (e.g. for binaural vs transaural)
1189 // Output:
1190 //  -EINVAL      if the configuration is not supported or it is unknown
1191 //  0            if the configuration is supported
1192 //----------------------------------------------------------------------------
VirtualizerIsDeviceSupported(audio_devices_t deviceType)1193 int VirtualizerIsDeviceSupported(audio_devices_t deviceType) {
1194     ALOGV("%s: deviceType:%#x", __func__, deviceType);
1195     switch (deviceType) {
1196         case AUDIO_DEVICE_OUT_WIRED_HEADSET:
1197         case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
1198         case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
1199         case AUDIO_DEVICE_OUT_USB_HEADSET:
1200         case AUDIO_DEVICE_OUT_BLE_HEADSET:
1201             // case AUDIO_DEVICE_OUT_USB_DEVICE:  // For USB testing of the virtualizer only.
1202             return 0;
1203         default:
1204             return -EINVAL;
1205     }
1206 }
1207 
1208 //----------------------------------------------------------------------------
1209 // VirtualizerIsConfigurationSupported()
1210 //----------------------------------------------------------------------------
1211 // Purpose:
1212 // Check if a channel mask + audio device type is supported by this implementation
1213 //
1214 // Inputs:
1215 //  channelMask  the channel mask of the input to virtualize
1216 //  deviceType   the type of device that affects the processing (e.g. for binaural vs transaural)
1217 // Output:
1218 //  -EINVAL      if the configuration is not supported or it is unknown
1219 //  0            if the configuration is supported
1220 //----------------------------------------------------------------------------
VirtualizerIsConfigurationSupported(audio_channel_mask_t channelMask,audio_devices_t deviceType)1221 int VirtualizerIsConfigurationSupported(audio_channel_mask_t channelMask,
1222                                         audio_devices_t deviceType) {
1223     uint32_t channelCount = audio_channel_count_from_out_mask(channelMask);
1224     if (channelCount < 1 || channelCount > FCC_2) {  // TODO: update to 8 channels when supported.
1225         return -EINVAL;
1226     }
1227     return VirtualizerIsDeviceSupported(deviceType);
1228 }
1229 
1230 //----------------------------------------------------------------------------
1231 // VirtualizerForceVirtualizationMode()
1232 //----------------------------------------------------------------------------
1233 // Purpose:
1234 // Force the virtualization mode to that of the given audio device
1235 //
1236 // Inputs:
1237 //  pContext     effect engine context
1238 //  forcedDevice the type of device whose virtualization mode we'll always use
1239 // Output:
1240 //  -EINVAL      if the device is not supported or is unknown
1241 //  0            if the device is supported and the virtualization mode forced
1242 //
1243 //----------------------------------------------------------------------------
VirtualizerForceVirtualizationMode(EffectContext * pContext,audio_devices_t forcedDevice)1244 int VirtualizerForceVirtualizationMode(EffectContext* pContext, audio_devices_t forcedDevice) {
1245     ALOGV("VirtualizerForceVirtualizationMode: forcedDev=0x%x enabled=%d tmpDisabled=%d",
1246           forcedDevice, pContext->pBundledContext->bVirtualizerEnabled,
1247           pContext->pBundledContext->bVirtualizerTempDisabled);
1248     int status = 0;
1249     bool useVirtualizer = false;
1250 
1251     if (VirtualizerIsDeviceSupported(forcedDevice) != 0) {
1252         if (forcedDevice != AUDIO_DEVICE_NONE) {
1253             // forced device is not supported, make it behave as a reset of forced mode
1254             forcedDevice = AUDIO_DEVICE_NONE;
1255             // but return an error
1256             status = -EINVAL;
1257         }
1258     }
1259 
1260     if (forcedDevice == AUDIO_DEVICE_NONE) {
1261         // disabling forced virtualization mode:
1262         // verify whether the virtualization should be enabled or disabled
1263         if (VirtualizerIsDeviceSupported(pContext->pBundledContext->nOutputDevice) == 0) {
1264             useVirtualizer = (pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE);
1265         }
1266         pContext->pBundledContext->nVirtualizerForcedDevice = AUDIO_DEVICE_NONE;
1267     } else {
1268         // forcing virtualization mode: here we already know the device is supported
1269         pContext->pBundledContext->nVirtualizerForcedDevice = AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
1270         // only enable for a supported mode, when the effect is enabled
1271         useVirtualizer = (pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE);
1272     }
1273 
1274     if (useVirtualizer) {
1275         if (pContext->pBundledContext->bVirtualizerTempDisabled == LVM_TRUE) {
1276             ALOGV("\tVirtualizerForceVirtualizationMode re-enable LVM_VIRTUALIZER");
1277             android::LvmEffect_enable(pContext);
1278             pContext->pBundledContext->bVirtualizerTempDisabled = LVM_FALSE;
1279         } else {
1280             ALOGV("\tVirtualizerForceVirtualizationMode leaving LVM_VIRTUALIZER enabled");
1281         }
1282     } else {
1283         if (pContext->pBundledContext->bVirtualizerTempDisabled == LVM_FALSE) {
1284             ALOGV("\tVirtualizerForceVirtualizationMode disable LVM_VIRTUALIZER");
1285             android::LvmEffect_disable(pContext);
1286             pContext->pBundledContext->bVirtualizerTempDisabled = LVM_TRUE;
1287         } else {
1288             ALOGV("\tVirtualizerForceVirtualizationMode leaving LVM_VIRTUALIZER disabled");
1289         }
1290     }
1291 
1292     ALOGV("\tafter VirtualizerForceVirtualizationMode: enabled=%d tmpDisabled=%d",
1293           pContext->pBundledContext->bVirtualizerEnabled,
1294           pContext->pBundledContext->bVirtualizerTempDisabled);
1295 
1296     return status;
1297 }
1298 //----------------------------------------------------------------------------
1299 // VirtualizerGetSpeakerAngles()
1300 //----------------------------------------------------------------------------
1301 // Purpose:
1302 // Get the virtual speaker angles for a channel mask + audio device type
1303 // configuration which is guaranteed to be supported by this implementation
1304 //
1305 // Inputs:
1306 //  channelMask:   the channel mask of the input to virtualize
1307 //  deviceType     the type of device that affects the processing (e.g. for binaural vs transaural)
1308 // Input/Output:
1309 //  pSpeakerAngles the array of integer where each speaker angle is written as a triplet in the
1310 //                 following format:
1311 //                    int32_t a bit mask with a single value selected for each speaker, following
1312 //                            the convention of the audio_channel_mask_t type
1313 //                    int32_t a value in degrees expressing the speaker azimuth, where 0 is in front
1314 //                            of the user, 180 behind, -90 to the left, 90 to the right of the user
1315 //                    int32_t a value in degrees expressing the speaker elevation, where 0 is the
1316 //                            horizontal plane, +90 is directly above the user, -90 below
1317 //
1318 //----------------------------------------------------------------------------
VirtualizerGetSpeakerAngles(audio_channel_mask_t channelMask,audio_devices_t,int32_t * pSpeakerAngles)1319 void VirtualizerGetSpeakerAngles(audio_channel_mask_t channelMask,
1320                                  audio_devices_t /* deviceType __unused */,
1321                                  int32_t* pSpeakerAngles) {
1322     // the channel count is guaranteed to be 1 or 2
1323     // the device is guaranteed to be of type headphone
1324     // this virtualizer is always using 2 virtual speakers at -90 and 90deg of azimuth, 0deg of
1325     // elevation but the return information is sized for nbChannels * 3, so we have to consider
1326     // the (false here) case of a single channel, and return only 3 fields.
1327     if (audio_channel_count_from_out_mask(channelMask) == 1) {
1328         *pSpeakerAngles++ = (int32_t)AUDIO_CHANNEL_OUT_MONO;  // same as FRONT_LEFT
1329         *pSpeakerAngles++ = 0;                                // azimuth
1330         *pSpeakerAngles = 0;                                  // elevation
1331     } else {
1332         *pSpeakerAngles++ = (int32_t)AUDIO_CHANNEL_OUT_FRONT_LEFT;
1333         *pSpeakerAngles++ = -90;  // azimuth
1334         *pSpeakerAngles++ = 0;    // elevation
1335         *pSpeakerAngles++ = (int32_t)AUDIO_CHANNEL_OUT_FRONT_RIGHT;
1336         *pSpeakerAngles++ = 90;  // azimuth
1337         *pSpeakerAngles = 0;     // elevation
1338     }
1339 }
1340 
1341 //----------------------------------------------------------------------------
1342 // VirtualizerGetVirtualizationMode()
1343 //----------------------------------------------------------------------------
1344 // Purpose:
1345 // Retrieve the current device whose processing mode is used by this effect
1346 //
1347 // Output:
1348 //   AUDIO_DEVICE_NONE if the effect is not virtualizing
1349 //   or the device type if the effect is virtualizing
1350 //----------------------------------------------------------------------------
VirtualizerGetVirtualizationMode(EffectContext * pContext)1351 audio_devices_t VirtualizerGetVirtualizationMode(EffectContext* pContext) {
1352     audio_devices_t virtDevice = AUDIO_DEVICE_NONE;
1353     if ((pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE) &&
1354         (pContext->pBundledContext->bVirtualizerTempDisabled == LVM_FALSE)) {
1355         if (pContext->pBundledContext->nVirtualizerForcedDevice != AUDIO_DEVICE_NONE) {
1356             // virtualization mode is forced, return that device
1357             virtDevice = pContext->pBundledContext->nVirtualizerForcedDevice;
1358         } else {
1359             // no forced mode, return the current device
1360             virtDevice = pContext->pBundledContext->nOutputDevice;
1361         }
1362     }
1363     ALOGV("VirtualizerGetVirtualizationMode() returning 0x%x", virtDevice);
1364     return virtDevice;
1365 }
1366 
1367 //----------------------------------------------------------------------------
1368 // EqualizerGetBandLevel()
1369 //----------------------------------------------------------------------------
1370 // Purpose: Retrieve the gain currently being used for the band passed in
1371 //
1372 // Inputs:
1373 //  band:       band number
1374 //  pContext:   effect engine context
1375 //
1376 // Outputs:
1377 //
1378 //----------------------------------------------------------------------------
EqualizerGetBandLevel(EffectContext * pContext,int32_t band)1379 int32_t EqualizerGetBandLevel(EffectContext* pContext, int32_t band) {
1380     // ALOGV("\tEqualizerGetBandLevel -> %d\n", pContext->pBundledContext->bandGaindB[band] );
1381     return pContext->pBundledContext->bandGaindB[band] * 100;
1382 }
1383 
1384 //----------------------------------------------------------------------------
1385 // EqualizerSetBandLevel()
1386 //----------------------------------------------------------------------------
1387 // Purpose:
1388 //  Sets gain value for the given band.
1389 //
1390 // Inputs:
1391 //  band:       band number
1392 //  Gain:       Gain to be applied in millibels
1393 //  pContext:   effect engine context
1394 //
1395 // Outputs:
1396 //
1397 //---------------------------------------------------------------------------
EqualizerSetBandLevel(EffectContext * pContext,int band,short Gain)1398 void EqualizerSetBandLevel(EffectContext* pContext, int band, short Gain) {
1399     int gainRounded;
1400     if (Gain > 0) {
1401         gainRounded = (int)((Gain + 50) / 100);
1402     } else {
1403         gainRounded = (int)((Gain - 50) / 100);
1404     }
1405     // ALOGV("\tEqualizerSetBandLevel(%d)->(%d)", Gain, gainRounded);
1406     pContext->pBundledContext->bandGaindB[band] = gainRounded;
1407     pContext->pBundledContext->CurPreset = PRESET_CUSTOM;
1408 
1409     EqualizerUpdateActiveParams(pContext);
1410     LvmEffect_limitLevel(pContext);
1411 }
1412 
1413 //----------------------------------------------------------------------------
1414 // EqualizerGetCentreFrequency()
1415 //----------------------------------------------------------------------------
1416 // Purpose: Retrieve the frequency being used for the band passed in
1417 //
1418 // Inputs:
1419 //  band:       band number
1420 //  pContext:   effect engine context
1421 //
1422 // Outputs:
1423 //
1424 //----------------------------------------------------------------------------
EqualizerGetCentreFrequency(EffectContext * pContext,int32_t band)1425 int32_t EqualizerGetCentreFrequency(EffectContext* pContext, int32_t band) {
1426     int32_t Frequency = 0;
1427 
1428     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
1429     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
1430     LVM_EQNB_BandDef_t* BandDef;
1431     /* Get the current settings */
1432     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1433 
1434     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "EqualizerGetCentreFrequency")
1435 
1436     BandDef = ActiveParams.pEQNB_BandDefinition;
1437     Frequency = (int32_t)BandDef[band].Frequency * 1000;  // Convert to millibels
1438 
1439     // ALOGV("\tEqualizerGetCentreFrequency -> %d\n", Frequency );
1440     // ALOGV("\tEqualizerGetCentreFrequency Successfully returned from LVM_GetControlParameters\n");
1441     return Frequency;
1442 }
1443 
1444 //----------------------------------------------------------------------------
1445 // EqualizerGetBandFreqRange(
1446 //----------------------------------------------------------------------------
1447 // Purpose:
1448 //
1449 // Gets lower and upper boundaries of a band.
1450 // For the high shelf, the low bound is the band frequency and the high
1451 // bound is Nyquist.
1452 // For the peaking filters, they are the gain[dB]/2 points.
1453 //
1454 // Inputs:
1455 //  band:       band number
1456 //  pContext:   effect engine context
1457 //
1458 // Outputs:
1459 //  pLow:       lower band range
1460 //  pLow:       upper band range
1461 //----------------------------------------------------------------------------
EqualizerGetBandFreqRange(EffectContext *,int32_t band,uint32_t * pLow,uint32_t * pHi)1462 int32_t EqualizerGetBandFreqRange(EffectContext* /* pContext __unused */, int32_t band,
1463                                   uint32_t* pLow, uint32_t* pHi) {
1464     *pLow = bandFreqRange[band][0];
1465     *pHi = bandFreqRange[band][1];
1466     return 0;
1467 }
1468 
1469 //----------------------------------------------------------------------------
1470 // EqualizerGetBand(
1471 //----------------------------------------------------------------------------
1472 // Purpose:
1473 //
1474 // Returns the band with the maximum influence on a given frequency.
1475 // Result is unaffected by whether EQ is enabled or not, or by whether
1476 // changes have been committed or not.
1477 //
1478 // Inputs:
1479 //  targetFreq   The target frequency, in millihertz.
1480 //  pContext:    effect engine context
1481 //
1482 // Outputs:
1483 //  pLow:       lower band range
1484 //  pLow:       upper band range
1485 //----------------------------------------------------------------------------
EqualizerGetBand(EffectContext *,uint32_t targetFreq)1486 int32_t EqualizerGetBand(EffectContext* /* pContext __unused */, uint32_t targetFreq) {
1487     int band = 0;
1488 
1489     if (targetFreq < bandFreqRange[0][0]) {
1490         return -EINVAL;
1491     } else if (targetFreq == bandFreqRange[0][0]) {
1492         return 0;
1493     }
1494     for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
1495         if ((targetFreq > bandFreqRange[i][0]) && (targetFreq <= bandFreqRange[i][1])) {
1496             band = i;
1497         }
1498     }
1499     return band;
1500 }
1501 
1502 //----------------------------------------------------------------------------
1503 // EqualizerGetPreset(
1504 //----------------------------------------------------------------------------
1505 // Purpose:
1506 //
1507 // Gets the currently set preset ID.
1508 // Will return PRESET_CUSTOM in case the EQ parameters have been modified
1509 // manually since a preset was set.
1510 //
1511 // Inputs:
1512 //  pContext:    effect engine context
1513 //
1514 //----------------------------------------------------------------------------
EqualizerGetPreset(EffectContext * pContext)1515 int32_t EqualizerGetPreset(EffectContext* pContext) {
1516     return pContext->pBundledContext->CurPreset;
1517 }
1518 
1519 //----------------------------------------------------------------------------
1520 // EqualizerSetPreset(
1521 //----------------------------------------------------------------------------
1522 // Purpose:
1523 //
1524 // Sets the current preset by ID.
1525 // All the band parameters will be overridden.
1526 //
1527 // Inputs:
1528 //  pContext:    effect engine context
1529 //  preset       The preset ID.
1530 //
1531 //----------------------------------------------------------------------------
EqualizerSetPreset(EffectContext * pContext,int preset)1532 void EqualizerSetPreset(EffectContext* pContext, int preset) {
1533     // ALOGV("\tEqualizerSetPreset(%d)", preset);
1534     pContext->pBundledContext->CurPreset = preset;
1535 
1536     // ActiveParams.pEQNB_BandDefinition = &BandDefs[0];
1537     for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
1538         pContext->pBundledContext->bandGaindB[i] =
1539                 EQNB_5BandSoftPresets[i + preset * FIVEBAND_NUMBANDS];
1540     }
1541 
1542     EqualizerUpdateActiveParams(pContext);
1543     LvmEffect_limitLevel(pContext);
1544 
1545     // ALOGV("\tEqualizerSetPreset Successfully called LVM_SetControlParameters\n");
1546     return;
1547 }
1548 
EqualizerGetNumPresets()1549 int32_t EqualizerGetNumPresets() {
1550     return sizeof(gEqualizerPresets) / sizeof(PresetConfig);
1551 }
1552 
1553 //----------------------------------------------------------------------------
1554 // EqualizerGetPresetName(
1555 //----------------------------------------------------------------------------
1556 // Purpose:
1557 // Gets a human-readable name for a preset ID. Will return "Custom" if
1558 // PRESET_CUSTOM is passed.
1559 //
1560 // Inputs:
1561 // preset       The preset ID. Must be less than number of presets.
1562 //
1563 //-------------------------------------------------------------------------
EqualizerGetPresetName(int32_t preset)1564 const char* EqualizerGetPresetName(int32_t preset) {
1565     // ALOGV("\tEqualizerGetPresetName start(%d)", preset);
1566     if (preset == PRESET_CUSTOM) {
1567         return "Custom";
1568     } else {
1569         return gEqualizerPresets[preset].name;
1570     }
1571     // ALOGV("\tEqualizerGetPresetName end(%d)", preset);
1572     return 0;
1573 }
1574 
1575 //----------------------------------------------------------------------------
1576 // VolumeSetVolumeLevel()
1577 //----------------------------------------------------------------------------
1578 // Purpose:
1579 //
1580 // Inputs:
1581 //  pContext:   effect engine context
1582 //  level       level to be applied
1583 //
1584 //----------------------------------------------------------------------------
1585 
VolumeSetVolumeLevel(EffectContext * pContext,int16_t level)1586 int VolumeSetVolumeLevel(EffectContext* pContext, int16_t level) {
1587     if (level > 0 || level < -9600) {
1588         return -EINVAL;
1589     }
1590 
1591     if (pContext->pBundledContext->bMuteEnabled == LVM_TRUE) {
1592         pContext->pBundledContext->levelSaved = level / 100;
1593     } else {
1594         pContext->pBundledContext->volume = level / 100;
1595     }
1596 
1597     LvmEffect_limitLevel(pContext);
1598 
1599     return 0;
1600 } /* end VolumeSetVolumeLevel */
1601 
1602 //----------------------------------------------------------------------------
1603 // VolumeGetVolumeLevel()
1604 //----------------------------------------------------------------------------
1605 // Purpose:
1606 //
1607 // Inputs:
1608 //  pContext:   effect engine context
1609 //
1610 //----------------------------------------------------------------------------
1611 
VolumeGetVolumeLevel(EffectContext * pContext,int16_t * level)1612 int VolumeGetVolumeLevel(EffectContext* pContext, int16_t* level) {
1613     if (pContext->pBundledContext->bMuteEnabled == LVM_TRUE) {
1614         *level = pContext->pBundledContext->levelSaved * 100;
1615     } else {
1616         *level = pContext->pBundledContext->volume * 100;
1617     }
1618     return 0;
1619 } /* end VolumeGetVolumeLevel */
1620 
1621 //----------------------------------------------------------------------------
1622 // VolumeSetMute()
1623 //----------------------------------------------------------------------------
1624 // Purpose:
1625 //
1626 // Inputs:
1627 //  pContext:   effect engine context
1628 //  mute:       enable/disable flag
1629 //
1630 //----------------------------------------------------------------------------
1631 
VolumeSetMute(EffectContext * pContext,uint32_t mute)1632 int32_t VolumeSetMute(EffectContext* pContext, uint32_t mute) {
1633     // ALOGV("\tVolumeSetMute start(%d)", mute);
1634 
1635     pContext->pBundledContext->bMuteEnabled = mute;
1636 
1637     /* Set appropriate volume level */
1638     if (pContext->pBundledContext->bMuteEnabled == LVM_TRUE) {
1639         pContext->pBundledContext->levelSaved = pContext->pBundledContext->volume;
1640         pContext->pBundledContext->volume = -96;
1641     } else {
1642         pContext->pBundledContext->volume = pContext->pBundledContext->levelSaved;
1643     }
1644 
1645     LvmEffect_limitLevel(pContext);
1646 
1647     return 0;
1648 } /* end setMute */
1649 
1650 //----------------------------------------------------------------------------
1651 // VolumeGetMute()
1652 //----------------------------------------------------------------------------
1653 // Purpose:
1654 //
1655 // Inputs:
1656 //  pContext:   effect engine context
1657 //
1658 // Ourputs:
1659 //  mute:       enable/disable flag
1660 //----------------------------------------------------------------------------
1661 
VolumeGetMute(EffectContext * pContext,uint32_t * mute)1662 int32_t VolumeGetMute(EffectContext* pContext, uint32_t* mute) {
1663     // ALOGV("\tVolumeGetMute start");
1664     if ((pContext->pBundledContext->bMuteEnabled == LVM_FALSE) ||
1665         (pContext->pBundledContext->bMuteEnabled == LVM_TRUE)) {
1666         *mute = pContext->pBundledContext->bMuteEnabled;
1667         return 0;
1668     } else {
1669         ALOGV("\tLVM_ERROR : VolumeGetMute read an invalid value from context %d",
1670               pContext->pBundledContext->bMuteEnabled);
1671         return -EINVAL;
1672     }
1673     // ALOGV("\tVolumeGetMute end");
1674 } /* end getMute */
1675 
VolumeConvertStereoPosition(int16_t position)1676 int16_t VolumeConvertStereoPosition(int16_t position) {
1677     int16_t convertedPosition = 0;
1678 
1679     convertedPosition = (int16_t)(((float)position / 1000) * 96);
1680     return convertedPosition;
1681 }
1682 
1683 //----------------------------------------------------------------------------
1684 // VolumeSetStereoPosition()
1685 //----------------------------------------------------------------------------
1686 // Purpose:
1687 //
1688 // Inputs:
1689 //  pContext:       effect engine context
1690 //  position:       stereo position
1691 //
1692 // Outputs:
1693 //----------------------------------------------------------------------------
1694 
VolumeSetStereoPosition(EffectContext * pContext,int16_t position)1695 int VolumeSetStereoPosition(EffectContext* pContext, int16_t position) {
1696     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
1697     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
1698     LVM_INT16 Balance = 0;
1699 
1700     pContext->pBundledContext->positionSaved = position;
1701     Balance = VolumeConvertStereoPosition(pContext->pBundledContext->positionSaved);
1702 
1703     // ALOGV("\tVolumeSetStereoPosition start pContext->pBundledContext->positionSaved = %d",
1704     // pContext->pBundledContext->positionSaved);
1705 
1706     if (pContext->pBundledContext->bStereoPositionEnabled == LVM_TRUE) {
1707         // ALOGV("\tVolumeSetStereoPosition Position to be set is %d %d\n", position, Balance);
1708         pContext->pBundledContext->positionSaved = position;
1709         /* Get the current settings */
1710         LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1711         LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeSetStereoPosition")
1712         if (LvmStatus != LVM_SUCCESS) return -EINVAL;
1713         // ALOGV("\tVolumeSetStereoPosition Successfully returned from LVM_GetControlParameters
1714         // got:"
1715         //     " %d\n", ActiveParams.VC_Balance);
1716 
1717         /* Volume parameters */
1718         ActiveParams.VC_Balance = Balance;
1719         // ALOGV("\tVolumeSetStereoPosition() (-96dB -> +96dB)   -> %d\n", ActiveParams.VC_Balance
1720         // );
1721 
1722         /* Activate the initial settings */
1723         LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1724         LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "VolumeSetStereoPosition")
1725         if (LvmStatus != LVM_SUCCESS) return -EINVAL;
1726 
1727         // ALOGV("\tVolumeSetStereoPosition Successfully called LVM_SetControlParameters\n");
1728 
1729         /* Get the current settings */
1730         LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1731         LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeSetStereoPosition")
1732         if (LvmStatus != LVM_SUCCESS) return -EINVAL;
1733         // ALOGV("\tVolumeSetStereoPosition Successfully returned from LVM_GetControlParameters got:
1734         // "
1735         //     "%d\n", ActiveParams.VC_Balance);
1736     } else {
1737         // ALOGV("\tVolumeSetStereoPosition Position attempting to set, but not enabled %d %d\n",
1738         // position, Balance);
1739     }
1740     // ALOGV("\tVolumeSetStereoPosition end pContext->pBundledContext->positionSaved = %d\n",
1741     // pContext->pBundledContext->positionSaved);
1742     return 0;
1743 } /* end VolumeSetStereoPosition */
1744 
1745 //----------------------------------------------------------------------------
1746 // VolumeGetStereoPosition()
1747 //----------------------------------------------------------------------------
1748 // Purpose:
1749 //
1750 // Inputs:
1751 //  pContext:       effect engine context
1752 //
1753 // Outputs:
1754 //  position:       stereo position
1755 //----------------------------------------------------------------------------
1756 
VolumeGetStereoPosition(EffectContext * pContext,int16_t * position)1757 int32_t VolumeGetStereoPosition(EffectContext* pContext, int16_t* position) {
1758     // ALOGV("\tVolumeGetStereoPosition start");
1759 
1760     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
1761     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
1762     LVM_INT16 balance;
1763 
1764     // ALOGV("\tVolumeGetStereoPosition start pContext->pBundledContext->positionSaved = %d",
1765     // pContext->pBundledContext->positionSaved);
1766 
1767     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1768     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeGetStereoPosition")
1769     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
1770 
1771     // ALOGV("\tVolumeGetStereoPosition -> %d\n", ActiveParams.VC_Balance);
1772     // ALOGV("\tVolumeGetStereoPosition Successfully returned from LVM_GetControlParameters\n");
1773 
1774     balance = VolumeConvertStereoPosition(pContext->pBundledContext->positionSaved);
1775 
1776     if (pContext->pBundledContext->bStereoPositionEnabled == LVM_TRUE) {
1777         if (balance != ActiveParams.VC_Balance) {
1778             return -EINVAL;
1779         }
1780     }
1781     *position = (LVM_INT16)pContext->pBundledContext->positionSaved;  // Convert dB to millibels
1782     // ALOGV("\tVolumeGetStereoPosition end returning pContext->pBundledContext->positionSaved
1783     // =%d\n", pContext->pBundledContext->positionSaved);
1784     return 0;
1785 } /* end VolumeGetStereoPosition */
1786 
1787 //----------------------------------------------------------------------------
1788 // VolumeEnableStereoPosition()
1789 //----------------------------------------------------------------------------
1790 // Purpose:
1791 //
1792 // Inputs:
1793 //  pContext:   effect engine context
1794 //  mute:       enable/disable flag
1795 //
1796 //----------------------------------------------------------------------------
1797 
VolumeEnableStereoPosition(EffectContext * pContext,uint32_t enabled)1798 int32_t VolumeEnableStereoPosition(EffectContext* pContext, uint32_t enabled) {
1799     // ALOGV("\tVolumeEnableStereoPosition start()");
1800 
1801     pContext->pBundledContext->bStereoPositionEnabled = enabled;
1802 
1803     LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
1804     LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
1805 
1806     /* Get the current settings */
1807     LvmStatus = LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1808     LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeEnableStereoPosition")
1809     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
1810 
1811     // ALOGV("\tVolumeEnableStereoPosition Successfully returned from LVM_GetControlParameters\n");
1812     // ALOGV("\tVolumeEnableStereoPosition to %d, position was %d\n",
1813     //     enabled, ActiveParams.VC_Balance );
1814 
1815     /* Set appropriate stereo position */
1816     if (pContext->pBundledContext->bStereoPositionEnabled == LVM_FALSE) {
1817         ActiveParams.VC_Balance = 0;
1818     } else {
1819         ActiveParams.VC_Balance =
1820                 VolumeConvertStereoPosition(pContext->pBundledContext->positionSaved);
1821     }
1822 
1823     /* Activate the initial settings */
1824     LvmStatus = LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
1825     LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "VolumeEnableStereoPosition")
1826     if (LvmStatus != LVM_SUCCESS) return -EINVAL;
1827 
1828     // ALOGV("\tVolumeEnableStereoPosition Successfully called LVM_SetControlParameters\n");
1829     // ALOGV("\tVolumeEnableStereoPosition end()\n");
1830     return 0;
1831 } /* end VolumeEnableStereoPosition */
1832 
1833 //----------------------------------------------------------------------------
1834 // BassBoost_getParameter()
1835 //----------------------------------------------------------------------------
1836 // Purpose:
1837 // Get a BassBoost parameter
1838 //
1839 // Inputs:
1840 //  pBassBoost       - handle to instance data
1841 //  pParam           - pointer to parameter
1842 //  pValue           - pointer to variable to hold retrieved value
1843 //  pValueSize       - pointer to value size: maximum size as input
1844 //
1845 // Outputs:
1846 //  *pValue updated with parameter value
1847 //  *pValueSize updated with actual value size
1848 //
1849 //
1850 // Side Effects:
1851 //
1852 //----------------------------------------------------------------------------
1853 
BassBoost_getParameter(EffectContext * pContext,uint32_t paramSize,void * pParam,uint32_t * pValueSize,void * pValue)1854 int BassBoost_getParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
1855                            uint32_t* pValueSize, void* pValue) {
1856     int status = 0;
1857     int32_t* params = (int32_t*)pParam;
1858 
1859     ALOGVV("%s start", __func__);
1860 
1861     if (paramSize < sizeof(int32_t)) {
1862         ALOGV("%s invalid paramSize: %u", __func__, paramSize);
1863         return -EINVAL;
1864     }
1865     switch (params[0]) {
1866         case BASSBOOST_PARAM_STRENGTH_SUPPORTED:
1867             if (*pValueSize != sizeof(uint32_t)) {  // legacy: check equality here.
1868                 ALOGV("%s BASSBOOST_PARAM_STRENGTH_SUPPORTED invalid *pValueSize %u", __func__,
1869                       *pValueSize);
1870                 status = -EINVAL;
1871                 break;
1872             }
1873             // no need to set *pValueSize
1874 
1875             *(uint32_t*)pValue = 1;
1876             ALOGVV("%s BASSBOOST_PARAM_STRENGTH_SUPPORTED %u", __func__, *(uint32_t*)pValue);
1877             break;
1878 
1879         case BASSBOOST_PARAM_STRENGTH:
1880             if (*pValueSize != sizeof(int16_t)) {  // legacy: check equality here.
1881                 ALOGV("%s BASSBOOST_PARAM_STRENGTH invalid *pValueSize %u", __func__, *pValueSize);
1882                 status = -EINVAL;
1883                 break;
1884             }
1885             // no need to set *pValueSize
1886 
1887             *(int16_t*)pValue = BassGetStrength(pContext);
1888             ALOGVV("%s BASSBOOST_PARAM_STRENGTH %d", __func__, *(int16_t*)pValue);
1889             break;
1890 
1891         default:
1892             ALOGV("%s invalid param %d", __func__, params[0]);
1893             status = -EINVAL;
1894             break;
1895     }
1896 
1897     ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
1898     return status;
1899 } /* end BassBoost_getParameter */
1900 
1901 //----------------------------------------------------------------------------
1902 // BassBoost_setParameter()
1903 //----------------------------------------------------------------------------
1904 // Purpose:
1905 // Set a BassBoost parameter
1906 //
1907 // Inputs:
1908 //  pBassBoost       - handle to instance data
1909 //  pParam           - pointer to parameter
1910 //  pValue           - pointer to value
1911 //
1912 // Outputs:
1913 //
1914 //----------------------------------------------------------------------------
1915 
BassBoost_setParameter(EffectContext * pContext,uint32_t paramSize,void * pParam,uint32_t valueSize,void * pValue)1916 int BassBoost_setParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
1917                            uint32_t valueSize, void* pValue) {
1918     int status = 0;
1919     int32_t* params = (int32_t*)pParam;
1920 
1921     ALOGVV("%s start", __func__);
1922 
1923     if (paramSize != sizeof(int32_t)) {  // legacy: check equality here.
1924         ALOGV("%s invalid paramSize: %u", __func__, paramSize);
1925         return -EINVAL;
1926     }
1927     switch (params[0]) {
1928         case BASSBOOST_PARAM_STRENGTH: {
1929             if (valueSize < sizeof(int16_t)) {
1930                 ALOGV("%s BASSBOOST_PARAM_STRENGTH invalid valueSize: %u", __func__, valueSize);
1931                 status = -EINVAL;
1932                 break;
1933             }
1934 
1935             const int16_t strength = *(int16_t*)pValue;
1936             ALOGVV("%s BASSBOOST_PARAM_STRENGTH %d", __func__, strength);
1937             ALOGVV("%s BASSBOOST_PARAM_STRENGTH Calling BassSetStrength", __func__);
1938             BassSetStrength(pContext, (int32_t)strength);
1939             ALOGVV("%s BASSBOOST_PARAM_STRENGTH Called BassSetStrength", __func__);
1940         } break;
1941 
1942         default:
1943             ALOGV("%s invalid param %d", __func__, params[0]);
1944             status = -EINVAL;
1945             break;
1946     }
1947 
1948     ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
1949     return status;
1950 } /* end BassBoost_setParameter */
1951 
1952 //----------------------------------------------------------------------------
1953 // Virtualizer_getParameter()
1954 //----------------------------------------------------------------------------
1955 // Purpose:
1956 // Get a Virtualizer parameter
1957 //
1958 // Inputs:
1959 //  pVirtualizer     - handle to instance data
1960 //  pParam           - pointer to parameter
1961 //  pValue           - pointer to variable to hold retrieved value
1962 //  pValueSize       - pointer to value size: maximum size as input
1963 //
1964 // Outputs:
1965 //  *pValue updated with parameter value
1966 //  *pValueSize updated with actual value size
1967 //
1968 //
1969 // Side Effects:
1970 //
1971 //----------------------------------------------------------------------------
1972 
Virtualizer_getParameter(EffectContext * pContext,uint32_t paramSize,void * pParam,uint32_t * pValueSize,void * pValue)1973 int Virtualizer_getParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
1974                              uint32_t* pValueSize, void* pValue) {
1975     int status = 0;
1976     int32_t* params = (int32_t*)pParam;
1977 
1978     ALOGVV("%s start", __func__);
1979 
1980     if (paramSize < sizeof(int32_t)) {
1981         ALOGV("%s invalid paramSize: %u", __func__, paramSize);
1982         return -EINVAL;
1983     }
1984     switch (params[0]) {
1985         case VIRTUALIZER_PARAM_STRENGTH_SUPPORTED:
1986             if (*pValueSize != sizeof(uint32_t)) {  // legacy: check equality here.
1987                 ALOGV("%s VIRTUALIZER_PARAM_STRENGTH_SUPPORTED invalid *pValueSize %u", __func__,
1988                       *pValueSize);
1989                 status = -EINVAL;
1990                 break;
1991             }
1992             // no need to set *pValueSize
1993 
1994             *(uint32_t*)pValue = 1;
1995             ALOGVV("%s VIRTUALIZER_PARAM_STRENGTH_SUPPORTED %d", __func__, *(uint32_t*)pValue);
1996             break;
1997 
1998         case VIRTUALIZER_PARAM_STRENGTH:
1999             if (*pValueSize != sizeof(int16_t)) {  // legacy: check equality here.
2000                 ALOGV("%s VIRTUALIZER_PARAM_STRENGTH invalid *pValueSize %u", __func__,
2001                       *pValueSize);
2002                 status = -EINVAL;
2003                 break;
2004             }
2005             // no need to set *pValueSize
2006 
2007             *(int16_t*)pValue = VirtualizerGetStrength(pContext);
2008 
2009             ALOGVV("%s VIRTUALIZER_PARAM_STRENGTH %d", __func__, *(int16_t*)pValue);
2010             break;
2011 
2012         case VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES: {
2013             if (paramSize < 3 * sizeof(int32_t)) {
2014                 ALOGV("%s VIRTUALIZER_PARAM_SPEAKER_ANGLES invalid paramSize: %u", __func__,
2015                       paramSize);
2016                 status = -EINVAL;
2017                 break;
2018             }
2019 
2020             const audio_channel_mask_t channelMask = (audio_channel_mask_t)params[1];
2021             const audio_devices_t deviceType = (audio_devices_t)params[2];
2022             const uint32_t nbChannels = audio_channel_count_from_out_mask(channelMask);
2023             const uint32_t valueSizeRequired = 3 * nbChannels * sizeof(int32_t);
2024             if (*pValueSize < valueSizeRequired) {
2025                 ALOGV("%s VIRTUALIZER_PARAM_SPEAKER_ANGLES invalid *pValueSize %u", __func__,
2026                       *pValueSize);
2027                 status = -EINVAL;
2028                 break;
2029             }
2030             *pValueSize = valueSizeRequired;
2031 
2032             // verify the configuration is supported
2033             status = VirtualizerIsConfigurationSupported(channelMask, deviceType);
2034             if (status == 0) {
2035                 ALOGV("%s VIRTUALIZER_PARAM_VIRTUAL_SPEAKER_ANGLES mask=0x%x device=0x%x", __func__,
2036                       channelMask, deviceType);
2037                 // configuration is supported, get the angles
2038                 VirtualizerGetSpeakerAngles(channelMask, deviceType, (int32_t*)pValue);
2039             }
2040         } break;
2041 
2042         case VIRTUALIZER_PARAM_VIRTUALIZATION_MODE:
2043             if (*pValueSize != sizeof(uint32_t)) {  // legacy: check equality here.
2044                 ALOGV("%s VIRTUALIZER_PARAM_VIRTUALIZATION_MODE invalid *pValueSize %u", __func__,
2045                       *pValueSize);
2046                 status = -EINVAL;
2047                 break;
2048             }
2049             // no need to set *pValueSize
2050 
2051             *(uint32_t*)pValue = (uint32_t)VirtualizerGetVirtualizationMode(pContext);
2052             break;
2053 
2054         default:
2055             ALOGV("%s invalid param %d", __func__, params[0]);
2056             status = -EINVAL;
2057             break;
2058     }
2059 
2060     ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
2061     return status;
2062 } /* end Virtualizer_getParameter */
2063 
2064 //----------------------------------------------------------------------------
2065 // Virtualizer_setParameter()
2066 //----------------------------------------------------------------------------
2067 // Purpose:
2068 // Set a Virtualizer parameter
2069 //
2070 // Inputs:
2071 //  pVirtualizer     - handle to instance data
2072 //  pParam           - pointer to parameter
2073 //  pValue           - pointer to value
2074 //
2075 // Outputs:
2076 //
2077 //----------------------------------------------------------------------------
2078 
Virtualizer_setParameter(EffectContext * pContext,uint32_t paramSize,void * pParam,uint32_t valueSize,void * pValue)2079 int Virtualizer_setParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
2080                              uint32_t valueSize, void* pValue) {
2081     int status = 0;
2082     int32_t* params = (int32_t*)pParam;
2083 
2084     ALOGVV("%s start", __func__);
2085 
2086     if (paramSize != sizeof(int32_t)) {  // legacy: check equality here.
2087         ALOGV("%s invalid paramSize: %u", __func__, paramSize);
2088         return -EINVAL;
2089     }
2090     switch (params[0]) {
2091         case VIRTUALIZER_PARAM_STRENGTH: {
2092             if (valueSize < sizeof(int16_t)) {
2093                 ALOGV("%s VIRTUALIZER_PARAM_STRENGTH invalid valueSize: %u", __func__, valueSize);
2094                 status = -EINVAL;
2095                 break;
2096             }
2097 
2098             const int16_t strength = *(int16_t*)pValue;
2099             ALOGVV("%s VIRTUALIZER_PARAM_STRENGTH %d", __func__, strength);
2100             ALOGVV("%s VIRTUALIZER_PARAM_STRENGTH Calling VirtualizerSetStrength", __func__);
2101             VirtualizerSetStrength(pContext, (int32_t)strength);
2102             ALOGVV("%s VIRTUALIZER_PARAM_STRENGTH Called VirtualizerSetStrength", __func__);
2103         } break;
2104 
2105         case VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE: {
2106             if (valueSize < sizeof(int32_t)) {
2107                 ALOGV("%s VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE invalid valueSize: %u",
2108                       __func__, valueSize);
2109                 android_errorWriteLog(0x534e4554, "64478003");
2110                 status = -EINVAL;
2111                 break;
2112             }
2113 
2114             const audio_devices_t deviceType = (audio_devices_t) * (int32_t*)pValue;
2115             status = VirtualizerForceVirtualizationMode(pContext, deviceType);
2116             ALOGVV("%s VIRTUALIZER_PARAM_FORCE_VIRTUALIZATION_MODE device=%#x result=%d", __func__,
2117                    deviceType, status);
2118         } break;
2119 
2120         default:
2121             ALOGV("%s invalid param %d", __func__, params[0]);
2122             status = -EINVAL;
2123             break;
2124     }
2125 
2126     ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
2127     return status;
2128 } /* end Virtualizer_setParameter */
2129 
2130 //----------------------------------------------------------------------------
2131 // Equalizer_getParameter()
2132 //----------------------------------------------------------------------------
2133 // Purpose:
2134 // Get a Equalizer parameter
2135 //
2136 // Inputs:
2137 //  pEqualizer       - handle to instance data
2138 //  pParam           - pointer to parameter
2139 //  pValue           - pointer to variable to hold retrieved value
2140 //  pValueSize       - pointer to value size: maximum size as input
2141 //
2142 // Outputs:
2143 //  *pValue updated with parameter value
2144 //  *pValueSize updated with actual value size
2145 //
2146 //
2147 // Side Effects:
2148 //
2149 //----------------------------------------------------------------------------
Equalizer_getParameter(EffectContext * pContext,uint32_t paramSize,void * pParam,uint32_t * pValueSize,void * pValue)2150 int Equalizer_getParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
2151                            uint32_t* pValueSize, void* pValue) {
2152     int status = 0;
2153     int32_t* params = (int32_t*)pParam;
2154 
2155     ALOGVV("%s start", __func__);
2156 
2157     if (paramSize < sizeof(int32_t)) {
2158         ALOGV("%s invalid paramSize: %u", __func__, paramSize);
2159         return -EINVAL;
2160     }
2161     switch (params[0]) {
2162         case EQ_PARAM_NUM_BANDS:
2163             if (*pValueSize < sizeof(uint16_t)) {
2164                 ALOGV("%s EQ_PARAM_NUM_BANDS invalid *pValueSize %u", __func__, *pValueSize);
2165                 status = -EINVAL;
2166                 break;
2167             }
2168             *pValueSize = sizeof(uint16_t);
2169 
2170             *(uint16_t*)pValue = (uint16_t)FIVEBAND_NUMBANDS;
2171             ALOGVV("%s EQ_PARAM_NUM_BANDS %u", __func__, *(uint16_t*)pValue);
2172             break;
2173 
2174         case EQ_PARAM_CUR_PRESET:
2175             if (*pValueSize < sizeof(uint16_t)) {
2176                 ALOGV("%s EQ_PARAM_CUR_PRESET invalid *pValueSize %u", __func__, *pValueSize);
2177                 status = -EINVAL;
2178                 break;
2179             }
2180             *pValueSize = sizeof(uint16_t);
2181 
2182             *(uint16_t*)pValue = (uint16_t)EqualizerGetPreset(pContext);
2183             ALOGVV("%s EQ_PARAM_CUR_PRESET %u", __func__, *(uint16_t*)pValue);
2184             break;
2185 
2186         case EQ_PARAM_GET_NUM_OF_PRESETS:
2187             if (*pValueSize < sizeof(uint16_t)) {
2188                 ALOGV("%s EQ_PARAM_GET_NUM_OF_PRESETS invalid *pValueSize %u", __func__,
2189                       *pValueSize);
2190                 status = -EINVAL;
2191                 break;
2192             }
2193             *pValueSize = sizeof(uint16_t);
2194 
2195             *(uint16_t*)pValue = (uint16_t)EqualizerGetNumPresets();
2196             ALOGVV("%s EQ_PARAM_GET_NUM_OF_PRESETS %u", __func__, *(uint16_t*)pValue);
2197             break;
2198 
2199         case EQ_PARAM_GET_BAND: {
2200             if (paramSize < 2 * sizeof(int32_t)) {
2201                 ALOGV("%s EQ_PARAM_GET_BAND invalid paramSize: %u", __func__, paramSize);
2202                 status = -EINVAL;
2203                 break;
2204             }
2205             if (*pValueSize < sizeof(uint16_t)) {
2206                 ALOGV("%s EQ_PARAM_GET_BAND invalid *pValueSize %u", __func__, *pValueSize);
2207                 status = -EINVAL;
2208                 break;
2209             }
2210             *pValueSize = sizeof(uint16_t);
2211 
2212             const int32_t frequency = params[1];
2213             *(uint16_t*)pValue = (uint16_t)EqualizerGetBand(pContext, frequency);
2214             ALOGVV("%s EQ_PARAM_GET_BAND frequency %d, band %u", __func__, frequency,
2215                    *(uint16_t*)pValue);
2216         } break;
2217 
2218         case EQ_PARAM_BAND_LEVEL: {
2219             if (paramSize < 2 * sizeof(int32_t)) {
2220                 ALOGV("%s EQ_PARAM_BAND_LEVEL invalid paramSize %u", __func__, paramSize);
2221                 status = -EINVAL;
2222                 break;
2223             }
2224             if (*pValueSize < sizeof(int16_t)) {
2225                 ALOGV("%s EQ_PARAM_BAND_LEVEL invalid *pValueSize %u", __func__, *pValueSize);
2226                 status = -EINVAL;
2227                 break;
2228             }
2229             *pValueSize = sizeof(int16_t);
2230 
2231             const int32_t band = params[1];
2232             if (band < 0 || band >= FIVEBAND_NUMBANDS) {
2233                 if (band < 0) {
2234                     android_errorWriteLog(0x534e4554, "32438598");
2235                     ALOGW("%s EQ_PARAM_BAND_LEVEL invalid band %d", __func__, band);
2236                 }
2237                 status = -EINVAL;
2238                 break;
2239             }
2240             *(int16_t*)pValue = (int16_t)EqualizerGetBandLevel(pContext, band);
2241             ALOGVV("%s EQ_PARAM_BAND_LEVEL band %d, level %d", __func__, band, *(int16_t*)pValue);
2242         } break;
2243 
2244         case EQ_PARAM_LEVEL_RANGE:
2245             if (*pValueSize < 2 * sizeof(int16_t)) {
2246                 ALOGV("%s EQ_PARAM_LEVEL_RANGE invalid *pValueSize %u", __func__, *pValueSize);
2247                 status = -EINVAL;
2248                 break;
2249             }
2250             *pValueSize = 2 * sizeof(int16_t);
2251 
2252             *(int16_t*)pValue = -1500;
2253             *((int16_t*)pValue + 1) = 1500;
2254             ALOGVV("%s EQ_PARAM_LEVEL_RANGE min %d, max %d", __func__, *(int16_t*)pValue,
2255                    *((int16_t*)pValue + 1));
2256             break;
2257 
2258         case EQ_PARAM_BAND_FREQ_RANGE: {
2259             if (paramSize < 2 * sizeof(int32_t)) {
2260                 ALOGV("%s EQ_PARAM_BAND_FREQ_RANGE invalid paramSize: %u", __func__, paramSize);
2261                 status = -EINVAL;
2262                 break;
2263             }
2264             if (*pValueSize < 2 * sizeof(int32_t)) {
2265                 ALOGV("%s EQ_PARAM_BAND_FREQ_RANGE invalid *pValueSize %u", __func__, *pValueSize);
2266                 status = -EINVAL;
2267                 break;
2268             }
2269             *pValueSize = 2 * sizeof(int32_t);
2270 
2271             const int32_t band = params[1];
2272             if (band < 0 || band >= FIVEBAND_NUMBANDS) {
2273                 if (band < 0) {
2274                     android_errorWriteLog(0x534e4554, "32247948");
2275                     ALOGW("%s EQ_PARAM_BAND_FREQ_RANGE invalid band %d", __func__, band);
2276                 }
2277                 status = -EINVAL;
2278                 break;
2279             }
2280             EqualizerGetBandFreqRange(pContext, band, (uint32_t*)pValue, ((uint32_t*)pValue + 1));
2281             ALOGVV("%s EQ_PARAM_BAND_FREQ_RANGE band %d, min %d, max %d", __func__, band,
2282                    *(int32_t*)pValue, *((int32_t*)pValue + 1));
2283 
2284         } break;
2285 
2286         case EQ_PARAM_CENTER_FREQ: {
2287             if (paramSize < 2 * sizeof(int32_t)) {
2288                 ALOGV("%s EQ_PARAM_CENTER_FREQ invalid paramSize: %u", __func__, paramSize);
2289                 status = -EINVAL;
2290                 break;
2291             }
2292             if (*pValueSize < sizeof(int32_t)) {
2293                 ALOGV("%s EQ_PARAM_CENTER_FREQ invalid *pValueSize %u", __func__, *pValueSize);
2294                 status = -EINVAL;
2295                 break;
2296             }
2297             *pValueSize = sizeof(int32_t);
2298 
2299             const int32_t band = params[1];
2300             if (band < 0 || band >= FIVEBAND_NUMBANDS) {
2301                 status = -EINVAL;
2302                 if (band < 0) {
2303                     android_errorWriteLog(0x534e4554, "32436341");
2304                     ALOGW("%s EQ_PARAM_CENTER_FREQ invalid band %d", __func__, band);
2305                 }
2306                 break;
2307             }
2308             *(int32_t*)pValue = EqualizerGetCentreFrequency(pContext, band);
2309             ALOGVV("%s EQ_PARAM_CENTER_FREQ band %d, frequency %d", __func__, band,
2310                    *(int32_t*)pValue);
2311         } break;
2312 
2313         case EQ_PARAM_GET_PRESET_NAME: {
2314             if (paramSize < 2 * sizeof(int32_t)) {
2315                 ALOGV("%s EQ_PARAM_PRESET_NAME invalid paramSize: %u", __func__, paramSize);
2316                 status = -EINVAL;
2317                 break;
2318             }
2319             if (*pValueSize < 1) {
2320                 android_errorWriteLog(0x534e4554, "37536407");
2321                 status = -EINVAL;
2322                 break;
2323             }
2324 
2325             const int32_t preset = params[1];
2326             if ((preset < 0 && preset != PRESET_CUSTOM) || preset >= EqualizerGetNumPresets()) {
2327                 if (preset < 0) {
2328                     android_errorWriteLog(0x534e4554, "32448258");
2329                     ALOGE("%s EQ_PARAM_GET_PRESET_NAME preset %d", __func__, preset);
2330                 }
2331                 status = -EINVAL;
2332                 break;
2333             }
2334 
2335             char* const name = (char*)pValue;
2336             strncpy(name, EqualizerGetPresetName(preset), *pValueSize - 1);
2337             name[*pValueSize - 1] = 0;
2338             *pValueSize = strlen(name) + 1;
2339             ALOGVV("%s EQ_PARAM_GET_PRESET_NAME preset %d, name %s len %d", __func__, preset, name,
2340                    *pValueSize);
2341 
2342         } break;
2343 
2344         case EQ_PARAM_PROPERTIES: {
2345             constexpr uint32_t requiredValueSize = (2 + FIVEBAND_NUMBANDS) * sizeof(uint16_t);
2346             if (*pValueSize < requiredValueSize) {
2347                 ALOGV("%s EQ_PARAM_PROPERTIES invalid *pValueSize %u", __func__, *pValueSize);
2348                 status = -EINVAL;
2349                 break;
2350             }
2351             *pValueSize = requiredValueSize;
2352 
2353             int16_t* p = (int16_t*)pValue;
2354             ALOGV("%s EQ_PARAM_PROPERTIES", __func__);
2355             p[0] = (int16_t)EqualizerGetPreset(pContext);
2356             p[1] = (int16_t)FIVEBAND_NUMBANDS;
2357             for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
2358                 p[2 + i] = (int16_t)EqualizerGetBandLevel(pContext, i);
2359             }
2360         } break;
2361 
2362         default:
2363             ALOGV("%s invalid param %d", __func__, params[0]);
2364             status = -EINVAL;
2365             break;
2366     }
2367 
2368     ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
2369     return status;
2370 } /* end Equalizer_getParameter */
2371 
2372 //----------------------------------------------------------------------------
2373 // Equalizer_setParameter()
2374 //----------------------------------------------------------------------------
2375 // Purpose:
2376 // Set a Equalizer parameter
2377 //
2378 // Inputs:
2379 //  pEqualizer    - handle to instance data
2380 //  pParam        - pointer to parameter
2381 //  valueSize     - value size
2382 //  pValue        - pointer to value
2383 
2384 //
2385 // Outputs:
2386 //
2387 //----------------------------------------------------------------------------
Equalizer_setParameter(EffectContext * pContext,uint32_t paramSize,void * pParam,uint32_t valueSize,void * pValue)2388 int Equalizer_setParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
2389                            uint32_t valueSize, void* pValue) {
2390     int status = 0;
2391     int32_t* params = (int32_t*)pParam;
2392 
2393     ALOGVV("%s start", __func__);
2394 
2395     if (paramSize < sizeof(int32_t)) {
2396         ALOGV("%s invalid paramSize: %u", __func__, paramSize);
2397         return -EINVAL;
2398     }
2399     switch (params[0]) {
2400         case EQ_PARAM_CUR_PRESET: {
2401             if (valueSize < sizeof(int16_t)) {
2402                 ALOGV("%s EQ_PARAM_CUR_PRESET invalid valueSize %u", __func__, valueSize);
2403                 status = -EINVAL;
2404                 break;
2405             }
2406             const int32_t preset = (int32_t) * (uint16_t*)pValue;
2407 
2408             ALOGVV("%s EQ_PARAM_CUR_PRESET %d", __func__, preset);
2409             if (preset >= EqualizerGetNumPresets() || preset < 0) {
2410                 ALOGV("%s EQ_PARAM_CUR_PRESET invalid preset %d", __func__, preset);
2411                 status = -EINVAL;
2412                 break;
2413             }
2414             EqualizerSetPreset(pContext, preset);
2415         } break;
2416 
2417         case EQ_PARAM_BAND_LEVEL: {
2418             if (paramSize < 2 * sizeof(int32_t)) {
2419                 ALOGV("%s EQ_PARAM_BAND_LEVEL invalid paramSize: %u", __func__, paramSize);
2420                 status = -EINVAL;
2421                 break;
2422             }
2423             if (valueSize < sizeof(int16_t)) {
2424                 ALOGV("%s EQ_PARAM_BAND_LEVEL invalid valueSize %u", __func__, valueSize);
2425                 status = -EINVAL;
2426                 break;
2427             }
2428             const int32_t band = params[1];
2429             const int32_t level = (int32_t) * (int16_t*)pValue;
2430             ALOGVV("%s EQ_PARAM_BAND_LEVEL band %d, level %d", __func__, band, level);
2431             if (band < 0 || band >= FIVEBAND_NUMBANDS) {
2432                 if (band < 0) {
2433                     android_errorWriteLog(0x534e4554, "32095626");
2434                     ALOGE("%s EQ_PARAM_BAND_LEVEL invalid band %d", __func__, band);
2435                 }
2436                 status = -EINVAL;
2437                 break;
2438             }
2439             EqualizerSetBandLevel(pContext, band, level);
2440         } break;
2441 
2442         case EQ_PARAM_PROPERTIES: {
2443             ALOGVV("%s EQ_PARAM_PROPERTIES", __func__);
2444             if (valueSize < sizeof(int16_t)) {
2445                 ALOGV("%s EQ_PARAM_PROPERTIES invalid valueSize %u", __func__, valueSize);
2446                 status = -EINVAL;
2447                 break;
2448             }
2449             int16_t* p = (int16_t*)pValue;
2450             if ((int)p[0] >= EqualizerGetNumPresets()) {
2451                 ALOGV("%s EQ_PARAM_PROPERTIES invalid preset %d", __func__, (int)p[0]);
2452                 status = -EINVAL;
2453                 break;
2454             }
2455             if (p[0] >= 0) {
2456                 EqualizerSetPreset(pContext, (int)p[0]);
2457             } else {
2458                 constexpr uint32_t valueSizeRequired = (2 + FIVEBAND_NUMBANDS) * sizeof(int16_t);
2459                 if (valueSize < valueSizeRequired) {
2460                     android_errorWriteLog(0x534e4554, "37563371");
2461                     ALOGE("%s EQ_PARAM_PROPERTIES invalid valueSize %u < %u", __func__, valueSize,
2462                           valueSizeRequired);
2463                     status = -EINVAL;
2464                     break;
2465                 }
2466                 if ((int)p[1] != FIVEBAND_NUMBANDS) {
2467                     ALOGV("%s EQ_PARAM_PROPERTIES invalid bands %d", __func__, (int)p[1]);
2468                     status = -EINVAL;
2469                     break;
2470                 }
2471                 for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
2472                     EqualizerSetBandLevel(pContext, i, (int)p[2 + i]);
2473                 }
2474             }
2475         } break;
2476 
2477         default:
2478             ALOGV("%s invalid param %d", __func__, params[0]);
2479             status = -EINVAL;
2480             break;
2481     }
2482 
2483     ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
2484     return status;
2485 } /* end Equalizer_setParameter */
2486 
2487 //----------------------------------------------------------------------------
2488 // Volume_getParameter()
2489 //----------------------------------------------------------------------------
2490 // Purpose:
2491 // Get a Volume parameter
2492 //
2493 // Inputs:
2494 //  pVolume          - handle to instance data
2495 //  pParam           - pointer to parameter
2496 //  pValue           - pointer to variable to hold retrieved value
2497 //  pValueSize       - pointer to value size: maximum size as input
2498 //
2499 // Outputs:
2500 //  *pValue updated with parameter value
2501 //  *pValueSize updated with actual value size
2502 //
2503 //
2504 // Side Effects:
2505 //
2506 //----------------------------------------------------------------------------
2507 
Volume_getParameter(EffectContext * pContext,uint32_t paramSize,void * pParam,uint32_t * pValueSize,void * pValue)2508 int Volume_getParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
2509                         uint32_t* pValueSize, void* pValue) {
2510     int status = 0;
2511     int32_t* params = (int32_t*)pParam;
2512 
2513     ALOGVV("%s start", __func__);
2514 
2515     if (paramSize < sizeof(int32_t)) {
2516         ALOGV("%s invalid paramSize: %u", __func__, paramSize);
2517         return -EINVAL;
2518     }
2519     switch (params[0]) {
2520         case VOLUME_PARAM_LEVEL:
2521             if (*pValueSize != sizeof(int16_t)) {  // legacy: check equality here.
2522                 ALOGV("%s VOLUME_PARAM_LEVEL invalid *pValueSize %u", __func__, *pValueSize);
2523                 status = -EINVAL;
2524                 break;
2525             }
2526             // no need to set *pValueSize
2527 
2528             status = VolumeGetVolumeLevel(pContext, (int16_t*)(pValue));
2529             ALOGVV("%s VOLUME_PARAM_LEVEL %d", __func__, *(int16_t*)pValue);
2530             break;
2531 
2532         case VOLUME_PARAM_MAXLEVEL:
2533             if (*pValueSize != sizeof(int16_t)) {  // legacy: check equality here.
2534                 ALOGV("%s VOLUME_PARAM_MAXLEVEL invalid *pValueSize %u", __func__, *pValueSize);
2535                 status = -EINVAL;
2536                 break;
2537             }
2538             // no need to set *pValueSize
2539 
2540             // in millibel
2541             *(int16_t*)pValue = 0;
2542             ALOGVV("%s VOLUME_PARAM_MAXLEVEL %d", __func__, *(int16_t*)pValue);
2543             break;
2544 
2545         case VOLUME_PARAM_STEREOPOSITION:
2546             if (*pValueSize != sizeof(int16_t)) {  // legacy: check equality here.
2547                 ALOGV("%s VOLUME_PARAM_STEREOPOSITION invalid *pValueSize %u", __func__,
2548                       *pValueSize);
2549                 status = -EINVAL;
2550                 break;
2551             }
2552             // no need to set *pValueSize
2553 
2554             VolumeGetStereoPosition(pContext, (int16_t*)pValue);
2555             ALOGVV("%s VOLUME_PARAM_STEREOPOSITION %d", __func__, *(int16_t*)pValue);
2556             break;
2557 
2558         case VOLUME_PARAM_MUTE:
2559             if (*pValueSize < sizeof(uint32_t)) {
2560                 ALOGV("%s VOLUME_PARAM_MUTE invalid *pValueSize %u", __func__, *pValueSize);
2561                 status = -EINVAL;
2562                 break;
2563             }
2564             *pValueSize = sizeof(uint32_t);
2565 
2566             status = VolumeGetMute(pContext, (uint32_t*)pValue);
2567             ALOGV("%s VOLUME_PARAM_MUTE %u", __func__, *(uint32_t*)pValue);
2568             break;
2569 
2570         case VOLUME_PARAM_ENABLESTEREOPOSITION:
2571             if (*pValueSize < sizeof(int32_t)) {
2572                 ALOGV("%s VOLUME_PARAM_ENABLESTEREOPOSITION invalid *pValueSize %u", __func__,
2573                       *pValueSize);
2574                 status = -EINVAL;
2575                 break;
2576             }
2577             *pValueSize = sizeof(int32_t);
2578 
2579             *(int32_t*)pValue = pContext->pBundledContext->bStereoPositionEnabled;
2580             ALOGVV("%s VOLUME_PARAM_ENABLESTEREOPOSITION %d", __func__, *(int32_t*)pValue);
2581 
2582             break;
2583 
2584         default:
2585             ALOGV("%s invalid param %d", __func__, params[0]);
2586             status = -EINVAL;
2587             break;
2588     }
2589 
2590     ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
2591     return status;
2592 } /* end Volume_getParameter */
2593 
2594 //----------------------------------------------------------------------------
2595 // Volume_setParameter()
2596 //----------------------------------------------------------------------------
2597 // Purpose:
2598 // Set a Volume parameter
2599 //
2600 // Inputs:
2601 //  pVolume       - handle to instance data
2602 //  pParam        - pointer to parameter
2603 //  pValue        - pointer to value
2604 //
2605 // Outputs:
2606 //
2607 //----------------------------------------------------------------------------
2608 
Volume_setParameter(EffectContext * pContext,uint32_t paramSize,void * pParam,uint32_t valueSize,void * pValue)2609 int Volume_setParameter(EffectContext* pContext, uint32_t paramSize, void* pParam,
2610                         uint32_t valueSize, void* pValue) {
2611     int status = 0;
2612     int32_t* params = (int32_t*)pParam;
2613 
2614     ALOGVV("%s start", __func__);
2615 
2616     if (paramSize < sizeof(int32_t)) {
2617         ALOGV("%s invalid paramSize: %u", __func__, paramSize);
2618         return -EINVAL;
2619     }
2620     switch (params[0]) {
2621         case VOLUME_PARAM_LEVEL: {
2622             if (valueSize < sizeof(int16_t)) {
2623                 ALOGV("%s VOLUME_PARAM_LEVEL invalid valueSize %u", __func__, valueSize);
2624                 status = -EINVAL;
2625                 break;
2626             }
2627 
2628             const int16_t level = *(int16_t*)pValue;
2629             ALOGVV("%s VOLUME_PARAM_LEVEL %d", __func__, level);
2630             ALOGVV("%s VOLUME_PARAM_LEVEL Calling VolumeSetVolumeLevel", __func__);
2631             status = VolumeSetVolumeLevel(pContext, level);
2632             ALOGVV("%s VOLUME_PARAM_LEVEL Called VolumeSetVolumeLevel", __func__);
2633         } break;
2634 
2635         case VOLUME_PARAM_MUTE: {
2636             if (valueSize < sizeof(uint32_t)) {
2637                 ALOGV("%s VOLUME_PARAM_MUTE invalid valueSize %u", __func__, valueSize);
2638                 android_errorWriteLog(0x534e4554, "64477217");
2639                 status = -EINVAL;
2640                 break;
2641             }
2642 
2643             const uint32_t mute = *(uint32_t*)pValue;
2644             ALOGVV("%s VOLUME_PARAM_MUTE %d", __func__, mute);
2645             ALOGVV("%s VOLUME_PARAM_MUTE Calling VolumeSetMute", __func__);
2646             status = VolumeSetMute(pContext, mute);
2647             ALOGVV("%s VOLUME_PARAM_MUTE Called VolumeSetMute", __func__);
2648         } break;
2649 
2650         case VOLUME_PARAM_ENABLESTEREOPOSITION: {
2651             if (valueSize < sizeof(uint32_t)) {
2652                 ALOGV("%s VOLUME_PARAM_ENABLESTEREOPOSITION invalid valueSize %u", __func__,
2653                       valueSize);
2654                 status = -EINVAL;
2655                 break;
2656             }
2657 
2658             const uint32_t positionEnabled = *(uint32_t*)pValue;
2659             status = VolumeEnableStereoPosition(pContext, positionEnabled)
2660                              ?: VolumeSetStereoPosition(pContext,
2661                                                         pContext->pBundledContext->positionSaved);
2662             ALOGVV("%s VOLUME_PARAM_ENABLESTEREOPOSITION called", __func__);
2663         } break;
2664 
2665         case VOLUME_PARAM_STEREOPOSITION: {
2666             if (valueSize < sizeof(int16_t)) {
2667                 ALOGV("%s VOLUME_PARAM_STEREOPOSITION invalid valueSize %u", __func__, valueSize);
2668                 status = -EINVAL;
2669                 break;
2670             }
2671 
2672             const int16_t position = *(int16_t*)pValue;
2673             ALOGVV("%s VOLUME_PARAM_STEREOPOSITION %d", __func__, position);
2674             ALOGVV("%s VOLUME_PARAM_STEREOPOSITION Calling VolumeSetStereoPosition", __func__);
2675             status = VolumeSetStereoPosition(pContext, position);
2676             ALOGVV("%s VOLUME_PARAM_STEREOPOSITION Called VolumeSetStereoPosition", __func__);
2677         } break;
2678 
2679         default:
2680             ALOGV("%s invalid param %d", __func__, params[0]);
2681             status = -EINVAL;
2682             break;
2683     }
2684 
2685     ALOGVV("%s end param: %d, status: %d", __func__, params[0], status);
2686     return status;
2687 } /* end Volume_setParameter */
2688 
2689 /****************************************************************************************
2690  * Name : LVC_ToDB_s32Tos16()
2691  *  Input       : Signed 32-bit integer
2692  *  Output      : Signed 16-bit integer
2693  *                  MSB (16) = sign bit
2694  *                  (15->05) = integer part
2695  *                  (04->01) = decimal part
2696  *  Returns     : Db value with respect to full scale
2697  *  Description :
2698  *  Remarks     :
2699  ****************************************************************************************/
2700 
LVC_ToDB_s32Tos16(LVM_INT32 Lin_fix)2701 LVM_INT16 LVC_ToDB_s32Tos16(LVM_INT32 Lin_fix) {
2702     LVM_INT16 db_fix;
2703     LVM_INT16 Shift;
2704     LVM_INT16 SmallRemainder;
2705     LVM_UINT32 Remainder = (LVM_UINT32)Lin_fix;
2706 
2707     /* Count leading bits, 1 cycle in assembly*/
2708     for (Shift = 0; Shift < 32; Shift++) {
2709         if ((Remainder & 0x80000000U) != 0) {
2710             break;
2711         }
2712         Remainder = Remainder << 1;
2713     }
2714 
2715     /*
2716      * Based on the approximation equation (for Q11.4 format):
2717      *
2718      * dB = -96 * Shift + 16 * (8 * Remainder - 2 * Remainder^2)
2719      */
2720     db_fix = (LVM_INT16)(-96 * Shift); /* Six dB steps in Q11.4 format*/
2721     SmallRemainder = (LVM_INT16)((Remainder & 0x7fffffff) >> 24);
2722     db_fix = (LVM_INT16)(db_fix + SmallRemainder);
2723     SmallRemainder = (LVM_INT16)(SmallRemainder * SmallRemainder);
2724     db_fix = (LVM_INT16)(db_fix - (LVM_INT16)((LVM_UINT16)SmallRemainder >> 9));
2725 
2726     /* Correct for small offset */
2727     db_fix = (LVM_INT16)(db_fix - 5);
2728 
2729     return db_fix;
2730 }
2731 
2732 //----------------------------------------------------------------------------
2733 // Effect_setEnabled()
2734 //----------------------------------------------------------------------------
2735 // Purpose:
2736 // Enable or disable effect
2737 //
2738 // Inputs:
2739 //  pContext      - pointer to effect context
2740 //  enabled       - true if enabling the effect, false otherwise
2741 //
2742 // Outputs:
2743 //
2744 //----------------------------------------------------------------------------
2745 
Effect_setEnabled(EffectContext * pContext,bool enabled)2746 int Effect_setEnabled(EffectContext* pContext, bool enabled) {
2747     ALOGV("%s effectType %d, enabled %d, currently enabled %d", __func__, pContext->EffectType,
2748           enabled, pContext->pBundledContext->NumberEffectsEnabled);
2749     int& effectInDrain = pContext->pBundledContext->effectInDrain;
2750     if (enabled) {
2751         // Bass boost or Virtualizer can be temporarily disabled if playing over device speaker due
2752         // to their nature.
2753         bool tempDisabled = false;
2754         switch (pContext->EffectType) {
2755             case LVM_BASS_BOOST:
2756                 if (pContext->pBundledContext->bBassEnabled == LVM_TRUE) {
2757                     ALOGV("\tEffect_setEnabled() LVM_BASS_BOOST is already enabled");
2758                     return -EINVAL;
2759                 }
2760                 if (pContext->pBundledContext->SamplesToExitCountBb <= 0) {
2761                     pContext->pBundledContext->NumberEffectsEnabled++;
2762                 }
2763                 effectInDrain &= ~(1 << LVM_BASS_BOOST);
2764                 pContext->pBundledContext->SamplesToExitCountBb =
2765                         (LVM_INT32)(pContext->pBundledContext->SamplesPerSecond * 0.1);
2766                 pContext->pBundledContext->bBassEnabled = LVM_TRUE;
2767                 tempDisabled = pContext->pBundledContext->bBassTempDisabled;
2768                 break;
2769             case LVM_EQUALIZER:
2770                 if (pContext->pBundledContext->bEqualizerEnabled == LVM_TRUE) {
2771                     ALOGV("\tEffect_setEnabled() LVM_EQUALIZER is already enabled");
2772                     return -EINVAL;
2773                 }
2774                 if (pContext->pBundledContext->SamplesToExitCountEq <= 0) {
2775                     pContext->pBundledContext->NumberEffectsEnabled++;
2776                 }
2777                 effectInDrain &= ~(1 << LVM_EQUALIZER);
2778                 pContext->pBundledContext->SamplesToExitCountEq =
2779                         (LVM_INT32)(pContext->pBundledContext->SamplesPerSecond * 0.1);
2780                 pContext->pBundledContext->bEqualizerEnabled = LVM_TRUE;
2781                 break;
2782             case LVM_VIRTUALIZER:
2783                 if (pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE) {
2784                     ALOGV("\tEffect_setEnabled() LVM_VIRTUALIZER is already enabled");
2785                     return -EINVAL;
2786                 }
2787                 if (pContext->pBundledContext->SamplesToExitCountVirt <= 0) {
2788                     pContext->pBundledContext->NumberEffectsEnabled++;
2789                 }
2790                 effectInDrain &= ~(1 << LVM_VIRTUALIZER);
2791                 pContext->pBundledContext->SamplesToExitCountVirt =
2792                         (LVM_INT32)(pContext->pBundledContext->SamplesPerSecond * 0.1);
2793                 pContext->pBundledContext->bVirtualizerEnabled = LVM_TRUE;
2794                 tempDisabled = pContext->pBundledContext->bVirtualizerTempDisabled;
2795                 break;
2796             case LVM_VOLUME:
2797                 if (pContext->pBundledContext->bVolumeEnabled == LVM_TRUE) {
2798                     ALOGV("\tEffect_setEnabled() LVM_VOLUME is already enabled");
2799                     return -EINVAL;
2800                 }
2801                 if ((effectInDrain & 1 << LVM_VOLUME) == 0) {
2802                     pContext->pBundledContext->NumberEffectsEnabled++;
2803                 }
2804                 effectInDrain &= ~(1 << LVM_VOLUME);
2805                 pContext->pBundledContext->bVolumeEnabled = LVM_TRUE;
2806                 break;
2807             default:
2808                 ALOGV("\tEffect_setEnabled() invalid effect type");
2809                 return -EINVAL;
2810         }
2811         if (!tempDisabled) {
2812             LvmEffect_enable(pContext);
2813         }
2814     } else {
2815         switch (pContext->EffectType) {
2816             case LVM_BASS_BOOST:
2817                 if (pContext->pBundledContext->bBassEnabled == LVM_FALSE) {
2818                     ALOGV("\tEffect_setEnabled() LVM_BASS_BOOST is already disabled");
2819                     return -EINVAL;
2820                 }
2821                 pContext->pBundledContext->bBassEnabled = LVM_FALSE;
2822                 effectInDrain |= 1 << LVM_BASS_BOOST;
2823                 break;
2824             case LVM_EQUALIZER:
2825                 if (pContext->pBundledContext->bEqualizerEnabled == LVM_FALSE) {
2826                     ALOGV("\tEffect_setEnabled() LVM_EQUALIZER is already disabled");
2827                     return -EINVAL;
2828                 }
2829                 pContext->pBundledContext->bEqualizerEnabled = LVM_FALSE;
2830                 effectInDrain |= 1 << LVM_EQUALIZER;
2831                 break;
2832             case LVM_VIRTUALIZER:
2833                 if (pContext->pBundledContext->bVirtualizerEnabled == LVM_FALSE) {
2834                     ALOGV("\tEffect_setEnabled() LVM_VIRTUALIZER is already disabled");
2835                     return -EINVAL;
2836                 }
2837                 pContext->pBundledContext->bVirtualizerEnabled = LVM_FALSE;
2838                 effectInDrain |= 1 << LVM_VIRTUALIZER;
2839                 break;
2840             case LVM_VOLUME:
2841                 if (pContext->pBundledContext->bVolumeEnabled == LVM_FALSE) {
2842                     ALOGV("\tEffect_setEnabled() LVM_VOLUME is already disabled");
2843                     return -EINVAL;
2844                 }
2845                 pContext->pBundledContext->bVolumeEnabled = LVM_FALSE;
2846                 effectInDrain |= 1 << LVM_VOLUME;
2847                 break;
2848             default:
2849                 ALOGV("\tEffect_setEnabled() invalid effect type");
2850                 return -EINVAL;
2851         }
2852         LvmEffect_disable(pContext);
2853     }
2854 
2855     return 0;
2856 }
2857 
2858 //----------------------------------------------------------------------------
2859 // LVC_Convert_VolToDb()
2860 //----------------------------------------------------------------------------
2861 // Purpose:
2862 // Convery volume in Q24 to dB
2863 //
2864 // Inputs:
2865 //  vol:   Q.24 volume dB
2866 //
2867 //-----------------------------------------------------------------------
2868 
LVC_Convert_VolToDb(uint32_t vol)2869 int16_t LVC_Convert_VolToDb(uint32_t vol) {
2870     int16_t dB;
2871 
2872     dB = LVC_ToDB_s32Tos16(vol << 7);
2873     dB = (dB + 8) >> 4;
2874     dB = (dB < -96) ? -96 : dB;
2875 
2876     return dB;
2877 }
2878 
2879 }  // namespace
2880 }  // namespace android
2881 
2882 extern "C" {
2883 /* Effect Control Interface Implementation: Process */
Effect_process(effect_handle_t self,audio_buffer_t * inBuffer,audio_buffer_t * outBuffer)2884 int Effect_process(effect_handle_t self, audio_buffer_t* inBuffer, audio_buffer_t* outBuffer) {
2885     EffectContext* pContext = (EffectContext*)self;
2886     int status = 0;
2887     int processStatus = 0;
2888     const int NrChannels = audio_channel_count_from_out_mask(pContext->config.inputCfg.channels);
2889 
2890     // ALOGV("\tEffect_process Start : Enabled = %d     Called = %d (%8d %8d %8d)",
2891     // pContext->pBundledContext->NumberEffectsEnabled,pContext->pBundledContext->NumberEffectsCalled,
2892     //    pContext->pBundledContext->SamplesToExitCountBb,
2893     //    pContext->pBundledContext->SamplesToExitCountVirt,
2894     //    pContext->pBundledContext->SamplesToExitCountEq);
2895 
2896     if (pContext == NULL) {
2897         ALOGV("\tLVM_ERROR : Effect_process() ERROR pContext == NULL");
2898         return -EINVAL;
2899     }
2900 
2901     // if(pContext->EffectType == LVM_BASS_BOOST){
2902     //  ALOGV("\tEffect_process: Effect type is BASS_BOOST");
2903     //}else if(pContext->EffectType == LVM_EQUALIZER){
2904     //  ALOGV("\tEffect_process: Effect type is LVM_EQUALIZER");
2905     //}else if(pContext->EffectType == LVM_VIRTUALIZER){
2906     //  ALOGV("\tEffect_process: Effect type is LVM_VIRTUALIZER");
2907     //}
2908 
2909     if (inBuffer == NULL || inBuffer->raw == NULL || outBuffer == NULL || outBuffer->raw == NULL ||
2910         inBuffer->frameCount != outBuffer->frameCount) {
2911         ALOGV("\tLVM_ERROR : Effect_process() ERROR NULL INPUT POINTER OR FRAME COUNT IS WRONG");
2912         return -EINVAL;
2913     }
2914 
2915     int& effectProcessCalled = pContext->pBundledContext->effectProcessCalled;
2916     int& effectInDrain = pContext->pBundledContext->effectInDrain;
2917     if ((effectProcessCalled & 1 << pContext->EffectType) != 0) {
2918         ALOGW("Effect %d already called", pContext->EffectType);
2919         const int undrainedEffects = effectInDrain & ~effectProcessCalled;
2920         if ((undrainedEffects & 1 << LVM_BASS_BOOST) != 0) {
2921             ALOGW("Draining BASS_BOOST");
2922             pContext->pBundledContext->SamplesToExitCountBb = 0;
2923             --pContext->pBundledContext->NumberEffectsEnabled;
2924             effectInDrain &= ~(1 << LVM_BASS_BOOST);
2925         }
2926         if ((undrainedEffects & 1 << LVM_EQUALIZER) != 0) {
2927             ALOGW("Draining EQUALIZER");
2928             pContext->pBundledContext->SamplesToExitCountEq = 0;
2929             --pContext->pBundledContext->NumberEffectsEnabled;
2930             effectInDrain &= ~(1 << LVM_EQUALIZER);
2931         }
2932         if ((undrainedEffects & 1 << LVM_VIRTUALIZER) != 0) {
2933             ALOGW("Draining VIRTUALIZER");
2934             pContext->pBundledContext->SamplesToExitCountVirt = 0;
2935             --pContext->pBundledContext->NumberEffectsEnabled;
2936             effectInDrain &= ~(1 << LVM_VIRTUALIZER);
2937         }
2938         if ((undrainedEffects & 1 << LVM_VOLUME) != 0) {
2939             ALOGW("Draining VOLUME");
2940             --pContext->pBundledContext->NumberEffectsEnabled;
2941             effectInDrain &= ~(1 << LVM_VOLUME);
2942         }
2943     }
2944     effectProcessCalled |= 1 << pContext->EffectType;
2945 
2946     if ((pContext->pBundledContext->bBassEnabled == LVM_FALSE) &&
2947         (pContext->EffectType == LVM_BASS_BOOST)) {
2948         // ALOGV("\tEffect_process() LVM_BASS_BOOST Effect is not enabled");
2949         if (pContext->pBundledContext->SamplesToExitCountBb > 0) {
2950             pContext->pBundledContext->SamplesToExitCountBb -= outBuffer->frameCount * NrChannels;
2951             // ALOGV("\tEffect_process: Waiting to turn off BASS_BOOST, %d samples left",
2952             //    pContext->pBundledContext->SamplesToExitCountBb);
2953         }
2954         if (pContext->pBundledContext->SamplesToExitCountBb <= 0) {
2955             status = -ENODATA;
2956             if ((effectInDrain & 1 << LVM_BASS_BOOST) != 0) {
2957                 pContext->pBundledContext->NumberEffectsEnabled--;
2958                 effectInDrain &= ~(1 << LVM_BASS_BOOST);
2959             }
2960             ALOGV("\tEffect_process() this is the last frame for LVM_BASS_BOOST");
2961         }
2962     }
2963     if ((pContext->pBundledContext->bVolumeEnabled == LVM_FALSE) &&
2964         (pContext->EffectType == LVM_VOLUME)) {
2965         // ALOGV("\tEffect_process() LVM_VOLUME Effect is not enabled");
2966         status = -ENODATA;
2967         if ((effectInDrain & 1 << LVM_VOLUME) != 0) {
2968             pContext->pBundledContext->NumberEffectsEnabled--;
2969             effectInDrain &= ~(1 << LVM_VOLUME);
2970         }
2971     }
2972     if ((pContext->pBundledContext->bEqualizerEnabled == LVM_FALSE) &&
2973         (pContext->EffectType == LVM_EQUALIZER)) {
2974         // ALOGV("\tEffect_process() LVM_EQUALIZER Effect is not enabled");
2975         if (pContext->pBundledContext->SamplesToExitCountEq > 0) {
2976             pContext->pBundledContext->SamplesToExitCountEq -= outBuffer->frameCount * NrChannels;
2977             // ALOGV("\tEffect_process: Waiting to turn off EQUALIZER, %d samples left",
2978             //    pContext->pBundledContext->SamplesToExitCountEq);
2979         }
2980         if (pContext->pBundledContext->SamplesToExitCountEq <= 0) {
2981             status = -ENODATA;
2982             if ((effectInDrain & 1 << LVM_EQUALIZER) != 0) {
2983                 pContext->pBundledContext->NumberEffectsEnabled--;
2984                 effectInDrain &= ~(1 << LVM_EQUALIZER);
2985             }
2986             ALOGV("\tEffect_process() this is the last frame for LVM_EQUALIZER");
2987         }
2988     }
2989     if ((pContext->pBundledContext->bVirtualizerEnabled == LVM_FALSE) &&
2990         (pContext->EffectType == LVM_VIRTUALIZER)) {
2991         // ALOGV("\tEffect_process() LVM_VIRTUALIZER Effect is not enabled");
2992         if (pContext->pBundledContext->SamplesToExitCountVirt > 0) {
2993             pContext->pBundledContext->SamplesToExitCountVirt -= outBuffer->frameCount * NrChannels;
2994             // ALOGV("\tEffect_process: Waiting for to turn off VIRTUALIZER, %d samples left",
2995             //    pContext->pBundledContext->SamplesToExitCountVirt);
2996         }
2997         if (pContext->pBundledContext->SamplesToExitCountVirt <= 0) {
2998             status = -ENODATA;
2999             if ((effectInDrain & 1 << LVM_VIRTUALIZER) != 0) {
3000                 pContext->pBundledContext->NumberEffectsEnabled--;
3001                 effectInDrain &= ~(1 << LVM_VIRTUALIZER);
3002             }
3003             ALOGV("\tEffect_process() this is the last frame for LVM_VIRTUALIZER");
3004         }
3005     }
3006 
3007     if (status != -ENODATA) {
3008         pContext->pBundledContext->NumberEffectsCalled++;
3009     }
3010 
3011     if (pContext->pBundledContext->NumberEffectsCalled >=
3012         pContext->pBundledContext->NumberEffectsEnabled) {
3013         // We expect the # effects called to be equal to # effects enabled in sequence (including
3014         // draining effects).  Warn if this is not the case due to inconsistent calls.
3015         ALOGW_IF(pContext->pBundledContext->NumberEffectsCalled >
3016                          pContext->pBundledContext->NumberEffectsEnabled,
3017                  "%s Number of effects called %d is greater than number of effects enabled %d",
3018                  __func__, pContext->pBundledContext->NumberEffectsCalled,
3019                  pContext->pBundledContext->NumberEffectsEnabled);
3020         effectProcessCalled = 0;  // reset our consistency check.
3021 
3022         // ALOGV("\tEffect_process     Calling process with %d effects enabled, %d called: Effect
3023         // %d", pContext->pBundledContext->NumberEffectsEnabled,
3024         // pContext->pBundledContext->NumberEffectsCalled, pContext->EffectType);
3025 
3026         if (status == -ENODATA) {
3027             ALOGV("\tEffect_process() processing last frame");
3028         }
3029         pContext->pBundledContext->NumberEffectsCalled = 0;
3030         /* Process all the available frames, block processing is
3031            handled internalLY by the LVM bundle */
3032         processStatus = android::LvmBundle_process(inBuffer->f32, outBuffer->f32,
3033                                                    outBuffer->frameCount, pContext);
3034         if (processStatus != 0) {
3035             ALOGV("\tLVM_ERROR : LvmBundle_process returned error %d", processStatus);
3036             if (status == 0) {
3037                 status = processStatus;
3038             }
3039             return status;
3040         }
3041     } else {
3042         // ALOGV("\tEffect_process Not Calling process with %d effects enabled, %d called: Effect
3043         // %d", pContext->pBundledContext->NumberEffectsEnabled,
3044         // pContext->pBundledContext->NumberEffectsCalled, pContext->EffectType);
3045 
3046         if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
3047             for (size_t i = 0; i < outBuffer->frameCount * NrChannels; ++i) {
3048                 outBuffer->f32[i] += inBuffer->f32[i];
3049             }
3050         } else if (outBuffer->raw != inBuffer->raw) {
3051             memcpy(outBuffer->raw, inBuffer->raw,
3052                    outBuffer->frameCount * sizeof(effect_buffer_t) * FCC_2);
3053         }
3054     }
3055 
3056     return status;
3057 } /* end Effect_process */
3058 
3059 // The value offset of an effect parameter is computed by rounding up
3060 // the parameter size to the next 32 bit alignment.
computeParamVOffset(const effect_param_t * p)3061 static inline uint32_t computeParamVOffset(const effect_param_t* p) {
3062     return ((p->psize + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t);
3063 }
3064 
3065 /* Effect Control Interface Implementation: Command */
Effect_command(effect_handle_t self,uint32_t cmdCode,uint32_t cmdSize,void * pCmdData,uint32_t * replySize,void * pReplyData)3066 int Effect_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, void* pCmdData,
3067                    uint32_t* replySize, void* pReplyData) {
3068     EffectContext* pContext = (EffectContext*)self;
3069 
3070     // ALOGV("\t\nEffect_command start");
3071 
3072     if (pContext->EffectType == LVM_BASS_BOOST) {
3073         // ALOGV("\tEffect_command setting command for LVM_BASS_BOOST");
3074     }
3075     if (pContext->EffectType == LVM_VIRTUALIZER) {
3076         // ALOGV("\tEffect_command setting command for LVM_VIRTUALIZER");
3077     }
3078     if (pContext->EffectType == LVM_EQUALIZER) {
3079         // ALOGV("\tEffect_command setting command for LVM_EQUALIZER");
3080     }
3081     if (pContext->EffectType == LVM_VOLUME) {
3082         // ALOGV("\tEffect_command setting command for LVM_VOLUME");
3083     }
3084 
3085     if (pContext == NULL) {
3086         ALOGV("\tLVM_ERROR : Effect_command ERROR pContext == NULL");
3087         return -EINVAL;
3088     }
3089 
3090     // ALOGV("\tEffect_command INPUTS are: command %d cmdSize %d",cmdCode, cmdSize);
3091 
3092     // Incase we disable an effect, next time process is
3093     // called the number of effect called could be greater
3094     // pContext->pBundledContext->NumberEffectsCalled = 0;
3095 
3096     // ALOGV("\tEffect_command NumberEffectsCalled = %d, NumberEffectsEnabled = %d",
3097     //        pContext->pBundledContext->NumberEffectsCalled,
3098     //        pContext->pBundledContext->NumberEffectsEnabled);
3099 
3100     switch (cmdCode) {
3101         case EFFECT_CMD_INIT:
3102             if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
3103                 ALOGV("\tLVM_ERROR, EFFECT_CMD_INIT: ERROR for effect type %d",
3104                       pContext->EffectType);
3105                 return -EINVAL;
3106             }
3107             *(int*)pReplyData = 0;
3108             // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT start");
3109             if (pContext->EffectType == LVM_BASS_BOOST) {
3110                 // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT for LVM_BASS_BOOST");
3111                 android::BassSetStrength(pContext, 0);
3112             }
3113             if (pContext->EffectType == LVM_VIRTUALIZER) {
3114                 // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT for LVM_VIRTUALIZER");
3115                 android::VirtualizerSetStrength(pContext, 0);
3116             }
3117             if (pContext->EffectType == LVM_EQUALIZER) {
3118                 // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT for LVM_EQUALIZER");
3119                 android::EqualizerSetPreset(pContext, 0);
3120             }
3121             if (pContext->EffectType == LVM_VOLUME) {
3122                 // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_INIT for LVM_VOLUME");
3123                 *(int*)pReplyData = android::VolumeSetVolumeLevel(pContext, 0);
3124             }
3125             break;
3126 
3127         case EFFECT_CMD_SET_CONFIG:
3128             // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_CONFIG start");
3129             if (pCmdData == NULL || cmdSize != sizeof(effect_config_t) || pReplyData == NULL ||
3130                 replySize == NULL || *replySize != sizeof(int)) {
3131                 ALOGV("\tLVM_ERROR : Effect_command cmdCode Case: "
3132                       "EFFECT_CMD_SET_CONFIG: ERROR");
3133                 return -EINVAL;
3134             }
3135             *(int*)pReplyData = android::Effect_setConfig(pContext, (effect_config_t*)pCmdData);
3136             // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_CONFIG end");
3137             break;
3138 
3139         case EFFECT_CMD_GET_CONFIG:
3140             if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(effect_config_t)) {
3141                 ALOGV("\tLVM_ERROR : Effect_command cmdCode Case: "
3142                       "EFFECT_CMD_GET_CONFIG: ERROR");
3143                 return -EINVAL;
3144             }
3145 
3146             android::Effect_getConfig(pContext, (effect_config_t*)pReplyData);
3147             break;
3148 
3149         case EFFECT_CMD_RESET:
3150             // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_RESET start");
3151             android::Effect_setConfig(pContext, &pContext->config);
3152             // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_RESET end");
3153             break;
3154 
3155         case EFFECT_CMD_GET_PARAM: {
3156             // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_GET_PARAM start");
3157 
3158             effect_param_t* p = (effect_param_t*)pCmdData;
3159             if (pCmdData == NULL || cmdSize < sizeof(effect_param_t) ||
3160                 cmdSize < (sizeof(effect_param_t) + p->psize) || pReplyData == NULL ||
3161                 replySize == NULL || *replySize < (sizeof(effect_param_t) + p->psize)) {
3162                 ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: ERROR");
3163                 return -EINVAL;
3164             }
3165             if (EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t) < (size_t)p->psize) {
3166                 android_errorWriteLog(0x534e4554, "26347509");
3167                 ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: psize too big");
3168                 return -EINVAL;
3169             }
3170             const uint32_t paddedParamSize = computeParamVOffset(p);
3171             if ((EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t) < paddedParamSize) ||
3172                 (EFFECT_PARAM_SIZE_MAX - sizeof(effect_param_t) - paddedParamSize < p->vsize)) {
3173                 ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: padded_psize or vsize too big");
3174                 return -EINVAL;
3175             }
3176             uint32_t expectedReplySize = sizeof(effect_param_t) + paddedParamSize + p->vsize;
3177             if (*replySize < expectedReplySize) {
3178                 ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: min. replySize %u, got %u bytes",
3179                       expectedReplySize, *replySize);
3180                 android_errorWriteLog(0x534e4554, "32705438");
3181                 return -EINVAL;
3182             }
3183 
3184             memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
3185 
3186             p = (effect_param_t*)pReplyData;
3187 
3188             uint32_t voffset = paddedParamSize;
3189             if (pContext->EffectType == LVM_BASS_BOOST) {
3190                 p->status = android::BassBoost_getParameter(pContext, p->psize, p->data, &p->vsize,
3191                                                             p->data + voffset);
3192                 // ALOGV("\tBassBoost_command EFFECT_CMD_GET_PARAM "
3193                 //        "*pCmdData %d, *replySize %d, *pReplyData %d ",
3194                 //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
3195                 //        *replySize,
3196                 //        *(int16_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset));
3197             }
3198 
3199             if (pContext->EffectType == LVM_VIRTUALIZER) {
3200                 p->status = android::Virtualizer_getParameter(pContext, p->psize, (void*)p->data,
3201                                                               &p->vsize, p->data + voffset);
3202 
3203                 // ALOGV("\tVirtualizer_command EFFECT_CMD_GET_PARAM "
3204                 //        "*pCmdData %d, *replySize %d, *pReplyData %d ",
3205                 //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
3206                 //        *replySize,
3207                 //        *(int16_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset));
3208             }
3209             if (pContext->EffectType == LVM_EQUALIZER) {
3210                 // ALOGV("\tEqualizer_command cmdCode Case: "
3211                 //        "EFFECT_CMD_GET_PARAM start");
3212                 p->status = android::Equalizer_getParameter(pContext, p->psize, p->data, &p->vsize,
3213                                                             p->data + voffset);
3214 
3215                 // ALOGV("\tEqualizer_command EFFECT_CMD_GET_PARAM *pCmdData %d, *replySize %d, "
3216                 //       "*pReplyData %08x %08x",
3217                 //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)), *replySize,
3218                 //        *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset),
3219                 //        *(int32_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset +
3220                 //        sizeof(int32_t)));
3221             }
3222             if (pContext->EffectType == LVM_VOLUME) {
3223                 // ALOGV("\tVolume_command cmdCode Case: EFFECT_CMD_GET_PARAM start");
3224                 p->status = android::Volume_getParameter(pContext, p->psize, (void*)p->data,
3225                                                          &p->vsize, p->data + voffset);
3226 
3227                 // ALOGV("\tVolume_command EFFECT_CMD_GET_PARAM "
3228                 //        "*pCmdData %d, *replySize %d, *pReplyData %d ",
3229                 //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
3230                 //        *replySize,
3231                 //        *(int16_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset));
3232             }
3233             *replySize = sizeof(effect_param_t) + voffset + p->vsize;
3234 
3235             // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_GET_PARAM end");
3236         } break;
3237         case EFFECT_CMD_SET_PARAM: {
3238             // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_PARAM start");
3239             if (pContext->EffectType == LVM_BASS_BOOST) {
3240                 // ALOGV("\tBassBoost_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value
3241                 // %d",
3242                 //       *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
3243                 //       *replySize,
3244                 //       *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
3245 
3246                 if (pCmdData == NULL ||
3247                     cmdSize != (sizeof(effect_param_t) + sizeof(int32_t) + sizeof(int16_t)) ||
3248                     pReplyData == NULL || replySize == NULL || *replySize != sizeof(int32_t)) {
3249                     ALOGV("\tLVM_ERROR : BassBoost_command cmdCode Case: "
3250                           "EFFECT_CMD_SET_PARAM: ERROR");
3251                     return -EINVAL;
3252                 }
3253 
3254                 effect_param_t* const p = (effect_param_t*)pCmdData;
3255                 const uint32_t voffset = computeParamVOffset(p);
3256 
3257                 // ALOGV("\tnBassBoost_command cmdSize is %d\n"
3258                 //        "\tsizeof(effect_param_t) is  %d\n"
3259                 //        "\tp->psize is %d\n"
3260                 //        "\tp->vsize is %d"
3261                 //        "\n",
3262                 //        cmdSize, sizeof(effect_param_t), p->psize, p->vsize );
3263 
3264                 *(int*)pReplyData = android::BassBoost_setParameter(
3265                         pContext, p->psize, (void*)p->data, p->vsize, p->data + voffset);
3266             }
3267             if (pContext->EffectType == LVM_VIRTUALIZER) {
3268                 // Warning this log will fail to properly read an int32_t value, assumes int16_t
3269                 // ALOGV("\tVirtualizer_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value
3270                 // %d",
3271                 //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
3272                 //        *replySize,
3273                 //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) +
3274                 //        sizeof(int32_t)));
3275 
3276                 if (pCmdData == NULL ||
3277                     // legal parameters are int16_t or int32_t
3278                     cmdSize > (sizeof(effect_param_t) + sizeof(int32_t) + sizeof(int32_t)) ||
3279                     cmdSize < (sizeof(effect_param_t) + sizeof(int32_t) + sizeof(int16_t)) ||
3280                     pReplyData == NULL || replySize == NULL || *replySize != sizeof(int32_t)) {
3281                     ALOGV("\tLVM_ERROR : Virtualizer_command cmdCode Case: "
3282                           "EFFECT_CMD_SET_PARAM: ERROR");
3283                     return -EINVAL;
3284                 }
3285 
3286                 effect_param_t* const p = (effect_param_t*)pCmdData;
3287                 const uint32_t voffset = computeParamVOffset(p);
3288 
3289                 // ALOGV("\tnVirtualizer_command cmdSize is %d\n"
3290                 //        "\tsizeof(effect_param_t) is  %d\n"
3291                 //        "\tp->psize is %d\n"
3292                 //        "\tp->vsize is %d"
3293                 //        "\n",
3294                 //        cmdSize, sizeof(effect_param_t), p->psize, p->vsize );
3295 
3296                 *(int*)pReplyData = android::Virtualizer_setParameter(
3297                         pContext, p->psize, (void*)p->data, p->vsize, p->data + voffset);
3298             }
3299             if (pContext->EffectType == LVM_EQUALIZER) {
3300                 // ALOGV("\tEqualizer_command cmdCode Case: "
3301                 //        "EFFECT_CMD_SET_PARAM start");
3302                 // ALOGV("\tEqualizer_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d
3303                 // ",
3304                 //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
3305                 //        *replySize,
3306                 //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) +
3307                 //        sizeof(int32_t)));
3308 
3309                 if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
3310                     pReplyData == NULL || replySize == NULL || *replySize != sizeof(int32_t)) {
3311                     ALOGV("\tLVM_ERROR : Equalizer_command cmdCode Case: "
3312                           "EFFECT_CMD_SET_PARAM: ERROR");
3313                     return -EINVAL;
3314                 }
3315 
3316                 effect_param_t* const p = (effect_param_t*)pCmdData;
3317                 const uint32_t voffset = computeParamVOffset(p);
3318 
3319                 *(int*)pReplyData = android::Equalizer_setParameter(
3320                         pContext, p->psize, (void*)p->data, p->vsize, p->data + voffset);
3321             }
3322             if (pContext->EffectType == LVM_VOLUME) {
3323                 // ALOGV("\tVolume_command cmdCode Case: EFFECT_CMD_SET_PARAM start");
3324                 // ALOGV("\tVolume_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
3325                 //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
3326                 //        *replySize,
3327                 //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) +sizeof(int32_t)));
3328 
3329                 if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
3330                     pReplyData == NULL || replySize == NULL || *replySize != sizeof(int32_t)) {
3331                     ALOGV("\tLVM_ERROR : Volume_command cmdCode Case: "
3332                           "EFFECT_CMD_SET_PARAM: ERROR");
3333                     return -EINVAL;
3334                 }
3335 
3336                 effect_param_t* const p = (effect_param_t*)pCmdData;
3337                 const uint32_t voffset = computeParamVOffset(p);
3338 
3339                 *(int*)pReplyData = android::Volume_setParameter(pContext, p->psize, (void*)p->data,
3340                                                                  p->vsize, p->data + voffset);
3341             }
3342             // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_PARAM end");
3343         } break;
3344 
3345         case EFFECT_CMD_ENABLE:
3346             ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_ENABLE start");
3347             if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
3348                 ALOGV("\tLVM_ERROR : Effect_command cmdCode Case: EFFECT_CMD_ENABLE: ERROR");
3349                 return -EINVAL;
3350             }
3351 
3352             *(int*)pReplyData = android::Effect_setEnabled(pContext, LVM_TRUE);
3353             break;
3354 
3355         case EFFECT_CMD_DISABLE:
3356             // ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_DISABLE start");
3357             if (pReplyData == NULL || replySize == NULL || *replySize != sizeof(int)) {
3358                 ALOGV("\tLVM_ERROR : Effect_command cmdCode Case: EFFECT_CMD_DISABLE: ERROR");
3359                 return -EINVAL;
3360             }
3361             *(int*)pReplyData = android::Effect_setEnabled(pContext, LVM_FALSE);
3362             break;
3363 
3364         case EFFECT_CMD_SET_DEVICE: {
3365             ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_DEVICE start");
3366             if (pCmdData == NULL) {
3367                 ALOGV("\tLVM_ERROR : Effect_command cmdCode Case: EFFECT_CMD_SET_DEVICE: ERROR");
3368                 return -EINVAL;
3369             }
3370 
3371             audio_devices_t device = *(audio_devices_t *)pCmdData;
3372             pContext->pBundledContext->nOutputDevice = device;
3373 
3374             if (pContext->EffectType == LVM_BASS_BOOST) {
3375                 if ((device == AUDIO_DEVICE_OUT_SPEAKER) ||
3376                     (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) ||
3377                      device == AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER ||
3378                      device == AUDIO_DEVICE_OUT_BLE_SPEAKER) {
3379                     ALOGV("%s: EFFECT_CMD_SET_DEVICE device %#x is invalid for LVM_BASS_BOOST",
3380                             __func__, device);
3381 
3382                     // If a device doesn't support bassboost the effect must be temporarily disabled
3383                     // the effect must still report its original state as this can only be changed
3384                     // by the ENABLE/DISABLE command
3385 
3386                     if (pContext->pBundledContext->bBassEnabled == LVM_TRUE) {
3387                         ALOGV("\tEFFECT_CMD_SET_DEVICE disable LVM_BASS_BOOST %d",
3388                               *(int32_t*)pCmdData);
3389                         android::LvmEffect_disable(pContext);
3390                     }
3391                     pContext->pBundledContext->bBassTempDisabled = LVM_TRUE;
3392                 } else {
3393                     ALOGV("\tEFFECT_CMD_SET_DEVICE device is valid for LVM_BASS_BOOST %d",
3394                           *(int32_t*)pCmdData);
3395 
3396                     // If a device supports bassboost and the effect has been temporarily disabled
3397                     // previously then re-enable it
3398 
3399                     if (pContext->pBundledContext->bBassEnabled == LVM_TRUE) {
3400                         ALOGV("\tEFFECT_CMD_SET_DEVICE re-enable LVM_BASS_BOOST %d",
3401                               *(int32_t*)pCmdData);
3402                         android::LvmEffect_enable(pContext);
3403                     }
3404                     pContext->pBundledContext->bBassTempDisabled = LVM_FALSE;
3405                 }
3406             }
3407             if (pContext->EffectType == LVM_VIRTUALIZER) {
3408                 if (pContext->pBundledContext->nVirtualizerForcedDevice == AUDIO_DEVICE_NONE) {
3409                     // default case unless configuration is forced
3410                     if (android::VirtualizerIsDeviceSupported(device) != 0) {
3411                         ALOGV("\tEFFECT_CMD_SET_DEVICE device is invalid for LVM_VIRTUALIZER %d",
3412                               *(int32_t*)pCmdData);
3413                         ALOGV("\tEFFECT_CMD_SET_DEVICE temporary disable LVM_VIRTUALIZER");
3414 
3415                         // If a device doesn't support virtualizer the effect must be temporarily
3416                         // disabled the effect must still report its original state as this can
3417                         // only be changed by the ENABLE/DISABLE command
3418 
3419                         if (pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE) {
3420                             ALOGV("\tEFFECT_CMD_SET_DEVICE disable LVM_VIRTUALIZER %d",
3421                                   *(int32_t*)pCmdData);
3422                             android::LvmEffect_disable(pContext);
3423                         }
3424                         pContext->pBundledContext->bVirtualizerTempDisabled = LVM_TRUE;
3425                     } else {
3426                         ALOGV("\tEFFECT_CMD_SET_DEVICE device is valid for LVM_VIRTUALIZER %d",
3427                               *(int32_t*)pCmdData);
3428 
3429                         // If a device supports virtualizer and the effect has been temporarily
3430                         // disabled previously then re-enable it
3431 
3432                         if (pContext->pBundledContext->bVirtualizerEnabled == LVM_TRUE) {
3433                             ALOGV("\tEFFECT_CMD_SET_DEVICE re-enable LVM_VIRTUALIZER %d",
3434                                   *(int32_t*)pCmdData);
3435                             android::LvmEffect_enable(pContext);
3436                         }
3437                         pContext->pBundledContext->bVirtualizerTempDisabled = LVM_FALSE;
3438                     }
3439                 }  // else virtualization mode is forced to a certain device, nothing to do
3440             }
3441             ALOGV("\tEffect_command cmdCode Case: EFFECT_CMD_SET_DEVICE end");
3442             break;
3443         }
3444         case EFFECT_CMD_SET_VOLUME: {
3445             uint32_t leftVolume, rightVolume;
3446             int16_t leftdB, rightdB;
3447             int16_t maxdB, pandB;
3448             int32_t vol_ret[2] = {1 << 24, 1 << 24};     // Apply no volume
3449             LVM_ControlParams_t ActiveParams;            /* Current control Parameters */
3450             LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
3451 
3452             // if pReplyData is NULL, VOL_CTRL is delegated to another effect
3453             if (pReplyData == LVM_NULL) {
3454                 break;
3455             }
3456 
3457             if (pCmdData == NULL || cmdSize != 2 * sizeof(uint32_t) || pReplyData == NULL ||
3458                 replySize == NULL || *replySize < 2 * sizeof(int32_t)) {
3459                 ALOGV("\tLVM_ERROR : Effect_command cmdCode Case: "
3460                       "EFFECT_CMD_SET_VOLUME: ERROR");
3461                 return -EINVAL;
3462             }
3463 
3464             leftVolume = ((*(uint32_t*)pCmdData));
3465             rightVolume = ((*((uint32_t*)pCmdData + 1)));
3466 
3467             if (leftVolume == 0x1000000) {
3468                 leftVolume -= 1;
3469             }
3470             if (rightVolume == 0x1000000) {
3471                 rightVolume -= 1;
3472             }
3473 
3474             // Convert volume to dB
3475             leftdB = android::LVC_Convert_VolToDb(leftVolume);
3476             rightdB = android::LVC_Convert_VolToDb(rightVolume);
3477 
3478             pandB = rightdB - leftdB;
3479 
3480             // Calculate max volume in dB
3481             maxdB = leftdB;
3482             if (rightdB > maxdB) {
3483                 maxdB = rightdB;
3484             }
3485             // ALOGV("\tEFFECT_CMD_SET_VOLUME Session: %d, SessionID: %d VOLUME is %d dB, "
3486             //      "effect is %d",
3487             // pContext->pBundledContext->SessionNo, pContext->pBundledContext->SessionId,
3488             //(int32_t)maxdB, pContext->EffectType);
3489             // ALOGV("\tEFFECT_CMD_SET_VOLUME: Left is %d, Right is %d", leftVolume, rightVolume);
3490             // ALOGV("\tEFFECT_CMD_SET_VOLUME: Left %ddB, Right %ddB, Position %ddB",
3491             //        leftdB, rightdB, pandB);
3492 
3493             memcpy(pReplyData, vol_ret, sizeof(int32_t) * 2);
3494             android::VolumeSetVolumeLevel(pContext, (int16_t)(maxdB * 100));
3495 
3496             /* Get the current settings */
3497             LvmStatus =
3498                     LVM_GetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
3499             LVM_ERROR_CHECK(LvmStatus, "LVM_GetControlParameters", "VolumeSetStereoPosition")
3500             if (LvmStatus != LVM_SUCCESS) return -EINVAL;
3501 
3502             /* Volume parameters */
3503             ActiveParams.VC_Balance = pandB;
3504             ALOGV("\t\tVolumeSetStereoPosition() (-96dB -> +96dB)-> %d\n", ActiveParams.VC_Balance);
3505 
3506             /* Activate the initial settings */
3507             LvmStatus =
3508                     LVM_SetControlParameters(pContext->pBundledContext->hInstance, &ActiveParams);
3509             LVM_ERROR_CHECK(LvmStatus, "LVM_SetControlParameters", "VolumeSetStereoPosition")
3510             if (LvmStatus != LVM_SUCCESS) return -EINVAL;
3511             break;
3512         }
3513         case EFFECT_CMD_SET_AUDIO_MODE:
3514             break;
3515         default:
3516             return -EINVAL;
3517     }
3518 
3519     // ALOGV("\tEffect_command end...\n\n");
3520     return 0;
3521 } /* end Effect_command */
3522 
3523 /* Effect Control Interface Implementation: get_descriptor */
Effect_getDescriptor(effect_handle_t self,effect_descriptor_t * pDescriptor)3524 int Effect_getDescriptor(effect_handle_t self, effect_descriptor_t* pDescriptor) {
3525     EffectContext* pContext = (EffectContext*)self;
3526     const effect_descriptor_t* desc;
3527 
3528     if (pContext == NULL || pDescriptor == NULL) {
3529         ALOGV("Effect_getDescriptor() invalid param");
3530         return -EINVAL;
3531     }
3532 
3533     switch (pContext->EffectType) {
3534         case LVM_BASS_BOOST:
3535             desc = &android::gBassBoostDescriptor;
3536             break;
3537         case LVM_VIRTUALIZER:
3538             desc = &android::gVirtualizerDescriptor;
3539             break;
3540         case LVM_EQUALIZER:
3541             desc = &android::gEqualizerDescriptor;
3542             break;
3543         case LVM_VOLUME:
3544             desc = &android::gVolumeDescriptor;
3545             break;
3546         default:
3547             return -EINVAL;
3548     }
3549 
3550     *pDescriptor = *desc;
3551 
3552     return 0;
3553 } /* end Effect_getDescriptor */
3554 
3555 // effect_handle_t interface implementation for effect
3556 const struct effect_interface_s gLvmEffectInterface = {
3557         Effect_process,
3558         Effect_command,
3559         Effect_getDescriptor,
3560         NULL,
3561 }; /* end gLvmEffectInterface */
3562 
3563 // This is the only symbol that needs to be exported
3564 __attribute__((visibility("default"))) audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
3565         .tag = AUDIO_EFFECT_LIBRARY_TAG,
3566         .version = EFFECT_LIBRARY_API_VERSION,
3567         .name = "Effect Bundle Library",
3568         .implementor = "NXP Software Ltd.",
3569         .create_effect = android::EffectCreate,
3570         .release_effect = android::EffectRelease,
3571         .get_descriptor = android::EffectGetDescriptor,
3572 };
3573 }
3574