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