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 "Reverb"
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 "EffectReverb.h"
28// from Reverb/lib
29#include "LVREV.h"
30
31// effect_handle_t interface implementation for reverb
32extern "C" const struct effect_interface_s gReverbInterface;
33
34#define LVM_ERROR_CHECK(LvmStatus, callingFunc, calledFunc){\
35        if (LvmStatus == LVREV_NULLADDRESS){\
36            ALOGV("\tLVREV_ERROR : Parameter error - "\
37                    "null pointer returned by %s in %s\n\n\n\n", callingFunc, calledFunc);\
38        }\
39        if (LvmStatus == LVREV_INVALIDNUMSAMPLES){\
40            ALOGV("\tLVREV_ERROR : Parameter error - "\
41                    "bad number of samples returned by %s in %s\n\n\n\n", callingFunc, calledFunc);\
42        }\
43        if (LvmStatus == LVREV_OUTOFRANGE){\
44            ALOGV("\tLVREV_ERROR : Parameter error - "\
45                    "out of range returned by %s in %s\n", callingFunc, calledFunc);\
46        }\
47    }
48
49// Namespaces
50namespace android {
51namespace {
52
53/************************************************************************************/
54/*                                                                                  */
55/* Preset definitions                                                               */
56/*                                                                                  */
57/************************************************************************************/
58
59const static t_reverb_settings sReverbPresets[] = {
60        // REVERB_PRESET_NONE: values are unused
61        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
62        // REVERB_PRESET_SMALLROOM
63        {-400, -600, 1100, 830, -400, 5, 500, 10, 1000, 1000},
64        // REVERB_PRESET_MEDIUMROOM
65        {-400, -600, 1300, 830, -1000, 20, -200, 20, 1000, 1000},
66        // REVERB_PRESET_LARGEROOM
67        {-400, -600, 1500, 830, -1600, 5, -1000, 40, 1000, 1000},
68        // REVERB_PRESET_MEDIUMHALL
69        {-400, -600, 1800, 700, -1300, 15, -800, 30, 1000, 1000},
70        // REVERB_PRESET_LARGEHALL
71        {-400, -600, 1800, 700, -2000, 30, -1400, 60, 1000, 1000},
72        // REVERB_PRESET_PLATE
73        {-400, -200, 1300, 900, 0, 2, 0, 10, 1000, 750},
74};
75
76
77// NXP SW auxiliary environmental reverb
78const effect_descriptor_t gAuxEnvReverbDescriptor = {
79        { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e } },
80        { 0x4a387fc0, 0x8ab3, 0x11df, 0x8bad, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
81        EFFECT_CONTROL_API_VERSION,
82        EFFECT_FLAG_TYPE_AUXILIARY,
83        LVREV_CUP_LOAD_ARM9E,
84        LVREV_MEM_USAGE,
85        "Auxiliary Environmental Reverb",
86        "NXP Software Ltd.",
87};
88
89// NXP SW insert environmental reverb
90static const effect_descriptor_t gInsertEnvReverbDescriptor = {
91        {0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}},
92        {0xc7a511a0, 0xa3bb, 0x11df, 0x860e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
93        EFFECT_CONTROL_API_VERSION,
94        EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL,
95        LVREV_CUP_LOAD_ARM9E,
96        LVREV_MEM_USAGE,
97        "Insert Environmental Reverb",
98        "NXP Software Ltd.",
99};
100
101// NXP SW auxiliary preset reverb
102static const effect_descriptor_t gAuxPresetReverbDescriptor = {
103        {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
104        {0xf29a1400, 0xa3bb, 0x11df, 0x8ddc, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
105        EFFECT_CONTROL_API_VERSION,
106        EFFECT_FLAG_TYPE_AUXILIARY,
107        LVREV_CUP_LOAD_ARM9E,
108        LVREV_MEM_USAGE,
109        "Auxiliary Preset Reverb",
110        "NXP Software Ltd.",
111};
112
113// NXP SW insert preset reverb
114static const effect_descriptor_t gInsertPresetReverbDescriptor = {
115        {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
116        {0x172cdf00, 0xa3bc, 0x11df, 0xa72f, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
117        EFFECT_CONTROL_API_VERSION,
118        EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL,
119        LVREV_CUP_LOAD_ARM9E,
120        LVREV_MEM_USAGE,
121        "Insert Preset Reverb",
122        "NXP Software Ltd.",
123};
124
125// gDescriptors contains pointers to all defined effect descriptor in this library
126static const effect_descriptor_t * const gDescriptors[] = {
127        &gAuxEnvReverbDescriptor,
128        &gInsertEnvReverbDescriptor,
129        &gAuxPresetReverbDescriptor,
130        &gInsertPresetReverbDescriptor
131};
132
133struct ReverbContext{
134    const struct effect_interface_s *itfe;
135    effect_config_t                 config;
136    LVREV_Handle_t                  hInstance;
137    int16_t                         SavedRoomLevel;
138    int16_t                         SavedHfLevel;
139    int16_t                         SavedDecayTime;
140    int16_t                         SavedDecayHfRatio;
141    int16_t                         SavedReverbLevel;
142    int16_t                         SavedDiffusion;
143    int16_t                         SavedDensity;
144    bool                            bEnabled;
145    #ifdef LVM_PCM
146    FILE                            *PcmInPtr;
147    FILE                            *PcmOutPtr;
148    #endif
149    LVM_Fs_en                       SampleRate;
150    LVM_INT32                       *InFrames32;
151    LVM_INT32                       *OutFrames32;
152    bool                            auxiliary;
153    bool                            preset;
154    uint16_t                        curPreset;
155    uint16_t                        nextPreset;
156    int                             SamplesToExitCount;
157    LVM_INT16                       leftVolume;
158    LVM_INT16                       rightVolume;
159    LVM_INT16                       prevLeftVolume;
160    LVM_INT16                       prevRightVolume;
161    int                             volumeMode;
162};
163
164enum {
165    REVERB_VOLUME_OFF,
166    REVERB_VOLUME_FLAT,
167    REVERB_VOLUME_RAMP,
168};
169
170#define REVERB_DEFAULT_PRESET REVERB_PRESET_NONE
171
172
173#define REVERB_SEND_LEVEL   (0x0C00) // 0.75 in 4.12 format
174#define REVERB_UNIT_VOLUME  (0x1000) // 1.0 in 4.12 format
175
176//--- local function prototypes
177int  Reverb_init            (ReverbContext *pContext);
178void Reverb_free            (ReverbContext *pContext);
179int  Reverb_setConfig       (ReverbContext *pContext, effect_config_t *pConfig);
180void Reverb_getConfig       (ReverbContext *pContext, effect_config_t *pConfig);
181int  Reverb_setParameter    (ReverbContext *pContext, void *pParam, void *pValue);
182int  Reverb_getParameter    (ReverbContext *pContext,
183                             void          *pParam,
184                             size_t        *pValueSize,
185                             void          *pValue);
186int Reverb_LoadPreset       (ReverbContext   *pContext);
187
188/* Effect Library Interface Implementation */
189
190extern "C" int EffectCreate(const effect_uuid_t *uuid,
191                            int32_t             sessionId,
192                            int32_t             ioId,
193                            effect_handle_t  *pHandle){
194    int ret;
195    int i;
196    int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
197    const effect_descriptor_t *desc;
198
199    ALOGV("\t\nEffectCreate start");
200
201    if (pHandle == NULL || uuid == NULL){
202        ALOGV("\tLVM_ERROR : EffectCreate() called with NULL pointer");
203        return -EINVAL;
204    }
205
206    for (i = 0; i < length; i++) {
207        desc = gDescriptors[i];
208        if (memcmp(uuid, &desc->uuid, sizeof(effect_uuid_t))
209                == 0) {
210            ALOGV("\tEffectCreate - UUID matched Reverb type %d, UUID = %x", i, desc->uuid.timeLow);
211            break;
212        }
213    }
214
215    if (i == length) {
216        return -ENOENT;
217    }
218
219    ReverbContext *pContext = new ReverbContext;
220
221    pContext->itfe      = &gReverbInterface;
222    pContext->hInstance = NULL;
223
224    pContext->auxiliary = false;
225    if ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY){
226        pContext->auxiliary = true;
227        ALOGV("\tEffectCreate - AUX");
228    }else{
229        ALOGV("\tEffectCreate - INS");
230    }
231
232    pContext->preset = false;
233    if (memcmp(&desc->type, SL_IID_PRESETREVERB, sizeof(effect_uuid_t)) == 0) {
234        pContext->preset = true;
235        // force reloading preset at first call to process()
236        pContext->curPreset = REVERB_PRESET_LAST + 1;
237        pContext->nextPreset = REVERB_DEFAULT_PRESET;
238        ALOGV("\tEffectCreate - PRESET");
239    }else{
240        ALOGV("\tEffectCreate - ENVIRONMENTAL");
241    }
242
243    ALOGV("\tEffectCreate - Calling Reverb_init");
244    ret = Reverb_init(pContext);
245
246    if (ret < 0){
247        ALOGV("\tLVM_ERROR : EffectCreate() init failed");
248        delete pContext;
249        return ret;
250    }
251
252    *pHandle = (effect_handle_t)pContext;
253
254    #ifdef LVM_PCM
255    pContext->PcmInPtr = NULL;
256    pContext->PcmOutPtr = NULL;
257
258    pContext->PcmInPtr  = fopen("/data/tmp/reverb_pcm_in.pcm", "w");
259    pContext->PcmOutPtr = fopen("/data/tmp/reverb_pcm_out.pcm", "w");
260
261    if((pContext->PcmInPtr  == NULL)||
262       (pContext->PcmOutPtr == NULL)){
263       return -EINVAL;
264    }
265    #endif
266
267
268    // Allocate memory for reverb process (*2 is for STEREO)
269    pContext->InFrames32  = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2);
270    pContext->OutFrames32 = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2);
271
272    ALOGV("\tEffectCreate %p, size %d", pContext, sizeof(ReverbContext));
273    ALOGV("\tEffectCreate end\n");
274    return 0;
275} /* end EffectCreate */
276
277extern "C" int EffectRelease(effect_handle_t handle){
278    ReverbContext * pContext = (ReverbContext *)handle;
279
280    ALOGV("\tEffectRelease %p", handle);
281    if (pContext == NULL){
282        ALOGV("\tLVM_ERROR : EffectRelease called with NULL pointer");
283        return -EINVAL;
284    }
285
286    #ifdef LVM_PCM
287    fclose(pContext->PcmInPtr);
288    fclose(pContext->PcmOutPtr);
289    #endif
290    free(pContext->InFrames32);
291    free(pContext->OutFrames32);
292    Reverb_free(pContext);
293    delete pContext;
294    return 0;
295} /* end EffectRelease */
296
297extern "C" int EffectGetDescriptor(const effect_uuid_t *uuid,
298                                   effect_descriptor_t *pDescriptor) {
299    int i;
300    int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
301
302    if (pDescriptor == NULL || uuid == NULL){
303        ALOGV("EffectGetDescriptor() called with NULL pointer");
304        return -EINVAL;
305    }
306
307    for (i = 0; i < length; i++) {
308        if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
309            *pDescriptor = *gDescriptors[i];
310            ALOGV("EffectGetDescriptor - UUID matched Reverb type %d, UUID = %x",
311                 i, gDescriptors[i]->uuid.timeLow);
312            return 0;
313        }
314    }
315
316    return -EINVAL;
317} /* end EffectGetDescriptor */
318
319/* local functions */
320#define CHECK_ARG(cond) {                     \
321    if (!(cond)) {                            \
322        ALOGV("\tLVM_ERROR : Invalid argument: "#cond);      \
323        return -EINVAL;                       \
324    }                                         \
325}
326
327//----------------------------------------------------------------------------
328// MonoTo2I_32()
329//----------------------------------------------------------------------------
330// Purpose:
331//  Convert MONO to STEREO
332//
333//----------------------------------------------------------------------------
334
335void MonoTo2I_32( const LVM_INT32  *src,
336                        LVM_INT32  *dst,
337                        LVM_INT16 n)
338{
339   LVM_INT16 ii;
340   src += (n-1);
341   dst += ((n*2)-1);
342
343   for (ii = n; ii != 0; ii--)
344   {
345       *dst = *src;
346       dst--;
347
348       *dst = *src;
349       dst--;
350       src--;
351   }
352
353   return;
354}
355
356//----------------------------------------------------------------------------
357// From2iToMono_32()
358//----------------------------------------------------------------------------
359// Purpose:
360//  Convert STEREO to MONO
361//
362//----------------------------------------------------------------------------
363
364void From2iToMono_32( const LVM_INT32 *src,
365                            LVM_INT32 *dst,
366                            LVM_INT16 n)
367{
368   LVM_INT16 ii;
369   LVM_INT32 Temp;
370
371   for (ii = n; ii != 0; ii--)
372   {
373       Temp = (*src>>1);
374       src++;
375
376       Temp +=(*src>>1);
377       src++;
378
379       *dst = Temp;
380       dst++;
381   }
382
383   return;
384}
385
386static inline int16_t clamp16(int32_t sample)
387{
388    if ((sample>>15) ^ (sample>>31))
389        sample = 0x7FFF ^ (sample>>31);
390    return sample;
391}
392
393//----------------------------------------------------------------------------
394// process()
395//----------------------------------------------------------------------------
396// Purpose:
397// Apply the Reverb
398//
399// Inputs:
400//  pIn:        pointer to stereo/mono 16 bit input data
401//  pOut:       pointer to stereo 16 bit output data
402//  frameCount: Frames to process
403//  pContext:   effect engine context
404//  strength    strength to be applied
405//
406//  Outputs:
407//  pOut:       pointer to updated stereo 16 bit output data
408//
409//----------------------------------------------------------------------------
410
411int process( LVM_INT16     *pIn,
412             LVM_INT16     *pOut,
413             int           frameCount,
414             ReverbContext *pContext){
415
416    LVM_INT16               samplesPerFrame = 1;
417    LVREV_ReturnStatus_en   LvmStatus = LVREV_SUCCESS;              /* Function call status */
418    LVM_INT16 *OutFrames16;
419
420
421    // Check that the input is either mono or stereo
422    if (pContext->config.inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO) {
423        samplesPerFrame = 2;
424    } else if (pContext->config.inputCfg.channels != AUDIO_CHANNEL_OUT_MONO) {
425        ALOGV("\tLVREV_ERROR : process invalid PCM format");
426        return -EINVAL;
427    }
428
429    OutFrames16 = (LVM_INT16 *)pContext->OutFrames32;
430
431    // Check for NULL pointers
432    if((pContext->InFrames32 == NULL)||(pContext->OutFrames32 == NULL)){
433        ALOGV("\tLVREV_ERROR : process failed to allocate memory for temporary buffers ");
434        return -EINVAL;
435    }
436
437    #ifdef LVM_PCM
438    fwrite(pIn, frameCount*sizeof(LVM_INT16)*samplesPerFrame, 1, pContext->PcmInPtr);
439    fflush(pContext->PcmInPtr);
440    #endif
441
442    if (pContext->preset && pContext->nextPreset != pContext->curPreset) {
443        Reverb_LoadPreset(pContext);
444    }
445
446
447
448    // Convert to Input 32 bits
449    if (pContext->auxiliary) {
450        for(int i=0; i<frameCount*samplesPerFrame; i++){
451            pContext->InFrames32[i] = (LVM_INT32)pIn[i]<<8;
452        }
453    } else {
454        // insert reverb input is always stereo
455        for (int i = 0; i < frameCount; i++) {
456            pContext->InFrames32[2*i] = (pIn[2*i] * REVERB_SEND_LEVEL) >> 4; // <<8 + >>12
457            pContext->InFrames32[2*i+1] = (pIn[2*i+1] * REVERB_SEND_LEVEL) >> 4; // <<8 + >>12
458        }
459    }
460
461    if (pContext->preset && pContext->curPreset == REVERB_PRESET_NONE) {
462        memset(pContext->OutFrames32, 0, frameCount * sizeof(LVM_INT32) * 2); //always stereo here
463    } else {
464        if(pContext->bEnabled == LVM_FALSE && pContext->SamplesToExitCount > 0) {
465            memset(pContext->InFrames32,0,frameCount * sizeof(LVM_INT32) * samplesPerFrame);
466            ALOGV("\tZeroing %d samples per frame at the end of call", samplesPerFrame);
467        }
468
469        /* Process the samples, producing a stereo output */
470        LvmStatus = LVREV_Process(pContext->hInstance,      /* Instance handle */
471                                  pContext->InFrames32,     /* Input buffer */
472                                  pContext->OutFrames32,    /* Output buffer */
473                                  frameCount);              /* Number of samples to read */
474    }
475
476    LVM_ERROR_CHECK(LvmStatus, "LVREV_Process", "process")
477    if(LvmStatus != LVREV_SUCCESS) return -EINVAL;
478
479    // Convert to 16 bits
480    if (pContext->auxiliary) {
481        for (int i=0; i < frameCount*2; i++) { //always stereo here
482            OutFrames16[i] = clamp16(pContext->OutFrames32[i]>>8);
483        }
484    } else {
485        for (int i=0; i < frameCount*2; i++) { //always stereo here
486            OutFrames16[i] = clamp16((pContext->OutFrames32[i]>>8) + (LVM_INT32)pIn[i]);
487        }
488
489        // apply volume with ramp if needed
490        if ((pContext->leftVolume != pContext->prevLeftVolume ||
491                pContext->rightVolume != pContext->prevRightVolume) &&
492                pContext->volumeMode == REVERB_VOLUME_RAMP) {
493            LVM_INT32 vl = (LVM_INT32)pContext->prevLeftVolume << 16;
494            LVM_INT32 incl = (((LVM_INT32)pContext->leftVolume << 16) - vl) / frameCount;
495            LVM_INT32 vr = (LVM_INT32)pContext->prevRightVolume << 16;
496            LVM_INT32 incr = (((LVM_INT32)pContext->rightVolume << 16) - vr) / frameCount;
497
498            for (int i = 0; i < frameCount; i++) {
499                OutFrames16[2*i] =
500                        clamp16((LVM_INT32)((vl >> 16) * OutFrames16[2*i]) >> 12);
501                OutFrames16[2*i+1] =
502                        clamp16((LVM_INT32)((vr >> 16) * OutFrames16[2*i+1]) >> 12);
503
504                vl += incl;
505                vr += incr;
506            }
507
508            pContext->prevLeftVolume = pContext->leftVolume;
509            pContext->prevRightVolume = pContext->rightVolume;
510        } else if (pContext->volumeMode != REVERB_VOLUME_OFF) {
511            if (pContext->leftVolume != REVERB_UNIT_VOLUME ||
512                pContext->rightVolume != REVERB_UNIT_VOLUME) {
513                for (int i = 0; i < frameCount; i++) {
514                    OutFrames16[2*i] =
515                            clamp16((LVM_INT32)(pContext->leftVolume * OutFrames16[2*i]) >> 12);
516                    OutFrames16[2*i+1] =
517                            clamp16((LVM_INT32)(pContext->rightVolume * OutFrames16[2*i+1]) >> 12);
518                }
519            }
520            pContext->prevLeftVolume = pContext->leftVolume;
521            pContext->prevRightVolume = pContext->rightVolume;
522            pContext->volumeMode = REVERB_VOLUME_RAMP;
523        }
524    }
525
526    #ifdef LVM_PCM
527    fwrite(OutFrames16, frameCount*sizeof(LVM_INT16)*2, 1, pContext->PcmOutPtr);
528    fflush(pContext->PcmOutPtr);
529    #endif
530
531    // Accumulate if required
532    if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
533        //ALOGV("\tBuffer access is ACCUMULATE");
534        for (int i=0; i<frameCount*2; i++){ //always stereo here
535            pOut[i] = clamp16((int32_t)pOut[i] + (int32_t)OutFrames16[i]);
536        }
537    }else{
538        //ALOGV("\tBuffer access is WRITE");
539        memcpy(pOut, OutFrames16, frameCount*sizeof(LVM_INT16)*2);
540    }
541
542    return 0;
543}    /* end process */
544
545//----------------------------------------------------------------------------
546// Reverb_free()
547//----------------------------------------------------------------------------
548// Purpose: Free all memory associated with the Bundle.
549//
550// Inputs:
551//  pContext:   effect engine context
552//
553// Outputs:
554//
555//----------------------------------------------------------------------------
556
557void Reverb_free(ReverbContext *pContext){
558
559    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;         /* Function call status */
560    LVREV_ControlParams_st    params;                        /* Control Parameters */
561    LVREV_MemoryTable_st      MemTab;
562
563    /* Free the algorithm memory */
564    LvmStatus = LVREV_GetMemoryTable(pContext->hInstance,
565                                   &MemTab,
566                                   LVM_NULL);
567
568    LVM_ERROR_CHECK(LvmStatus, "LVM_GetMemoryTable", "Reverb_free")
569
570    for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
571        if (MemTab.Region[i].Size != 0){
572            if (MemTab.Region[i].pBaseAddress != NULL){
573                ALOGV("\tfree() - START freeing %ld bytes for region %u at %p\n",
574                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
575
576                free(MemTab.Region[i].pBaseAddress);
577
578                ALOGV("\tfree() - END   freeing %ld bytes for region %u at %p\n",
579                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
580            }else{
581                ALOGV("\tLVM_ERROR : free() - trying to free with NULL pointer %ld bytes "
582                        "for region %u at %p ERROR\n",
583                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
584            }
585        }
586    }
587}    /* end Reverb_free */
588
589//----------------------------------------------------------------------------
590// Reverb_setConfig()
591//----------------------------------------------------------------------------
592// Purpose: Set input and output audio configuration.
593//
594// Inputs:
595//  pContext:   effect engine context
596//  pConfig:    pointer to effect_config_t structure holding input and output
597//      configuration parameters
598//
599// Outputs:
600//
601//----------------------------------------------------------------------------
602
603int Reverb_setConfig(ReverbContext *pContext, effect_config_t *pConfig){
604    LVM_Fs_en   SampleRate;
605    //ALOGV("\tReverb_setConfig start");
606
607    CHECK_ARG(pContext != NULL);
608    CHECK_ARG(pConfig != NULL);
609
610    CHECK_ARG(pConfig->inputCfg.samplingRate == pConfig->outputCfg.samplingRate);
611    CHECK_ARG(pConfig->inputCfg.format == pConfig->outputCfg.format);
612    CHECK_ARG((pContext->auxiliary && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_MONO) ||
613              ((!pContext->auxiliary) && pConfig->inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO));
614    CHECK_ARG(pConfig->outputCfg.channels == AUDIO_CHANNEL_OUT_STEREO);
615    CHECK_ARG(pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_WRITE
616              || pConfig->outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE);
617    CHECK_ARG(pConfig->inputCfg.format == AUDIO_FORMAT_PCM_16_BIT);
618
619    //ALOGV("\tReverb_setConfig calling memcpy");
620    pContext->config = *pConfig;
621
622
623    switch (pConfig->inputCfg.samplingRate) {
624    case 8000:
625        SampleRate = LVM_FS_8000;
626        break;
627    case 16000:
628        SampleRate = LVM_FS_16000;
629        break;
630    case 22050:
631        SampleRate = LVM_FS_22050;
632        break;
633    case 32000:
634        SampleRate = LVM_FS_32000;
635        break;
636    case 44100:
637        SampleRate = LVM_FS_44100;
638        break;
639    case 48000:
640        SampleRate = LVM_FS_48000;
641        break;
642    default:
643        ALOGV("\rReverb_setConfig invalid sampling rate %d", pConfig->inputCfg.samplingRate);
644        return -EINVAL;
645    }
646
647    if (pContext->SampleRate != SampleRate) {
648
649        LVREV_ControlParams_st    ActiveParams;
650        LVREV_ReturnStatus_en     LvmStatus = LVREV_SUCCESS;
651
652        //ALOGV("\tReverb_setConfig change sampling rate to %d", SampleRate);
653
654        /* Get the current settings */
655        LvmStatus = LVREV_GetControlParameters(pContext->hInstance,
656                                         &ActiveParams);
657
658        LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "Reverb_setConfig")
659        if(LvmStatus != LVREV_SUCCESS) return -EINVAL;
660
661        ActiveParams.SampleRate = SampleRate;
662
663        LvmStatus = LVREV_SetControlParameters(pContext->hInstance, &ActiveParams);
664
665        LVM_ERROR_CHECK(LvmStatus, "LVREV_SetControlParameters", "Reverb_setConfig")
666        if(LvmStatus != LVREV_SUCCESS) return -EINVAL;
667        //ALOGV("\tReverb_setConfig Succesfully called LVREV_SetControlParameters\n");
668        pContext->SampleRate = SampleRate;
669    }else{
670        //ALOGV("\tReverb_setConfig keep sampling rate at %d", SampleRate);
671    }
672
673    //ALOGV("\tReverb_setConfig End");
674    return 0;
675}   /* end Reverb_setConfig */
676
677//----------------------------------------------------------------------------
678// Reverb_getConfig()
679//----------------------------------------------------------------------------
680// Purpose: Get input and output audio configuration.
681//
682// Inputs:
683//  pContext:   effect engine context
684//  pConfig:    pointer to effect_config_t structure holding input and output
685//      configuration parameters
686//
687// Outputs:
688//
689//----------------------------------------------------------------------------
690
691void Reverb_getConfig(ReverbContext *pContext, effect_config_t *pConfig)
692{
693    *pConfig = pContext->config;
694}   /* end Reverb_getConfig */
695
696//----------------------------------------------------------------------------
697// Reverb_init()
698//----------------------------------------------------------------------------
699// Purpose: Initialize engine with default configuration
700//
701// Inputs:
702//  pContext:   effect engine context
703//
704// Outputs:
705//
706//----------------------------------------------------------------------------
707
708int Reverb_init(ReverbContext *pContext){
709    int status;
710
711    ALOGV("\tReverb_init start");
712
713    CHECK_ARG(pContext != NULL);
714
715    if (pContext->hInstance != NULL){
716        Reverb_free(pContext);
717    }
718
719    pContext->config.inputCfg.accessMode                    = EFFECT_BUFFER_ACCESS_READ;
720    if (pContext->auxiliary) {
721        pContext->config.inputCfg.channels                  = AUDIO_CHANNEL_OUT_MONO;
722    } else {
723        pContext->config.inputCfg.channels                  = AUDIO_CHANNEL_OUT_STEREO;
724    }
725
726    pContext->config.inputCfg.format                        = AUDIO_FORMAT_PCM_16_BIT;
727    pContext->config.inputCfg.samplingRate                  = 44100;
728    pContext->config.inputCfg.bufferProvider.getBuffer      = NULL;
729    pContext->config.inputCfg.bufferProvider.releaseBuffer  = NULL;
730    pContext->config.inputCfg.bufferProvider.cookie         = NULL;
731    pContext->config.inputCfg.mask                          = EFFECT_CONFIG_ALL;
732    pContext->config.outputCfg.accessMode                   = EFFECT_BUFFER_ACCESS_ACCUMULATE;
733    pContext->config.outputCfg.channels                     = AUDIO_CHANNEL_OUT_STEREO;
734    pContext->config.outputCfg.format                       = AUDIO_FORMAT_PCM_16_BIT;
735    pContext->config.outputCfg.samplingRate                 = 44100;
736    pContext->config.outputCfg.bufferProvider.getBuffer     = NULL;
737    pContext->config.outputCfg.bufferProvider.releaseBuffer = NULL;
738    pContext->config.outputCfg.bufferProvider.cookie        = NULL;
739    pContext->config.outputCfg.mask                         = EFFECT_CONFIG_ALL;
740
741    pContext->leftVolume = REVERB_UNIT_VOLUME;
742    pContext->rightVolume = REVERB_UNIT_VOLUME;
743    pContext->prevLeftVolume = REVERB_UNIT_VOLUME;
744    pContext->prevRightVolume = REVERB_UNIT_VOLUME;
745    pContext->volumeMode = REVERB_VOLUME_FLAT;
746
747    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;        /* Function call status */
748    LVREV_ControlParams_st    params;                         /* Control Parameters */
749    LVREV_InstanceParams_st   InstParams;                     /* Instance parameters */
750    LVREV_MemoryTable_st      MemTab;                         /* Memory allocation table */
751    bool                      bMallocFailure = LVM_FALSE;
752
753    /* Set the capabilities */
754    InstParams.MaxBlockSize  = MAX_CALL_SIZE;
755    InstParams.SourceFormat  = LVM_STEREO;          // Max format, could be mono during process
756    InstParams.NumDelays     = LVREV_DELAYLINES_4;
757
758    /* Allocate memory, forcing alignment */
759    LvmStatus = LVREV_GetMemoryTable(LVM_NULL,
760                                  &MemTab,
761                                  &InstParams);
762
763    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetMemoryTable", "Reverb_init")
764    if(LvmStatus != LVREV_SUCCESS) return -EINVAL;
765
766    ALOGV("\tCreateInstance Succesfully called LVM_GetMemoryTable\n");
767
768    /* Allocate memory */
769    for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
770        if (MemTab.Region[i].Size != 0){
771            MemTab.Region[i].pBaseAddress = malloc(MemTab.Region[i].Size);
772
773            if (MemTab.Region[i].pBaseAddress == LVM_NULL){
774                ALOGV("\tLVREV_ERROR :Reverb_init CreateInstance Failed to allocate %ld "
775                        "bytes for region %u\n", MemTab.Region[i].Size, i );
776                bMallocFailure = LVM_TRUE;
777            }else{
778                ALOGV("\tReverb_init CreateInstance allocate %ld bytes for region %u at %p\n",
779                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
780            }
781        }
782    }
783
784    /* If one or more of the memory regions failed to allocate, free the regions that were
785     * succesfully allocated and return with an error
786     */
787    if(bMallocFailure == LVM_TRUE){
788        for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
789            if (MemTab.Region[i].pBaseAddress == LVM_NULL){
790                ALOGV("\tLVM_ERROR :Reverb_init CreateInstance Failed to allocate %ld bytes "
791                        "for region %u - Not freeing\n", MemTab.Region[i].Size, i );
792            }else{
793                ALOGV("\tLVM_ERROR :Reverb_init CreateInstance Failed: but allocated %ld bytes "
794                        "for region %u at %p- free\n",
795                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
796                free(MemTab.Region[i].pBaseAddress);
797            }
798        }
799        return -EINVAL;
800    }
801    ALOGV("\tReverb_init CreateInstance Succesfully malloc'd memory\n");
802
803    /* Initialise */
804    pContext->hInstance = LVM_NULL;
805
806    /* Init sets the instance handle */
807    LvmStatus = LVREV_GetInstanceHandle(&pContext->hInstance,
808                                        &MemTab,
809                                        &InstParams);
810
811    LVM_ERROR_CHECK(LvmStatus, "LVM_GetInstanceHandle", "Reverb_init")
812    if(LvmStatus != LVREV_SUCCESS) return -EINVAL;
813
814    ALOGV("\tReverb_init CreateInstance Succesfully called LVM_GetInstanceHandle\n");
815
816    /* Set the initial process parameters */
817    /* General parameters */
818    params.OperatingMode  = LVM_MODE_ON;
819    params.SampleRate     = LVM_FS_44100;
820    pContext->SampleRate  = LVM_FS_44100;
821
822    if(pContext->config.inputCfg.channels == AUDIO_CHANNEL_OUT_MONO){
823        params.SourceFormat   = LVM_MONO;
824    } else {
825        params.SourceFormat   = LVM_STEREO;
826    }
827
828    /* Reverb parameters */
829    params.Level          = 0;
830    params.LPF            = 23999;
831    params.HPF            = 50;
832    params.T60            = 1490;
833    params.Density        = 100;
834    params.Damping        = 21;
835    params.RoomSize       = 100;
836
837    pContext->SamplesToExitCount = (params.T60 * pContext->config.inputCfg.samplingRate)/1000;
838
839    /* Saved strength is used to return the exact strength that was used in the set to the get
840     * because we map the original strength range of 0:1000 to 1:15, and this will avoid
841     * quantisation like effect when returning
842     */
843    pContext->SavedRoomLevel    = -6000;
844    pContext->SavedHfLevel      = 0;
845    pContext->bEnabled          = LVM_FALSE;
846    pContext->SavedDecayTime    = params.T60;
847    pContext->SavedDecayHfRatio = params.Damping*20;
848    pContext->SavedDensity      = params.RoomSize*10;
849    pContext->SavedDiffusion    = params.Density*10;
850    pContext->SavedReverbLevel  = -6000;
851
852    /* Activate the initial settings */
853    LvmStatus = LVREV_SetControlParameters(pContext->hInstance,
854                                         &params);
855
856    LVM_ERROR_CHECK(LvmStatus, "LVREV_SetControlParameters", "Reverb_init")
857    if(LvmStatus != LVREV_SUCCESS) return -EINVAL;
858
859    ALOGV("\tReverb_init CreateInstance Succesfully called LVREV_SetControlParameters\n");
860    ALOGV("\tReverb_init End");
861    return 0;
862}   /* end Reverb_init */
863
864//----------------------------------------------------------------------------
865// ReverbConvertLevel()
866//----------------------------------------------------------------------------
867// Purpose:
868// Convert level from OpenSL ES format to LVM format
869//
870// Inputs:
871//  level       level to be applied
872//
873//----------------------------------------------------------------------------
874
875int16_t ReverbConvertLevel(int16_t level){
876    static int16_t LevelArray[101] =
877    {
878       -12000, -4000,  -3398,  -3046,  -2796,  -2603,  -2444,  -2310,  -2194,  -2092,
879       -2000,  -1918,  -1842,  -1773,  -1708,  -1648,  -1592,  -1540,  -1490,  -1443,
880       -1398,  -1356,  -1316,  -1277,  -1240,  -1205,  -1171,  -1138,  -1106,  -1076,
881       -1046,  -1018,  -990,   -963,   -938,   -912,   -888,   -864,   -841,   -818,
882       -796,   -775,   -754,   -734,   -714,   -694,   -675,   -656,   -638,   -620,
883       -603,   -585,   -568,   -552,   -536,   -520,   -504,   -489,   -474,   -459,
884       -444,   -430,   -416,   -402,   -388,   -375,   -361,   -348,   -335,   -323,
885       -310,   -298,   -286,   -274,   -262,   -250,   -239,   -228,   -216,   -205,
886       -194,   -184,   -173,   -162,   -152,   -142,   -132,   -121,   -112,   -102,
887       -92,    -82,    -73,    -64,    -54,    -45,    -36,    -27,    -18,    -9,
888       0
889    };
890    int16_t i;
891
892    for(i = 0; i < 101; i++)
893    {
894       if(level <= LevelArray[i])
895           break;
896    }
897    return i;
898}
899
900//----------------------------------------------------------------------------
901// ReverbConvertHFLevel()
902//----------------------------------------------------------------------------
903// Purpose:
904// Convert level from OpenSL ES format to LVM format
905//
906// Inputs:
907//  level       level to be applied
908//
909//----------------------------------------------------------------------------
910
911int16_t ReverbConvertHfLevel(int16_t Hflevel){
912    int16_t i;
913
914    static LPFPair_t LPFArray[97] =
915    {   // Limit range to 50 for LVREV parameter range
916        {-10000, 50}, { -5000, 50 }, { -4000, 50},  { -3000, 158}, { -2000, 502},
917        {-1000, 1666},{ -900, 1897}, { -800, 2169}, { -700, 2496}, { -600, 2895},
918        {-500, 3400}, { -400, 4066}, { -300, 5011}, { -200, 6537}, { -100,  9826},
919        {-99, 9881 }, { -98, 9937 }, { -97, 9994 }, { -96, 10052}, { -95, 10111},
920        {-94, 10171}, { -93, 10231}, { -92, 10293}, { -91, 10356}, { -90, 10419},
921        {-89, 10484}, { -88, 10549}, { -87, 10616}, { -86, 10684}, { -85, 10753},
922        {-84, 10823}, { -83, 10895}, { -82, 10968}, { -81, 11042}, { -80, 11117},
923        {-79, 11194}, { -78, 11272}, { -77, 11352}, { -76, 11433}, { -75, 11516},
924        {-74, 11600}, { -73, 11686}, { -72, 11774}, { -71, 11864}, { -70, 11955},
925        {-69, 12049}, { -68, 12144}, { -67, 12242}, { -66, 12341}, { -65, 12443},
926        {-64, 12548}, { -63, 12654}, { -62, 12763}, { -61, 12875}, { -60, 12990},
927        {-59, 13107}, { -58, 13227}, { -57, 13351}, { -56, 13477}, { -55, 13607},
928        {-54, 13741}, { -53, 13878}, { -52, 14019}, { -51, 14164}, { -50, 14313},
929        {-49, 14467}, { -48, 14626}, { -47, 14789}, { -46, 14958}, { -45, 15132},
930        {-44, 15312}, { -43, 15498}, { -42, 15691}, { -41, 15890}, { -40, 16097},
931        {-39, 16311}, { -38, 16534}, { -37, 16766}, { -36, 17007}, { -35, 17259},
932        {-34, 17521}, { -33, 17795}, { -32, 18081}, { -31, 18381}, { -30, 18696},
933        {-29, 19027}, { -28, 19375}, { -27, 19742}, { -26, 20129}, { -25, 20540},
934        {-24, 20976}, { -23, 21439}, { -22, 21934}, { -21, 22463}, { -20, 23031},
935        {-19, 23643}, { -18, 23999}
936    };
937
938    for(i = 0; i < 96; i++)
939    {
940        if(Hflevel <= LPFArray[i].Room_HF)
941            break;
942    }
943    return LPFArray[i].LPF;
944}
945
946//----------------------------------------------------------------------------
947// ReverbSetRoomHfLevel()
948//----------------------------------------------------------------------------
949// Purpose:
950// Apply the HF level to the Reverb. Must first be converted to LVM format
951//
952// Inputs:
953//  pContext:   effect engine context
954//  level       level to be applied
955//
956//----------------------------------------------------------------------------
957
958void ReverbSetRoomHfLevel(ReverbContext *pContext, int16_t level){
959    //ALOGV("\tReverbSetRoomHfLevel start (%d)", level);
960
961    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
962    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
963
964    /* Get the current settings */
965    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
966    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbSetRoomHfLevel")
967    //ALOGV("\tReverbSetRoomHfLevel Succesfully returned from LVM_GetControlParameters\n");
968    //ALOGV("\tReverbSetRoomHfLevel() just Got -> %d\n", ActiveParams.LPF);
969
970    ActiveParams.LPF = ReverbConvertHfLevel(level);
971
972    /* Activate the initial settings */
973    LvmStatus = LVREV_SetControlParameters(pContext->hInstance, &ActiveParams);
974    LVM_ERROR_CHECK(LvmStatus, "LVREV_SetControlParameters", "ReverbSetRoomHfLevel")
975    //ALOGV("\tReverbSetRoomhfLevel() just Set -> %d\n", ActiveParams.LPF);
976    pContext->SavedHfLevel = level;
977    //ALOGV("\tReverbSetHfRoomLevel end.. saving %d", pContext->SavedHfLevel);
978    return;
979}
980
981//----------------------------------------------------------------------------
982// ReverbGetRoomHfLevel()
983//----------------------------------------------------------------------------
984// Purpose:
985// Get the level applied to the Revervb. Must first be converted to LVM format
986//
987// Inputs:
988//  pContext:   effect engine context
989//
990//----------------------------------------------------------------------------
991
992int16_t ReverbGetRoomHfLevel(ReverbContext *pContext){
993    int16_t level;
994    //ALOGV("\tReverbGetRoomHfLevel start, saved level is %d", pContext->SavedHfLevel);
995
996    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
997    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
998
999    /* Get the current settings */
1000    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1001    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbGetRoomHfLevel")
1002    //ALOGV("\tReverbGetRoomHfLevel Succesfully returned from LVM_GetControlParameters\n");
1003    //ALOGV("\tReverbGetRoomHfLevel() just Got -> %d\n", ActiveParams.LPF);
1004
1005    level = ReverbConvertHfLevel(pContext->SavedHfLevel);
1006
1007    //ALOGV("\tReverbGetRoomHfLevel() ActiveParams.LPFL %d, pContext->SavedHfLevel: %d, "
1008    //     "converted level: %d\n", ActiveParams.LPF, pContext->SavedHfLevel, level);
1009
1010    if(ActiveParams.LPF != level){
1011        ALOGV("\tLVM_ERROR : (ignore at start up) ReverbGetRoomHfLevel() has wrong level -> %d %d\n",
1012               ActiveParams.Level, level);
1013    }
1014
1015    //ALOGV("\tReverbGetRoomHfLevel end");
1016    return pContext->SavedHfLevel;
1017}
1018
1019//----------------------------------------------------------------------------
1020// ReverbSetReverbLevel()
1021//----------------------------------------------------------------------------
1022// Purpose:
1023// Apply the level to the Reverb. Must first be converted to LVM format
1024//
1025// Inputs:
1026//  pContext:   effect engine context
1027//  level       level to be applied
1028//
1029//----------------------------------------------------------------------------
1030
1031void ReverbSetReverbLevel(ReverbContext *pContext, int16_t level){
1032    //ALOGV("\n\tReverbSetReverbLevel start (%d)", level);
1033
1034    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1035    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
1036    LVM_INT32                 CombinedLevel;             // Sum of room and reverb level controls
1037
1038    /* Get the current settings */
1039    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1040    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbSetReverbLevel")
1041    //ALOGV("\tReverbSetReverbLevel Succesfully returned from LVM_GetControlParameters\n");
1042    //ALOGV("\tReverbSetReverbLevel just Got -> %d\n", ActiveParams.Level);
1043
1044    // needs to subtract max levels for both RoomLevel and ReverbLevel
1045    CombinedLevel = (level + pContext->SavedRoomLevel)-LVREV_MAX_REVERB_LEVEL;
1046    //ALOGV("\tReverbSetReverbLevel() CombinedLevel is %d = %d + %d\n",
1047    //      CombinedLevel, level, pContext->SavedRoomLevel);
1048
1049    ActiveParams.Level = ReverbConvertLevel(CombinedLevel);
1050
1051    //ALOGV("\tReverbSetReverbLevel() Trying to set -> %d\n", ActiveParams.Level);
1052
1053    /* Activate the initial settings */
1054    LvmStatus = LVREV_SetControlParameters(pContext->hInstance, &ActiveParams);
1055    LVM_ERROR_CHECK(LvmStatus, "LVREV_SetControlParameters", "ReverbSetReverbLevel")
1056    //ALOGV("\tReverbSetReverbLevel() just Set -> %d\n", ActiveParams.Level);
1057
1058    pContext->SavedReverbLevel = level;
1059    //ALOGV("\tReverbSetReverbLevel end pContext->SavedReverbLevel is %d\n\n",
1060    //     pContext->SavedReverbLevel);
1061    return;
1062}
1063
1064//----------------------------------------------------------------------------
1065// ReverbGetReverbLevel()
1066//----------------------------------------------------------------------------
1067// Purpose:
1068// Get the level applied to the Revervb. Must first be converted to LVM format
1069//
1070// Inputs:
1071//  pContext:   effect engine context
1072//
1073//----------------------------------------------------------------------------
1074
1075int16_t ReverbGetReverbLevel(ReverbContext *pContext){
1076    int16_t level;
1077    //ALOGV("\tReverbGetReverbLevel start");
1078
1079    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1080    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
1081    LVM_INT32                 CombinedLevel;             // Sum of room and reverb level controls
1082
1083    /* Get the current settings */
1084    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1085    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbGetReverbLevel")
1086    //ALOGV("\tReverbGetReverbLevel Succesfully returned from LVM_GetControlParameters\n");
1087    //ALOGV("\tReverbGetReverbLevel() just Got -> %d\n", ActiveParams.Level);
1088
1089    // needs to subtract max levels for both RoomLevel and ReverbLevel
1090    CombinedLevel = (pContext->SavedReverbLevel + pContext->SavedRoomLevel)-LVREV_MAX_REVERB_LEVEL;
1091
1092    //ALOGV("\tReverbGetReverbLevel() CombinedLevel is %d = %d + %d\n",
1093    //CombinedLevel, pContext->SavedReverbLevel, pContext->SavedRoomLevel);
1094    level = ReverbConvertLevel(CombinedLevel);
1095
1096    //ALOGV("\tReverbGetReverbLevel(): ActiveParams.Level: %d, pContext->SavedReverbLevel: %d, "
1097    //"pContext->SavedRoomLevel: %d, CombinedLevel: %d, converted level: %d\n",
1098    //ActiveParams.Level, pContext->SavedReverbLevel,pContext->SavedRoomLevel, CombinedLevel,level);
1099
1100    if(ActiveParams.Level != level){
1101        ALOGV("\tLVM_ERROR : (ignore at start up) ReverbGetReverbLevel() has wrong level -> %d %d\n",
1102                ActiveParams.Level, level);
1103    }
1104
1105    //ALOGV("\tReverbGetReverbLevel end\n");
1106
1107    return pContext->SavedReverbLevel;
1108}
1109
1110//----------------------------------------------------------------------------
1111// ReverbSetRoomLevel()
1112//----------------------------------------------------------------------------
1113// Purpose:
1114// Apply the level to the Reverb. Must first be converted to LVM format
1115//
1116// Inputs:
1117//  pContext:   effect engine context
1118//  level       level to be applied
1119//
1120//----------------------------------------------------------------------------
1121
1122void ReverbSetRoomLevel(ReverbContext *pContext, int16_t level){
1123    //ALOGV("\tReverbSetRoomLevel start (%d)", level);
1124
1125    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1126    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
1127    LVM_INT32                 CombinedLevel;             // Sum of room and reverb level controls
1128
1129    /* Get the current settings */
1130    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1131    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbSetRoomLevel")
1132    //ALOGV("\tReverbSetRoomLevel Succesfully returned from LVM_GetControlParameters\n");
1133    //ALOGV("\tReverbSetRoomLevel() just Got -> %d\n", ActiveParams.Level);
1134
1135    // needs to subtract max levels for both RoomLevel and ReverbLevel
1136    CombinedLevel = (level + pContext->SavedReverbLevel)-LVREV_MAX_REVERB_LEVEL;
1137    ActiveParams.Level = ReverbConvertLevel(CombinedLevel);
1138
1139    /* Activate the initial settings */
1140    LvmStatus = LVREV_SetControlParameters(pContext->hInstance, &ActiveParams);
1141    LVM_ERROR_CHECK(LvmStatus, "LVREV_SetControlParameters", "ReverbSetRoomLevel")
1142    //ALOGV("\tReverbSetRoomLevel() just Set -> %d\n", ActiveParams.Level);
1143
1144    pContext->SavedRoomLevel = level;
1145    //ALOGV("\tReverbSetRoomLevel end");
1146    return;
1147}
1148
1149//----------------------------------------------------------------------------
1150// ReverbGetRoomLevel()
1151//----------------------------------------------------------------------------
1152// Purpose:
1153// Get the level applied to the Revervb. Must first be converted to LVM format
1154//
1155// Inputs:
1156//  pContext:   effect engine context
1157//
1158//----------------------------------------------------------------------------
1159
1160int16_t ReverbGetRoomLevel(ReverbContext *pContext){
1161    int16_t level;
1162    //ALOGV("\tReverbGetRoomLevel start");
1163
1164    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1165    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
1166    LVM_INT32                 CombinedLevel;             // Sum of room and reverb level controls
1167
1168    /* Get the current settings */
1169    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1170    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbGetRoomLevel")
1171    //ALOGV("\tReverbGetRoomLevel Succesfully returned from LVM_GetControlParameters\n");
1172    //ALOGV("\tReverbGetRoomLevel() just Got -> %d\n", ActiveParams.Level);
1173
1174    // needs to subtract max levels for both RoomLevel and ReverbLevel
1175    CombinedLevel = (pContext->SavedRoomLevel + pContext->SavedReverbLevel-LVREV_MAX_REVERB_LEVEL);
1176    level = ReverbConvertLevel(CombinedLevel);
1177
1178    //ALOGV("\tReverbGetRoomLevel, Level = %d, pContext->SavedRoomLevel = %d, "
1179    //     "pContext->SavedReverbLevel = %d, CombinedLevel = %d, level = %d",
1180    //     ActiveParams.Level, pContext->SavedRoomLevel,
1181    //     pContext->SavedReverbLevel, CombinedLevel, level);
1182
1183    if(ActiveParams.Level != level){
1184        ALOGV("\tLVM_ERROR : (ignore at start up) ReverbGetRoomLevel() has wrong level -> %d %d\n",
1185              ActiveParams.Level, level);
1186    }
1187
1188    //ALOGV("\tReverbGetRoomLevel end");
1189    return pContext->SavedRoomLevel;
1190}
1191
1192//----------------------------------------------------------------------------
1193// ReverbSetDecayTime()
1194//----------------------------------------------------------------------------
1195// Purpose:
1196// Apply the decay time to the Reverb.
1197//
1198// Inputs:
1199//  pContext:   effect engine context
1200//  time        decay to be applied
1201//
1202//----------------------------------------------------------------------------
1203
1204void ReverbSetDecayTime(ReverbContext *pContext, uint32_t time){
1205    //ALOGV("\tReverbSetDecayTime start (%d)", time);
1206
1207    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1208    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
1209
1210    /* Get the current settings */
1211    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1212    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbSetDecayTime")
1213    //ALOGV("\tReverbSetDecayTime Succesfully returned from LVM_GetControlParameters\n");
1214    //ALOGV("\tReverbSetDecayTime() just Got -> %d\n", ActiveParams.T60);
1215
1216    if (time <= LVREV_MAX_T60) {
1217        ActiveParams.T60 = (LVM_UINT16)time;
1218    }
1219    else {
1220        ActiveParams.T60 = LVREV_MAX_T60;
1221    }
1222
1223    /* Activate the initial settings */
1224    LvmStatus = LVREV_SetControlParameters(pContext->hInstance, &ActiveParams);
1225    LVM_ERROR_CHECK(LvmStatus, "LVREV_SetControlParameters", "ReverbSetDecayTime")
1226    //ALOGV("\tReverbSetDecayTime() just Set -> %d\n", ActiveParams.T60);
1227
1228    pContext->SamplesToExitCount = (ActiveParams.T60 * pContext->config.inputCfg.samplingRate)/1000;
1229    //ALOGV("\tReverbSetDecayTime() just Set SamplesToExitCount-> %d\n",pContext->SamplesToExitCount);
1230    pContext->SavedDecayTime = (int16_t)time;
1231    //ALOGV("\tReverbSetDecayTime end");
1232    return;
1233}
1234
1235//----------------------------------------------------------------------------
1236// ReverbGetDecayTime()
1237//----------------------------------------------------------------------------
1238// Purpose:
1239// Get the decay time applied to the Revervb.
1240//
1241// Inputs:
1242//  pContext:   effect engine context
1243//
1244//----------------------------------------------------------------------------
1245
1246uint32_t ReverbGetDecayTime(ReverbContext *pContext){
1247    //ALOGV("\tReverbGetDecayTime start");
1248
1249    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1250    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
1251
1252    /* Get the current settings */
1253    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1254    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbGetDecayTime")
1255    //ALOGV("\tReverbGetDecayTime Succesfully returned from LVM_GetControlParameters\n");
1256    //ALOGV("\tReverbGetDecayTime() just Got -> %d\n", ActiveParams.T60);
1257
1258    if(ActiveParams.T60 != pContext->SavedDecayTime){
1259        // This will fail if the decay time is set to more than 7000
1260        ALOGV("\tLVM_ERROR : ReverbGetDecayTime() has wrong level -> %d %d\n",
1261         ActiveParams.T60, pContext->SavedDecayTime);
1262    }
1263
1264    //ALOGV("\tReverbGetDecayTime end");
1265    return (uint32_t)ActiveParams.T60;
1266}
1267
1268//----------------------------------------------------------------------------
1269// ReverbSetDecayHfRatio()
1270//----------------------------------------------------------------------------
1271// Purpose:
1272// Apply the HF decay ratio to the Reverb.
1273//
1274// Inputs:
1275//  pContext:   effect engine context
1276//  ratio       ratio to be applied
1277//
1278//----------------------------------------------------------------------------
1279
1280void ReverbSetDecayHfRatio(ReverbContext *pContext, int16_t ratio){
1281    //ALOGV("\tReverbSetDecayHfRatioe start (%d)", ratio);
1282
1283    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1284    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;   /* Function call status */
1285
1286    /* Get the current settings */
1287    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1288    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbSetDecayHfRatio")
1289    //ALOGV("\tReverbSetDecayHfRatio Succesfully returned from LVM_GetControlParameters\n");
1290    //ALOGV("\tReverbSetDecayHfRatio() just Got -> %d\n", ActiveParams.Damping);
1291
1292    ActiveParams.Damping = (LVM_INT16)(ratio/20);
1293
1294    /* Activate the initial settings */
1295    LvmStatus = LVREV_SetControlParameters(pContext->hInstance, &ActiveParams);
1296    LVM_ERROR_CHECK(LvmStatus, "LVREV_SetControlParameters", "ReverbSetDecayHfRatio")
1297    //ALOGV("\tReverbSetDecayHfRatio() just Set -> %d\n", ActiveParams.Damping);
1298
1299    pContext->SavedDecayHfRatio = ratio;
1300    //ALOGV("\tReverbSetDecayHfRatio end");
1301    return;
1302}
1303
1304//----------------------------------------------------------------------------
1305// ReverbGetDecayHfRatio()
1306//----------------------------------------------------------------------------
1307// Purpose:
1308// Get the HF decay ratio applied to the Revervb.
1309//
1310// Inputs:
1311//  pContext:   effect engine context
1312//
1313//----------------------------------------------------------------------------
1314
1315int32_t ReverbGetDecayHfRatio(ReverbContext *pContext){
1316    //ALOGV("\tReverbGetDecayHfRatio start");
1317
1318    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1319    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;   /* Function call status */
1320
1321    /* Get the current settings */
1322    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1323    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbGetDecayHfRatio")
1324    //ALOGV("\tReverbGetDecayHfRatio Succesfully returned from LVM_GetControlParameters\n");
1325    //ALOGV("\tReverbGetDecayHfRatio() just Got -> %d\n", ActiveParams.Damping);
1326
1327    if(ActiveParams.Damping != (LVM_INT16)(pContext->SavedDecayHfRatio / 20)){
1328        ALOGV("\tLVM_ERROR : ReverbGetDecayHfRatio() has wrong level -> %d %d\n",
1329         ActiveParams.Damping, pContext->SavedDecayHfRatio);
1330    }
1331
1332    //ALOGV("\tReverbGetDecayHfRatio end");
1333    return pContext->SavedDecayHfRatio;
1334}
1335
1336//----------------------------------------------------------------------------
1337// ReverbSetDiffusion()
1338//----------------------------------------------------------------------------
1339// Purpose:
1340// Apply the diffusion to the Reverb.
1341//
1342// Inputs:
1343//  pContext:   effect engine context
1344//  level        decay to be applied
1345//
1346//----------------------------------------------------------------------------
1347
1348void ReverbSetDiffusion(ReverbContext *pContext, int16_t level){
1349    //ALOGV("\tReverbSetDiffusion start (%d)", level);
1350
1351    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1352    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
1353
1354    /* Get the current settings */
1355    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1356    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbSetDiffusion")
1357    //ALOGV("\tReverbSetDiffusion Succesfully returned from LVM_GetControlParameters\n");
1358    //ALOGV("\tReverbSetDiffusion() just Got -> %d\n", ActiveParams.Density);
1359
1360    ActiveParams.Density = (LVM_INT16)(level/10);
1361
1362    /* Activate the initial settings */
1363    LvmStatus = LVREV_SetControlParameters(pContext->hInstance, &ActiveParams);
1364    LVM_ERROR_CHECK(LvmStatus, "LVREV_SetControlParameters", "ReverbSetDiffusion")
1365    //ALOGV("\tReverbSetDiffusion() just Set -> %d\n", ActiveParams.Density);
1366
1367    pContext->SavedDiffusion = level;
1368    //ALOGV("\tReverbSetDiffusion end");
1369    return;
1370}
1371
1372//----------------------------------------------------------------------------
1373// ReverbGetDiffusion()
1374//----------------------------------------------------------------------------
1375// Purpose:
1376// Get the decay time applied to the Revervb.
1377//
1378// Inputs:
1379//  pContext:   effect engine context
1380//
1381//----------------------------------------------------------------------------
1382
1383int32_t ReverbGetDiffusion(ReverbContext *pContext){
1384    //ALOGV("\tReverbGetDiffusion start");
1385
1386    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1387    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
1388    LVM_INT16                 Temp;
1389
1390    /* Get the current settings */
1391    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1392    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbGetDiffusion")
1393    //ALOGV("\tReverbGetDiffusion Succesfully returned from LVM_GetControlParameters\n");
1394    //ALOGV("\tReverbGetDiffusion just Got -> %d\n", ActiveParams.Density);
1395
1396    Temp = (LVM_INT16)(pContext->SavedDiffusion/10);
1397
1398    if(ActiveParams.Density != Temp){
1399        ALOGV("\tLVM_ERROR : ReverbGetDiffusion invalid value %d %d", Temp, ActiveParams.Density);
1400    }
1401
1402    //ALOGV("\tReverbGetDiffusion end");
1403    return pContext->SavedDiffusion;
1404}
1405
1406//----------------------------------------------------------------------------
1407// ReverbSetDensity()
1408//----------------------------------------------------------------------------
1409// Purpose:
1410// Apply the density level the Reverb.
1411//
1412// Inputs:
1413//  pContext:   effect engine context
1414//  level        decay to be applied
1415//
1416//----------------------------------------------------------------------------
1417
1418void ReverbSetDensity(ReverbContext *pContext, int16_t level){
1419    //ALOGV("\tReverbSetDensity start (%d)", level);
1420
1421    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1422    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
1423
1424    /* Get the current settings */
1425    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1426    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbSetDensity")
1427    //ALOGV("\tReverbSetDensity Succesfully returned from LVM_GetControlParameters\n");
1428    //ALOGV("\tReverbSetDensity just Got -> %d\n", ActiveParams.RoomSize);
1429
1430    ActiveParams.RoomSize = (LVM_INT16)(((level * 99) / 1000) + 1);
1431
1432    /* Activate the initial settings */
1433    LvmStatus = LVREV_SetControlParameters(pContext->hInstance, &ActiveParams);
1434    LVM_ERROR_CHECK(LvmStatus, "LVREV_SetControlParameters", "ReverbSetDensity")
1435    //ALOGV("\tReverbSetDensity just Set -> %d\n", ActiveParams.RoomSize);
1436
1437    pContext->SavedDensity = level;
1438    //ALOGV("\tReverbSetDensity end");
1439    return;
1440}
1441
1442//----------------------------------------------------------------------------
1443// ReverbGetDensity()
1444//----------------------------------------------------------------------------
1445// Purpose:
1446// Get the density level applied to the Revervb.
1447//
1448// Inputs:
1449//  pContext:   effect engine context
1450//
1451//----------------------------------------------------------------------------
1452
1453int32_t ReverbGetDensity(ReverbContext *pContext){
1454    //ALOGV("\tReverbGetDensity start");
1455
1456    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1457    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
1458    LVM_INT16                 Temp;
1459    /* Get the current settings */
1460    LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
1461    LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "ReverbGetDensity")
1462    //ALOGV("\tReverbGetDensity Succesfully returned from LVM_GetControlParameters\n");
1463    //ALOGV("\tReverbGetDensity() just Got -> %d\n", ActiveParams.RoomSize);
1464
1465
1466    Temp = (LVM_INT16)(((pContext->SavedDensity * 99) / 1000) + 1);
1467
1468    if(Temp != ActiveParams.RoomSize){
1469        ALOGV("\tLVM_ERROR : ReverbGetDensity invalid value %d %d", Temp, ActiveParams.RoomSize);
1470    }
1471
1472    //ALOGV("\tReverbGetDensity end");
1473    return pContext->SavedDensity;
1474}
1475
1476//----------------------------------------------------------------------------
1477// Reverb_LoadPreset()
1478//----------------------------------------------------------------------------
1479// Purpose:
1480// Load a the next preset
1481//
1482// Inputs:
1483//  pContext         - handle to instance data
1484//
1485// Outputs:
1486//
1487// Side Effects:
1488//
1489//----------------------------------------------------------------------------
1490int Reverb_LoadPreset(ReverbContext   *pContext)
1491{
1492    //TODO: add reflections delay, level and reverb delay when early reflections are
1493    // implemented
1494    pContext->curPreset = pContext->nextPreset;
1495
1496    if (pContext->curPreset != REVERB_PRESET_NONE) {
1497        const t_reverb_settings *preset = &sReverbPresets[pContext->curPreset];
1498        ReverbSetRoomLevel(pContext, preset->roomLevel);
1499        ReverbSetRoomHfLevel(pContext, preset->roomHFLevel);
1500        ReverbSetDecayTime(pContext, preset->decayTime);
1501        ReverbSetDecayHfRatio(pContext, preset->decayHFRatio);
1502        //reflectionsLevel
1503        //reflectionsDelay
1504        ReverbSetReverbLevel(pContext, preset->reverbLevel);
1505        // reverbDelay
1506        ReverbSetDiffusion(pContext, preset->diffusion);
1507        ReverbSetDensity(pContext, preset->density);
1508    }
1509
1510    return 0;
1511}
1512
1513
1514//----------------------------------------------------------------------------
1515// Reverb_getParameter()
1516//----------------------------------------------------------------------------
1517// Purpose:
1518// Get a Reverb parameter
1519//
1520// Inputs:
1521//  pContext         - handle to instance data
1522//  pParam           - pointer to parameter
1523//  pValue           - pointer to variable to hold retrieved value
1524//  pValueSize       - pointer to value size: maximum size as input
1525//
1526// Outputs:
1527//  *pValue updated with parameter value
1528//  *pValueSize updated with actual value size
1529//
1530//
1531// Side Effects:
1532//
1533//----------------------------------------------------------------------------
1534
1535int Reverb_getParameter(ReverbContext *pContext,
1536                        void          *pParam,
1537                        size_t        *pValueSize,
1538                        void          *pValue){
1539    int status = 0;
1540    int32_t *pParamTemp = (int32_t *)pParam;
1541    int32_t param = *pParamTemp++;
1542    char *name;
1543    t_reverb_settings *pProperties;
1544
1545    //ALOGV("\tReverb_getParameter start");
1546    if (pContext->preset) {
1547        if (param != REVERB_PARAM_PRESET || *pValueSize < sizeof(uint16_t)) {
1548            return -EINVAL;
1549        }
1550
1551        *(uint16_t *)pValue = pContext->nextPreset;
1552        ALOGV("get REVERB_PARAM_PRESET, preset %d", pContext->nextPreset);
1553        return 0;
1554    }
1555
1556    switch (param){
1557        case REVERB_PARAM_ROOM_LEVEL:
1558            if (*pValueSize != sizeof(int16_t)){
1559                ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid pValueSize1 %d", *pValueSize);
1560                return -EINVAL;
1561            }
1562            *pValueSize = sizeof(int16_t);
1563            break;
1564        case REVERB_PARAM_ROOM_HF_LEVEL:
1565            if (*pValueSize != sizeof(int16_t)){
1566                ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid pValueSize12 %d", *pValueSize);
1567                return -EINVAL;
1568            }
1569            *pValueSize = sizeof(int16_t);
1570            break;
1571        case REVERB_PARAM_DECAY_TIME:
1572            if (*pValueSize != sizeof(uint32_t)){
1573                ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid pValueSize3 %d", *pValueSize);
1574                return -EINVAL;
1575            }
1576            *pValueSize = sizeof(uint32_t);
1577            break;
1578        case REVERB_PARAM_DECAY_HF_RATIO:
1579            if (*pValueSize != sizeof(int16_t)){
1580                ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid pValueSize4 %d", *pValueSize);
1581                return -EINVAL;
1582            }
1583            *pValueSize = sizeof(int16_t);
1584            break;
1585        case REVERB_PARAM_REFLECTIONS_LEVEL:
1586            if (*pValueSize != sizeof(int16_t)){
1587                ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid pValueSize5 %d", *pValueSize);
1588                return -EINVAL;
1589            }
1590            *pValueSize = sizeof(int16_t);
1591            break;
1592        case REVERB_PARAM_REFLECTIONS_DELAY:
1593            if (*pValueSize != sizeof(uint32_t)){
1594                ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid pValueSize6 %d", *pValueSize);
1595                return -EINVAL;
1596            }
1597            *pValueSize = sizeof(uint32_t);
1598            break;
1599        case REVERB_PARAM_REVERB_LEVEL:
1600            if (*pValueSize != sizeof(int16_t)){
1601                ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid pValueSize7 %d", *pValueSize);
1602                return -EINVAL;
1603            }
1604            *pValueSize = sizeof(int16_t);
1605            break;
1606        case REVERB_PARAM_REVERB_DELAY:
1607            if (*pValueSize != sizeof(uint32_t)){
1608                ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid pValueSize8 %d", *pValueSize);
1609                return -EINVAL;
1610            }
1611            *pValueSize = sizeof(uint32_t);
1612            break;
1613        case REVERB_PARAM_DIFFUSION:
1614            if (*pValueSize != sizeof(int16_t)){
1615                ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid pValueSize9 %d", *pValueSize);
1616                return -EINVAL;
1617            }
1618            *pValueSize = sizeof(int16_t);
1619            break;
1620        case REVERB_PARAM_DENSITY:
1621            if (*pValueSize != sizeof(int16_t)){
1622                ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid pValueSize10 %d", *pValueSize);
1623                return -EINVAL;
1624            }
1625            *pValueSize = sizeof(int16_t);
1626            break;
1627        case REVERB_PARAM_PROPERTIES:
1628            if (*pValueSize != sizeof(t_reverb_settings)){
1629                ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid pValueSize11 %d", *pValueSize);
1630                return -EINVAL;
1631            }
1632            *pValueSize = sizeof(t_reverb_settings);
1633            break;
1634
1635        default:
1636            ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid param %d", param);
1637            return -EINVAL;
1638    }
1639
1640    pProperties = (t_reverb_settings *) pValue;
1641
1642    switch (param){
1643        case REVERB_PARAM_PROPERTIES:
1644            pProperties->roomLevel = ReverbGetRoomLevel(pContext);
1645            pProperties->roomHFLevel = ReverbGetRoomHfLevel(pContext);
1646            pProperties->decayTime = ReverbGetDecayTime(pContext);
1647            pProperties->decayHFRatio = ReverbGetDecayHfRatio(pContext);
1648            pProperties->reflectionsLevel = 0;
1649            pProperties->reflectionsDelay = 0;
1650            pProperties->reverbDelay = 0;
1651            pProperties->reverbLevel = ReverbGetReverbLevel(pContext);
1652            pProperties->diffusion = ReverbGetDiffusion(pContext);
1653            pProperties->density = ReverbGetDensity(pContext);
1654
1655            ALOGV("\tReverb_getParameter() REVERB_PARAM_PROPERTIES Value is roomLevel        %d",
1656                pProperties->roomLevel);
1657            ALOGV("\tReverb_getParameter() REVERB_PARAM_PROPERTIES Value is roomHFLevel      %d",
1658                pProperties->roomHFLevel);
1659            ALOGV("\tReverb_getParameter() REVERB_PARAM_PROPERTIES Value is decayTime        %d",
1660                pProperties->decayTime);
1661            ALOGV("\tReverb_getParameter() REVERB_PARAM_PROPERTIES Value is decayHFRatio     %d",
1662                pProperties->decayHFRatio);
1663            ALOGV("\tReverb_getParameter() REVERB_PARAM_PROPERTIES Value is reflectionsLevel %d",
1664                pProperties->reflectionsLevel);
1665            ALOGV("\tReverb_getParameter() REVERB_PARAM_PROPERTIES Value is reflectionsDelay %d",
1666                pProperties->reflectionsDelay);
1667            ALOGV("\tReverb_getParameter() REVERB_PARAM_PROPERTIES Value is reverbDelay      %d",
1668                pProperties->reverbDelay);
1669            ALOGV("\tReverb_getParameter() REVERB_PARAM_PROPERTIES Value is reverbLevel      %d",
1670                pProperties->reverbLevel);
1671            ALOGV("\tReverb_getParameter() REVERB_PARAM_PROPERTIES Value is diffusion        %d",
1672                pProperties->diffusion);
1673            ALOGV("\tReverb_getParameter() REVERB_PARAM_PROPERTIES Value is density          %d",
1674                pProperties->density);
1675            break;
1676
1677        case REVERB_PARAM_ROOM_LEVEL:
1678            *(int16_t *)pValue = ReverbGetRoomLevel(pContext);
1679
1680            //ALOGV("\tReverb_getParameter() REVERB_PARAM_ROOM_LEVEL Value is %d",
1681            //        *(int16_t *)pValue);
1682            break;
1683        case REVERB_PARAM_ROOM_HF_LEVEL:
1684            *(int16_t *)pValue = ReverbGetRoomHfLevel(pContext);
1685
1686            //ALOGV("\tReverb_getParameter() REVERB_PARAM_ROOM_HF_LEVEL Value is %d",
1687            //        *(int16_t *)pValue);
1688            break;
1689        case REVERB_PARAM_DECAY_TIME:
1690            *(uint32_t *)pValue = ReverbGetDecayTime(pContext);
1691
1692            //ALOGV("\tReverb_getParameter() REVERB_PARAM_DECAY_TIME Value is %d",
1693            //        *(int32_t *)pValue);
1694            break;
1695        case REVERB_PARAM_DECAY_HF_RATIO:
1696            *(int16_t *)pValue = ReverbGetDecayHfRatio(pContext);
1697
1698            //ALOGV("\tReverb_getParameter() REVERB_PARAM_DECAY_HF_RATION Value is %d",
1699            //        *(int16_t *)pValue);
1700            break;
1701        case REVERB_PARAM_REVERB_LEVEL:
1702             *(int16_t *)pValue = ReverbGetReverbLevel(pContext);
1703
1704            //ALOGV("\tReverb_getParameter() REVERB_PARAM_REVERB_LEVEL Value is %d",
1705            //        *(int16_t *)pValue);
1706            break;
1707        case REVERB_PARAM_DIFFUSION:
1708            *(int16_t *)pValue = ReverbGetDiffusion(pContext);
1709
1710            //ALOGV("\tReverb_getParameter() REVERB_PARAM_DECAY_DIFFUSION Value is %d",
1711            //        *(int16_t *)pValue);
1712            break;
1713        case REVERB_PARAM_DENSITY:
1714            *(uint16_t *)pValue = 0;
1715            *(int16_t *)pValue = ReverbGetDensity(pContext);
1716            //ALOGV("\tReverb_getParameter() REVERB_PARAM_DENSITY Value is %d",
1717            //        *(uint32_t *)pValue);
1718            break;
1719        case REVERB_PARAM_REFLECTIONS_LEVEL:
1720            *(uint16_t *)pValue = 0;
1721        case REVERB_PARAM_REFLECTIONS_DELAY:
1722            *(uint32_t *)pValue = 0;
1723        case REVERB_PARAM_REVERB_DELAY:
1724            *(uint32_t *)pValue = 0;
1725            break;
1726
1727        default:
1728            ALOGV("\tLVM_ERROR : Reverb_getParameter() invalid param %d", param);
1729            status = -EINVAL;
1730            break;
1731    }
1732
1733    //ALOGV("\tReverb_getParameter end");
1734    return status;
1735} /* end Reverb_getParameter */
1736
1737//----------------------------------------------------------------------------
1738// Reverb_setParameter()
1739//----------------------------------------------------------------------------
1740// Purpose:
1741// Set a Reverb parameter
1742//
1743// Inputs:
1744//  pContext         - handle to instance data
1745//  pParam           - pointer to parameter
1746//  pValue           - pointer to value
1747//
1748// Outputs:
1749//
1750//----------------------------------------------------------------------------
1751
1752int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue){
1753    int status = 0;
1754    int16_t level;
1755    int16_t ratio;
1756    uint32_t time;
1757    t_reverb_settings *pProperties;
1758    int32_t *pParamTemp = (int32_t *)pParam;
1759    int32_t param = *pParamTemp++;
1760
1761    //ALOGV("\tReverb_setParameter start");
1762    if (pContext->preset) {
1763        if (param != REVERB_PARAM_PRESET) {
1764            return -EINVAL;
1765        }
1766
1767        uint16_t preset = *(uint16_t *)pValue;
1768        ALOGV("set REVERB_PARAM_PRESET, preset %d", preset);
1769        if (preset > REVERB_PRESET_LAST) {
1770            return -EINVAL;
1771        }
1772        pContext->nextPreset = preset;
1773        return 0;
1774    }
1775
1776    switch (param){
1777        case REVERB_PARAM_PROPERTIES:
1778            ALOGV("\tReverb_setParameter() REVERB_PARAM_PROPERTIES");
1779            pProperties = (t_reverb_settings *) pValue;
1780            ReverbSetRoomLevel(pContext, pProperties->roomLevel);
1781            ReverbSetRoomHfLevel(pContext, pProperties->roomHFLevel);
1782            ReverbSetDecayTime(pContext, pProperties->decayTime);
1783            ReverbSetDecayHfRatio(pContext, pProperties->decayHFRatio);
1784            ReverbSetReverbLevel(pContext, pProperties->reverbLevel);
1785            ReverbSetDiffusion(pContext, pProperties->diffusion);
1786            ReverbSetDensity(pContext, pProperties->density);
1787            break;
1788        case REVERB_PARAM_ROOM_LEVEL:
1789            level = *(int16_t *)pValue;
1790            //ALOGV("\tReverb_setParameter() REVERB_PARAM_ROOM_LEVEL value is %d", level);
1791            //ALOGV("\tReverb_setParameter() Calling ReverbSetRoomLevel");
1792            ReverbSetRoomLevel(pContext, level);
1793            //ALOGV("\tReverb_setParameter() Called ReverbSetRoomLevel");
1794           break;
1795        case REVERB_PARAM_ROOM_HF_LEVEL:
1796            level = *(int16_t *)pValue;
1797            //ALOGV("\tReverb_setParameter() REVERB_PARAM_ROOM_HF_LEVEL value is %d", level);
1798            //ALOGV("\tReverb_setParameter() Calling ReverbSetRoomHfLevel");
1799            ReverbSetRoomHfLevel(pContext, level);
1800            //ALOGV("\tReverb_setParameter() Called ReverbSetRoomHfLevel");
1801           break;
1802        case REVERB_PARAM_DECAY_TIME:
1803            time = *(uint32_t *)pValue;
1804            //ALOGV("\tReverb_setParameter() REVERB_PARAM_DECAY_TIME value is %d", time);
1805            //ALOGV("\tReverb_setParameter() Calling ReverbSetDecayTime");
1806            ReverbSetDecayTime(pContext, time);
1807            //ALOGV("\tReverb_setParameter() Called ReverbSetDecayTime");
1808           break;
1809        case REVERB_PARAM_DECAY_HF_RATIO:
1810            ratio = *(int16_t *)pValue;
1811            //ALOGV("\tReverb_setParameter() REVERB_PARAM_DECAY_HF_RATIO value is %d", ratio);
1812            //ALOGV("\tReverb_setParameter() Calling ReverbSetDecayHfRatio");
1813            ReverbSetDecayHfRatio(pContext, ratio);
1814            //ALOGV("\tReverb_setParameter() Called ReverbSetDecayHfRatio");
1815            break;
1816         case REVERB_PARAM_REVERB_LEVEL:
1817            level = *(int16_t *)pValue;
1818            //ALOGV("\tReverb_setParameter() REVERB_PARAM_REVERB_LEVEL value is %d", level);
1819            //ALOGV("\tReverb_setParameter() Calling ReverbSetReverbLevel");
1820            ReverbSetReverbLevel(pContext, level);
1821            //ALOGV("\tReverb_setParameter() Called ReverbSetReverbLevel");
1822           break;
1823        case REVERB_PARAM_DIFFUSION:
1824            ratio = *(int16_t *)pValue;
1825            //ALOGV("\tReverb_setParameter() REVERB_PARAM_DECAY_DIFFUSION value is %d", ratio);
1826            //ALOGV("\tReverb_setParameter() Calling ReverbSetDiffusion");
1827            ReverbSetDiffusion(pContext, ratio);
1828            //ALOGV("\tReverb_setParameter() Called ReverbSetDiffusion");
1829            break;
1830        case REVERB_PARAM_DENSITY:
1831            ratio = *(int16_t *)pValue;
1832            //ALOGV("\tReverb_setParameter() REVERB_PARAM_DECAY_DENSITY value is %d", ratio);
1833            //ALOGV("\tReverb_setParameter() Calling ReverbSetDensity");
1834            ReverbSetDensity(pContext, ratio);
1835            //ALOGV("\tReverb_setParameter() Called ReverbSetDensity");
1836            break;
1837           break;
1838        case REVERB_PARAM_REFLECTIONS_LEVEL:
1839        case REVERB_PARAM_REFLECTIONS_DELAY:
1840        case REVERB_PARAM_REVERB_DELAY:
1841            break;
1842        default:
1843            ALOGV("\tLVM_ERROR : Reverb_setParameter() invalid param %d", param);
1844            break;
1845    }
1846
1847    //ALOGV("\tReverb_setParameter end");
1848    return status;
1849} /* end Reverb_setParameter */
1850
1851} // namespace
1852} // namespace
1853
1854extern "C" {
1855/* Effect Control Interface Implementation: Process */
1856int Reverb_process(effect_handle_t   self,
1857                                 audio_buffer_t         *inBuffer,
1858                                 audio_buffer_t         *outBuffer){
1859    android::ReverbContext * pContext = (android::ReverbContext *) self;
1860    int    status = 0;
1861
1862    if (pContext == NULL){
1863        ALOGV("\tLVM_ERROR : Reverb_process() ERROR pContext == NULL");
1864        return -EINVAL;
1865    }
1866    if (inBuffer == NULL  || inBuffer->raw == NULL  ||
1867            outBuffer == NULL || outBuffer->raw == NULL ||
1868            inBuffer->frameCount != outBuffer->frameCount){
1869        ALOGV("\tLVM_ERROR : Reverb_process() ERROR NULL INPUT POINTER OR FRAME COUNT IS WRONG");
1870        return -EINVAL;
1871    }
1872    //ALOGV("\tReverb_process() Calling process with %d frames", outBuffer->frameCount);
1873    /* Process all the available frames, block processing is handled internalLY by the LVM bundle */
1874    status = process(    (LVM_INT16 *)inBuffer->raw,
1875                         (LVM_INT16 *)outBuffer->raw,
1876                                      outBuffer->frameCount,
1877                                      pContext);
1878
1879    if (pContext->bEnabled == LVM_FALSE) {
1880        if (pContext->SamplesToExitCount > 0) {
1881            pContext->SamplesToExitCount -= outBuffer->frameCount;
1882        } else {
1883            status = -ENODATA;
1884        }
1885    }
1886
1887    return status;
1888}   /* end Reverb_process */
1889
1890/* Effect Control Interface Implementation: Command */
1891int Reverb_command(effect_handle_t  self,
1892                              uint32_t            cmdCode,
1893                              uint32_t            cmdSize,
1894                              void                *pCmdData,
1895                              uint32_t            *replySize,
1896                              void                *pReplyData){
1897    android::ReverbContext * pContext = (android::ReverbContext *) self;
1898    int retsize;
1899    LVREV_ControlParams_st    ActiveParams;              /* Current control Parameters */
1900    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;     /* Function call status */
1901
1902
1903    if (pContext == NULL){
1904        ALOGV("\tLVM_ERROR : Reverb_command ERROR pContext == NULL");
1905        return -EINVAL;
1906    }
1907
1908    //ALOGV("\tReverb_command INPUTS are: command %d cmdSize %d",cmdCode, cmdSize);
1909
1910    switch (cmdCode){
1911        case EFFECT_CMD_INIT:
1912            //ALOGV("\tReverb_command cmdCode Case: "
1913            //        "EFFECT_CMD_INIT start");
1914
1915            if (pReplyData == NULL || *replySize != sizeof(int)){
1916                ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
1917                        "EFFECT_CMD_INIT: ERROR");
1918                return -EINVAL;
1919            }
1920            *(int *) pReplyData = 0;
1921            break;
1922
1923        case EFFECT_CMD_SET_CONFIG:
1924            //ALOGV("\tReverb_command cmdCode Case: "
1925            //        "EFFECT_CMD_SET_CONFIG start");
1926            if (pCmdData == NULL ||
1927                cmdSize != sizeof(effect_config_t) ||
1928                pReplyData == NULL ||
1929                *replySize != sizeof(int)) {
1930                ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
1931                        "EFFECT_CMD_SET_CONFIG: ERROR");
1932                return -EINVAL;
1933            }
1934            *(int *) pReplyData = android::Reverb_setConfig(pContext,
1935                                                            (effect_config_t *) pCmdData);
1936            break;
1937
1938        case EFFECT_CMD_GET_CONFIG:
1939            if (pReplyData == NULL ||
1940                *replySize != sizeof(effect_config_t)) {
1941                ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
1942                        "EFFECT_CMD_GET_CONFIG: ERROR");
1943                return -EINVAL;
1944            }
1945
1946            android::Reverb_getConfig(pContext, (effect_config_t *)pReplyData);
1947            break;
1948
1949        case EFFECT_CMD_RESET:
1950            //ALOGV("\tReverb_command cmdCode Case: "
1951            //        "EFFECT_CMD_RESET start");
1952            Reverb_setConfig(pContext, &pContext->config);
1953            break;
1954
1955        case EFFECT_CMD_GET_PARAM:{
1956            //ALOGV("\tReverb_command cmdCode Case: "
1957            //        "EFFECT_CMD_GET_PARAM start");
1958            if (pCmdData == NULL ||
1959                    cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
1960                    pReplyData == NULL ||
1961                    *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))){
1962                ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
1963                        "EFFECT_CMD_GET_PARAM: ERROR");
1964                return -EINVAL;
1965            }
1966            effect_param_t *p = (effect_param_t *)pCmdData;
1967
1968            memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + p->psize);
1969
1970            p = (effect_param_t *)pReplyData;
1971
1972            int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
1973
1974            p->status = android::Reverb_getParameter(pContext,
1975                                                         (void *)p->data,
1976                                                         (size_t  *)&p->vsize,
1977                                                          p->data + voffset);
1978
1979            *replySize = sizeof(effect_param_t) + voffset + p->vsize;
1980
1981            //ALOGV("\tReverb_command EFFECT_CMD_GET_PARAM "
1982            //        "*pCmdData %d, *replySize %d, *pReplyData %d ",
1983            //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
1984            //        *replySize,
1985            //        *(int16_t *)((char *)pReplyData + sizeof(effect_param_t) + voffset));
1986
1987        } break;
1988        case EFFECT_CMD_SET_PARAM:{
1989
1990            //ALOGV("\tReverb_command cmdCode Case: "
1991            //        "EFFECT_CMD_SET_PARAM start");
1992            //ALOGV("\tReverb_command EFFECT_CMD_SET_PARAM param %d, *replySize %d, value %d ",
1993            //        *(int32_t *)((char *)pCmdData + sizeof(effect_param_t)),
1994            //        *replySize,
1995            //        *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
1996
1997            if (pCmdData == NULL || (cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)))
1998                    || pReplyData == NULL || *replySize != (int)sizeof(int32_t)) {
1999                ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
2000                        "EFFECT_CMD_SET_PARAM: ERROR");
2001                return -EINVAL;
2002            }
2003
2004            effect_param_t *p = (effect_param_t *) pCmdData;
2005
2006            if (p->psize != sizeof(int32_t)){
2007                ALOGV("\t4LVM_ERROR : Reverb_command cmdCode Case: "
2008                        "EFFECT_CMD_SET_PARAM: ERROR, psize is not sizeof(int32_t)");
2009                return -EINVAL;
2010            }
2011
2012            //ALOGV("\tn5Reverb_command cmdSize is %d\n"
2013            //        "\tsizeof(effect_param_t) is  %d\n"
2014            //        "\tp->psize is %d\n"
2015            //        "\tp->vsize is %d"
2016            //        "\n",
2017            //        cmdSize, sizeof(effect_param_t), p->psize, p->vsize );
2018
2019            *(int *)pReplyData = android::Reverb_setParameter(pContext,
2020                                                             (void *)p->data,
2021                                                              p->data + p->psize);
2022        } break;
2023
2024        case EFFECT_CMD_ENABLE:
2025            //ALOGV("\tReverb_command cmdCode Case: "
2026            //        "EFFECT_CMD_ENABLE start");
2027
2028            if (pReplyData == NULL || *replySize != sizeof(int)){
2029                ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
2030                        "EFFECT_CMD_ENABLE: ERROR");
2031                return -EINVAL;
2032            }
2033            if(pContext->bEnabled == LVM_TRUE){
2034                 ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
2035                         "EFFECT_CMD_ENABLE: ERROR-Effect is already enabled");
2036                 return -EINVAL;
2037             }
2038            *(int *)pReplyData = 0;
2039            pContext->bEnabled = LVM_TRUE;
2040            /* Get the current settings */
2041            LvmStatus = LVREV_GetControlParameters(pContext->hInstance, &ActiveParams);
2042            LVM_ERROR_CHECK(LvmStatus, "LVREV_GetControlParameters", "EFFECT_CMD_ENABLE")
2043            pContext->SamplesToExitCount =
2044                    (ActiveParams.T60 * pContext->config.inputCfg.samplingRate)/1000;
2045            // force no volume ramp for first buffer processed after enabling the effect
2046            pContext->volumeMode = android::REVERB_VOLUME_FLAT;
2047            //ALOGV("\tEFFECT_CMD_ENABLE SamplesToExitCount = %d", pContext->SamplesToExitCount);
2048            break;
2049        case EFFECT_CMD_DISABLE:
2050            //ALOGV("\tReverb_command cmdCode Case: "
2051            //        "EFFECT_CMD_DISABLE start");
2052
2053            if (pReplyData == NULL || *replySize != sizeof(int)){
2054                ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
2055                        "EFFECT_CMD_DISABLE: ERROR");
2056                return -EINVAL;
2057            }
2058            if(pContext->bEnabled == LVM_FALSE){
2059                 ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
2060                         "EFFECT_CMD_DISABLE: ERROR-Effect is not yet enabled");
2061                 return -EINVAL;
2062             }
2063            *(int *)pReplyData = 0;
2064            pContext->bEnabled = LVM_FALSE;
2065            break;
2066
2067        case EFFECT_CMD_SET_VOLUME:
2068            if (pCmdData == NULL ||
2069                cmdSize != 2 * sizeof(uint32_t)) {
2070                ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
2071                        "EFFECT_CMD_SET_VOLUME: ERROR");
2072                return -EINVAL;
2073            }
2074
2075
2076            if (pReplyData != NULL) { // we have volume control
2077                pContext->leftVolume = (LVM_INT16)((*(uint32_t *)pCmdData + (1 << 11)) >> 12);
2078                pContext->rightVolume = (LVM_INT16)((*((uint32_t *)pCmdData + 1) + (1 << 11)) >> 12);
2079                *(uint32_t *)pReplyData = (1 << 24);
2080                *((uint32_t *)pReplyData + 1) = (1 << 24);
2081                if (pContext->volumeMode == android::REVERB_VOLUME_OFF) {
2082                    // force no volume ramp for first buffer processed after getting volume control
2083                    pContext->volumeMode = android::REVERB_VOLUME_FLAT;
2084                }
2085            } else { // we don't have volume control
2086                pContext->leftVolume = REVERB_UNIT_VOLUME;
2087                pContext->rightVolume = REVERB_UNIT_VOLUME;
2088                pContext->volumeMode = android::REVERB_VOLUME_OFF;
2089            }
2090            ALOGV("EFFECT_CMD_SET_VOLUME left %d, right %d mode %d",
2091                    pContext->leftVolume, pContext->rightVolume,  pContext->volumeMode);
2092            break;
2093
2094        case EFFECT_CMD_SET_DEVICE:
2095        case EFFECT_CMD_SET_AUDIO_MODE:
2096        //ALOGV("\tReverb_command cmdCode Case: "
2097        //        "EFFECT_CMD_SET_DEVICE/EFFECT_CMD_SET_VOLUME/EFFECT_CMD_SET_AUDIO_MODE start");
2098            break;
2099
2100        default:
2101            ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
2102                    "DEFAULT start %d ERROR",cmdCode);
2103            return -EINVAL;
2104    }
2105
2106    //ALOGV("\tReverb_command end\n\n");
2107    return 0;
2108}    /* end Reverb_command */
2109
2110/* Effect Control Interface Implementation: get_descriptor */
2111int Reverb_getDescriptor(effect_handle_t   self,
2112                                    effect_descriptor_t *pDescriptor)
2113{
2114    android::ReverbContext * pContext = (android::ReverbContext *)self;
2115    const effect_descriptor_t *desc;
2116
2117    if (pContext == NULL || pDescriptor == NULL) {
2118        ALOGV("Reverb_getDescriptor() invalid param");
2119        return -EINVAL;
2120    }
2121
2122    if (pContext->auxiliary) {
2123        if (pContext->preset) {
2124            desc = &android::gAuxPresetReverbDescriptor;
2125        } else {
2126            desc = &android::gAuxEnvReverbDescriptor;
2127        }
2128    } else {
2129        if (pContext->preset) {
2130            desc = &android::gInsertPresetReverbDescriptor;
2131        } else {
2132            desc = &android::gInsertEnvReverbDescriptor;
2133        }
2134    }
2135
2136    *pDescriptor = *desc;
2137
2138    return 0;
2139}   /* end Reverb_getDescriptor */
2140
2141// effect_handle_t interface implementation for Reverb effect
2142const struct effect_interface_s gReverbInterface = {
2143    Reverb_process,
2144    Reverb_command,
2145    Reverb_getDescriptor,
2146    NULL,
2147};    /* end gReverbInterface */
2148
2149// This is the only symbol that needs to be exported
2150__attribute__ ((visibility ("default")))
2151audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
2152    tag : AUDIO_EFFECT_LIBRARY_TAG,
2153    version : EFFECT_LIBRARY_API_VERSION,
2154    name : "Reverb Library",
2155    implementor : "NXP Software Ltd.",
2156    create_effect : android::EffectCreate,
2157    release_effect : android::EffectRelease,
2158    get_descriptor : android::EffectGetDescriptor,
2159};
2160
2161}
2162