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