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