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