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