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