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