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