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