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