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