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