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