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