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