[go: nahoru, domu]

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