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