1c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent/*
2c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent * Copyright (C) 2010-2010 NXP Software
3c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent * Copyright (C) 2009 The Android Open Source Project
4c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent *
5c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
6c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent * you may not use this file except in compliance with the License.
7c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent * You may obtain a copy of the License at
8c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent *
9c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
10c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent *
11c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent * Unless required by applicable law or agreed to in writing, software
12c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
13c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent * See the License for the specific language governing permissions and
15c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent * limitations under the License.
16c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent */
17c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
18c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent#define LOG_TAG "Reverb"
19c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
2097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent//#define LOG_NDEBUG 0
21c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
22c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent#include <cutils/log.h>
23c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent#include <assert.h>
24c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent#include <stdlib.h>
25c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent#include <string.h>
26c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent#include <new>
27b4d307481960b6b348fae4b4e8edefd003c3d36cGlenn Kasten#include "EffectReverb.h"
28b4d307481960b6b348fae4b4e8edefd003c3d36cGlenn Kasten// from Reverb/lib
29b4d307481960b6b348fae4b4e8edefd003c3d36cGlenn Kasten#include "LVREV.h"
30c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
31e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent// effect_handle_t interface implementation for reverb
32c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentextern "C" const struct effect_interface_s gReverbInterface;
33c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
34c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent#define LVM_ERROR_CHECK(LvmStatus, callingFunc, calledFunc){\
35c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        if (LvmStatus == LVREV_NULLADDRESS){\
363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("\tLVREV_ERROR : Parameter error - "\
37c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                    "null pointer returned by %s in %s\n\n\n\n", callingFunc, calledFunc);\
38c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        }\
39c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        if (LvmStatus == LVREV_INVALIDNUMSAMPLES){\
403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("\tLVREV_ERROR : Parameter error - "\
41c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                    "bad number of samples returned by %s in %s\n\n\n\n", callingFunc, calledFunc);\
42c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        }\
43c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        if (LvmStatus == LVREV_OUTOFRANGE){\
443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("\tLVREV_ERROR : Parameter error - "\
45c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                    "out of range returned by %s in %s\n", callingFunc, calledFunc);\
46c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        }\
47c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
48c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
49c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Namespaces
50c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentnamespace android {
51c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentnamespace {
52c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
53c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent/************************************************************************************/
54c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent/*                                                                                  */
55c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent/* Preset definitions                                                               */
56c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent/*                                                                                  */
57c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent/************************************************************************************/
58c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
5997344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurentconst static t_reverb_settings sReverbPresets[] = {
6097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        // REVERB_PRESET_NONE: values are unused
6197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
6297344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        // REVERB_PRESET_SMALLROOM
63e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        {-400, -600, 1100, 830, -400, 5, 500, 10, 1000, 1000},
6497344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        // REVERB_PRESET_MEDIUMROOM
65e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        {-400, -600, 1300, 830, -1000, 20, -200, 20, 1000, 1000},
6697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        // REVERB_PRESET_LARGEROOM
67e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        {-400, -600, 1500, 830, -1600, 5, -1000, 40, 1000, 1000},
6897344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        // REVERB_PRESET_MEDIUMHALL
69e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        {-400, -600, 1800, 700, -1300, 15, -800, 30, 1000, 1000},
7097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        // REVERB_PRESET_LARGEHALL
71e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        {-400, -600, 1800, 700, -2000, 30, -1400, 60, 1000, 1000},
7297344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        // REVERB_PRESET_PLATE
73e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        {-400, -200, 1300, 900, 0, 2, 0, 10, 1000, 750},
7497344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent};
7597344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
7697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
7797344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent// NXP SW auxiliary environmental reverb
7897344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurentconst effect_descriptor_t gAuxEnvReverbDescriptor = {
79c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        { 0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, { 0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e } },
80c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        { 0x4a387fc0, 0x8ab3, 0x11df, 0x8bad, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } },
81e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        EFFECT_CONTROL_API_VERSION,
8297344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        EFFECT_FLAG_TYPE_AUXILIARY,
83d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent        LVREV_CUP_LOAD_ARM9E,
84d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent        LVREV_MEM_USAGE,
8597344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        "Auxiliary Environmental Reverb",
8697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        "NXP Software Ltd.",
8797344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent};
8897344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
8997344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent// NXP SW insert environmental reverb
9097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurentstatic const effect_descriptor_t gInsertEnvReverbDescriptor = {
9197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        {0xc2e5d5f0, 0x94bd, 0x4763, 0x9cac, {0x4e, 0x23, 0x4d, 0x06, 0x83, 0x9e}},
9297344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        {0xc7a511a0, 0xa3bb, 0x11df, 0x860e, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
93e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        EFFECT_CONTROL_API_VERSION,
94e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL,
95d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent        LVREV_CUP_LOAD_ARM9E,
96d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent        LVREV_MEM_USAGE,
9797344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        "Insert Environmental Reverb",
98c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        "NXP Software Ltd.",
99c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent};
100c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
10197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent// NXP SW auxiliary preset reverb
10297344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurentstatic const effect_descriptor_t gAuxPresetReverbDescriptor = {
10397344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
10497344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        {0xf29a1400, 0xa3bb, 0x11df, 0x8ddc, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
105e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        EFFECT_CONTROL_API_VERSION,
10697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        EFFECT_FLAG_TYPE_AUXILIARY,
107d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent        LVREV_CUP_LOAD_ARM9E,
108d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent        LVREV_MEM_USAGE,
10997344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        "Auxiliary Preset Reverb",
11097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        "NXP Software Ltd.",
11197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent};
11297344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
11397344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent// NXP SW insert preset reverb
11497344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurentstatic const effect_descriptor_t gInsertPresetReverbDescriptor = {
11597344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        {0x47382d60, 0xddd8, 0x11db, 0xbf3a, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
11697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        {0x172cdf00, 0xa3bc, 0x11df, 0xa72f, {0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b}},
117e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        EFFECT_CONTROL_API_VERSION,
118e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        EFFECT_FLAG_TYPE_INSERT | EFFECT_FLAG_INSERT_FIRST | EFFECT_FLAG_VOLUME_CTRL,
119d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent        LVREV_CUP_LOAD_ARM9E,
120d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent        LVREV_MEM_USAGE,
12197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        "Insert Preset Reverb",
12297344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        "NXP Software Ltd.",
12397344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent};
12497344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
12597344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent// gDescriptors contains pointers to all defined effect descriptor in this library
12697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurentstatic const effect_descriptor_t * const gDescriptors[] = {
12797344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        &gAuxEnvReverbDescriptor,
12897344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        &gInsertEnvReverbDescriptor,
12997344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        &gAuxPresetReverbDescriptor,
13097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        &gInsertPresetReverbDescriptor
13197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent};
13297344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
133c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentstruct ReverbContext{
134c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    const struct effect_interface_s *itfe;
135c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    effect_config_t                 config;
136c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    LVREV_Handle_t                  hInstance;
137c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    int16_t                         SavedRoomLevel;
138c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    int16_t                         SavedHfLevel;
139c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    int16_t                         SavedDecayTime;
140c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    int16_t                         SavedDecayHfRatio;
141c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    int16_t                         SavedReverbLevel;
142c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    int16_t                         SavedDiffusion;
143c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    int16_t                         SavedDensity;
144c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    bool                            bEnabled;
145c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    #ifdef LVM_PCM
146c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    FILE                            *PcmInPtr;
147c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    FILE                            *PcmOutPtr;
148c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    #endif
149c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    LVM_Fs_en                       SampleRate;
150d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent    LVM_INT32                       *InFrames32;
151d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent    LVM_INT32                       *OutFrames32;
15297344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    bool                            auxiliary;
15397344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    bool                            preset;
15497344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    uint16_t                        curPreset;
15597344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    uint16_t                        nextPreset;
1562d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent    int                             SamplesToExitCount;
157e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent    LVM_INT16                       leftVolume;
158e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent    LVM_INT16                       rightVolume;
159e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent    LVM_INT16                       prevLeftVolume;
160e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent    LVM_INT16                       prevRightVolume;
161e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent    int                             volumeMode;
162e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent};
163e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
164e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurentenum {
165e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent    REVERB_VOLUME_OFF,
166e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent    REVERB_VOLUME_FLAT,
167e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent    REVERB_VOLUME_RAMP,
168c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent};
169c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
170df489b929115ea93a0cf689830fe44400ce3c00fGlenn Kasten#define REVERB_DEFAULT_PRESET REVERB_PRESET_NONE
17197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
172e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
173e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent#define REVERB_SEND_LEVEL   (0x0C00) // 0.75 in 4.12 format
174e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent#define REVERB_UNIT_VOLUME  (0x1000) // 1.0 in 4.12 format
175e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
176c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//--- local function prototypes
177c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentint  Reverb_init            (ReverbContext *pContext);
178c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentvoid Reverb_free            (ReverbContext *pContext);
1793d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurentint  Reverb_setConfig       (ReverbContext *pContext, effect_config_t *pConfig);
1803d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurentvoid Reverb_getConfig       (ReverbContext *pContext, effect_config_t *pConfig);
181c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentint  Reverb_setParameter    (ReverbContext *pContext, void *pParam, void *pValue);
182c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentint  Reverb_getParameter    (ReverbContext *pContext,
183c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                             void          *pParam,
184c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                             size_t        *pValueSize,
185c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                             void          *pValue);
18697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurentint Reverb_LoadPreset       (ReverbContext   *pContext);
187c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
188c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent/* Effect Library Interface Implementation */
189c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentextern "C" int EffectQueryNumberEffects(uint32_t *pNumEffects){
1903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("\n\tEffectQueryNumberEffects start");
19197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    *pNumEffects = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
1923856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("\tEffectQueryNumberEffects creating %d effects", *pNumEffects);
1933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("\tEffectQueryNumberEffects end\n");
194c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    return 0;
195c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent}     /* end EffectQueryNumberEffects */
196c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
197e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentextern "C" int EffectQueryEffect(uint32_t index,
198e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                                 effect_descriptor_t *pDescriptor){
1993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("\n\tEffectQueryEffect start");
2003856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("\tEffectQueryEffect processing index %d", index);
201c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    if (pDescriptor == NULL){
2023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tLVM_ERROR : EffectQueryEffect was passed NULL pointer");
203c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        return -EINVAL;
204c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
20597344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    if (index >= sizeof(gDescriptors) / sizeof(const effect_descriptor_t *)) {
2063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tLVM_ERROR : EffectQueryEffect index out of range %d", index);
207c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        return -ENOENT;
208c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
209a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten    *pDescriptor = *gDescriptors[index];
2103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("\tEffectQueryEffect end\n");
211c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    return 0;
212c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent}     /* end EffectQueryEffect */
213c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
2145e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenextern "C" int EffectCreate(const effect_uuid_t *uuid,
215c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                            int32_t             sessionId,
216c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                            int32_t             ioId,
217e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                            effect_handle_t  *pHandle){
218c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    int ret;
219c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    int i;
22097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
22197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    const effect_descriptor_t *desc;
222c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
2233856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("\t\nEffectCreate start");
224c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
225e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (pHandle == NULL || uuid == NULL){
2263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tLVM_ERROR : EffectCreate() called with NULL pointer");
227c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        return -EINVAL;
228c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
229c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
23097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    for (i = 0; i < length; i++) {
23197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        desc = gDescriptors[i];
23297344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        if (memcmp(uuid, &desc->uuid, sizeof(effect_uuid_t))
23397344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent                == 0) {
2343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("\tEffectCreate - UUID matched Reverb type %d, UUID = %x", i, desc->uuid.timeLow);
23597344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent            break;
23697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        }
23797344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    }
23897344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
23997344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    if (i == length) {
24097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        return -ENOENT;
241c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
242c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
243c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    ReverbContext *pContext = new ReverbContext;
244c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
245c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    pContext->itfe      = &gReverbInterface;
246c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    pContext->hInstance = NULL;
247c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
24897344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    pContext->auxiliary = false;
24997344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    if ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY){
25097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        pContext->auxiliary = true;
2513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tEffectCreate - AUX");
2522d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent    }else{
2533856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tEffectCreate - INS");
25497344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    }
25597344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
25697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    pContext->preset = false;
25797344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    if (memcmp(&desc->type, SL_IID_PRESETREVERB, sizeof(effect_uuid_t)) == 0) {
25897344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        pContext->preset = true;
25997344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        // force reloading preset at first call to process()
26097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        pContext->curPreset = REVERB_PRESET_LAST + 1;
26197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        pContext->nextPreset = REVERB_DEFAULT_PRESET;
2623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tEffectCreate - PRESET");
2632d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent    }else{
2643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tEffectCreate - ENVIRONMENTAL");
26597344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    }
26697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
2673856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("\tEffectCreate - Calling Reverb_init");
268c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    ret = Reverb_init(pContext);
269c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
270c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    if (ret < 0){
2713856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tLVM_ERROR : EffectCreate() init failed");
272c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        delete pContext;
273c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        return ret;
274c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
275c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
276e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    *pHandle = (effect_handle_t)pContext;
277c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
278c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    #ifdef LVM_PCM
279c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    pContext->PcmInPtr = NULL;
280c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    pContext->PcmOutPtr = NULL;
281c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
282c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    pContext->PcmInPtr  = fopen("/data/tmp/reverb_pcm_in.pcm", "w");
283c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    pContext->PcmOutPtr = fopen("/data/tmp/reverb_pcm_out.pcm", "w");
284c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
285c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    if((pContext->PcmInPtr  == NULL)||
286c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       (pContext->PcmOutPtr == NULL)){
287c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       return -EINVAL;
288c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
289c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    #endif
290c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
291d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
292d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent    // Allocate memory for reverb process (*2 is for STEREO)
293d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent    pContext->InFrames32  = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2);
294d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent    pContext->OutFrames32 = (LVM_INT32 *)malloc(LVREV_MAX_FRAME_SIZE * sizeof(LVM_INT32) * 2);
295d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent
2963856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("\tEffectCreate %p, size %d", pContext, sizeof(ReverbContext));
2973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("\tEffectCreate end\n");
298c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    return 0;
299c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent} /* end EffectCreate */
300c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
301e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurentextern "C" int EffectRelease(effect_handle_t handle){
302e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    ReverbContext * pContext = (ReverbContext *)handle;
303c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
3043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("\tEffectRelease %p", handle);
305c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    if (pContext == NULL){
3063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tLVM_ERROR : EffectRelease called with NULL pointer");
307c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        return -EINVAL;
308c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
309c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
310c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    #ifdef LVM_PCM
311c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    fclose(pContext->PcmInPtr);
312c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    fclose(pContext->PcmOutPtr);
313c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    #endif
314d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent    free(pContext->InFrames32);
315d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent    free(pContext->OutFrames32);
316c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    Reverb_free(pContext);
317c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    delete pContext;
318c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    return 0;
319c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent} /* end EffectRelease */
320c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
3215e92a7861196ddae14638d4b7a63fc4892b7ef59Glenn Kastenextern "C" int EffectGetDescriptor(const effect_uuid_t *uuid,
322e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                                   effect_descriptor_t *pDescriptor) {
323e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    int i;
324e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    int length = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *);
325e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
326e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (pDescriptor == NULL || uuid == NULL){
3273856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("EffectGetDescriptor() called with NULL pointer");
328e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        return -EINVAL;
329e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
330e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
331e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    for (i = 0; i < length; i++) {
332e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
333a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten            *pDescriptor = *gDescriptors[i];
3343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("EffectGetDescriptor - UUID matched Reverb type %d, UUID = %x",
335e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent                 i, gDescriptors[i]->uuid.timeLow);
336e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent            return 0;
337e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent        }
338e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    }
339e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
340e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    return -EINVAL;
341e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent} /* end EffectGetDescriptor */
342e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent
343c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent/* local functions */
344c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent#define CHECK_ARG(cond) {                     \
345c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    if (!(cond)) {                            \
3463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tLVM_ERROR : Invalid argument: "#cond);      \
347c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        return -EINVAL;                       \
348c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }                                         \
349c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent}
350c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
351c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
352c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// MonoTo2I_32()
353c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
354c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Purpose:
355c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  Convert MONO to STEREO
356c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//
357c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
358c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
359c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentvoid MonoTo2I_32( const LVM_INT32  *src,
360c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                        LVM_INT32  *dst,
361c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                        LVM_INT16 n)
362c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent{
363c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   LVM_INT16 ii;
364c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   src += (n-1);
365c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   dst += ((n*2)-1);
366c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
367c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   for (ii = n; ii != 0; ii--)
368c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   {
369c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       *dst = *src;
370c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       dst--;
371c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
372c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       *dst = *src;
373c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       dst--;
374c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       src--;
375c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   }
376c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
377c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   return;
378c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent}
379c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
380c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
381c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// From2iToMono_32()
382c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
383c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Purpose:
384c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  Convert STEREO to MONO
385c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//
386c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
387c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
388c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentvoid From2iToMono_32( const LVM_INT32 *src,
389c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                            LVM_INT32 *dst,
390c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                            LVM_INT16 n)
391c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent{
392c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   LVM_INT16 ii;
393c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   LVM_INT32 Temp;
394c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
395c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   for (ii = n; ii != 0; ii--)
396c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   {
397c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       Temp = (*src>>1);
398c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       src++;
399c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
400c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       Temp +=(*src>>1);
401c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       src++;
402c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
403c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       *dst = Temp;
404c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent       dst++;
405c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   }
406c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
407c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent   return;
408c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent}
40997344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
41097344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurentstatic inline int16_t clamp16(int32_t sample)
41197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent{
41297344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    if ((sample>>15) ^ (sample>>31))
41397344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        sample = 0x7FFF ^ (sample>>31);
41497344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    return sample;
41597344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent}
41697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent
417c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
418c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// process()
419c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
420c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Purpose:
421c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Apply the Reverb
422c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//
423c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Inputs:
424c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  pIn:        pointer to stereo/mono 16 bit input data
425c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  pOut:       pointer to stereo 16 bit output data
426c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  frameCount: Frames to process
427c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  pContext:   effect engine context
428c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  strength    strength to be applied
429c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//
430c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  Outputs:
431c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  pOut:       pointer to updated stereo 16 bit output data
432c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//
433c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
434c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
435c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentint process( LVM_INT16     *pIn,
436c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent             LVM_INT16     *pOut,
437c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent             int           frameCount,
438c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent             ReverbContext *pContext){
439c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
4402d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent    LVM_INT16               samplesPerFrame = 1;
441c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    LVREV_ReturnStatus_en   LvmStatus = LVREV_SUCCESS;              /* Function call status */
442c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    LVM_INT16 *OutFrames16;
443c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
444c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
445c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    // Check that the input is either mono or stereo
446e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    if (pContext->config.inputCfg.channels == AUDIO_CHANNEL_OUT_STEREO) {
447c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        samplesPerFrame = 2;
448e1315cf0b63b4c14a77046519e6b01f6f60d74b0Eric Laurent    } else if (pContext->config.inputCfg.channels != AUDIO_CHANNEL_OUT_MONO) {
4493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tLVREV_ERROR : process invalid PCM format");
450c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        return -EINVAL;
451c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
452c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
453d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent    OutFrames16 = (LVM_INT16 *)pContext->OutFrames32;
454c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
455c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    // Check for NULL pointers
456d918324d44aa48b3b064ea9b87d0c520c38f15a9Eric Laurent    if((pContext->InFrames32 == NULL)||(pContext->OutFrames32 == NULL)){
4573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("\tLVREV_ERROR : process failed to allocate memory for temporary buffers ");
458c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        return -EINVAL;
459c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
460c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
461c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    #ifdef LVM_PCM
462c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    fwrite(pIn, frameCount*sizeof(LVM_INT16)*samplesPerFrame, 1, pContext->PcmInPtr);
463c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    fflush(pContext->PcmInPtr);
464c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    #endif
465c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
46697344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    if (pContext->preset && pContext->nextPreset != pContext->curPreset) {
46797344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        Reverb_LoadPreset(pContext);
46897344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    }
469e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
470e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
471e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
472c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    // Convert to Input 32 bits
473e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent    if (pContext->auxiliary) {
474e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        for(int i=0; i<frameCount*samplesPerFrame; i++){
475e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            pContext->InFrames32[i] = (LVM_INT32)pIn[i]<<8;
476e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        }
477e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent    } else {
478e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        // insert reverb input is always stereo
479e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        for (int i = 0; i < frameCount; i++) {
480e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            pContext->InFrames32[2*i] = (pIn[2*i] * REVERB_SEND_LEVEL) >> 4; // <<8 + >>12
481e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            pContext->InFrames32[2*i+1] = (pIn[2*i+1] * REVERB_SEND_LEVEL) >> 4; // <<8 + >>12
482e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        }
483c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
484c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
48597344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    if (pContext->preset && pContext->curPreset == REVERB_PRESET_NONE) {
4862d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent        memset(pContext->OutFrames32, 0, frameCount * sizeof(LVM_INT32) * 2); //always stereo here
48797344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    } else {
4882d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent        if(pContext->bEnabled == LVM_FALSE && pContext->SamplesToExitCount > 0) {
4895185b0138aaeffeecc93b958cb9cd9821f260fafEric Laurent            memset(pContext->InFrames32,0,frameCount * sizeof(LVM_INT32) * samplesPerFrame);
4903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("\tZeroing %d samples per frame at the end of call", samplesPerFrame);
49197344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent        }
4922d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent
4935185b0138aaeffeecc93b958cb9cd9821f260fafEric Laurent        /* Process the samples, producing a stereo output */
4942d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent        LvmStatus = LVREV_Process(pContext->hInstance,      /* Instance handle */
4952d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent                                  pContext->InFrames32,     /* Input buffer */
4962d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent                                  pContext->OutFrames32,    /* Output buffer */
4972d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent                                  frameCount);              /* Number of samples to read */
49897344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent    }
499c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
500c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    LVM_ERROR_CHECK(LvmStatus, "LVREV_Process", "process")
501c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    if(LvmStatus != LVREV_SUCCESS) return -EINVAL;
502c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
503c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    // Convert to 16 bits
5042d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent    if (pContext->auxiliary) {
5052d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent        for (int i=0; i < frameCount*2; i++) { //always stereo here
5062d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent            OutFrames16[i] = clamp16(pContext->OutFrames32[i]>>8);
5072d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent        }
5082d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent    } else {
5092d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent        for (int i=0; i < frameCount*2; i++) { //always stereo here
5102d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent            OutFrames16[i] = clamp16((pContext->OutFrames32[i]>>8) + (LVM_INT32)pIn[i]);
5112d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent        }
512e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
513e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        // apply volume with ramp if needed
514e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        if ((pContext->leftVolume != pContext->prevLeftVolume ||
515e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                pContext->rightVolume != pContext->prevRightVolume) &&
516e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                pContext->volumeMode == REVERB_VOLUME_RAMP) {
517e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            LVM_INT32 vl = (LVM_INT32)pContext->prevLeftVolume << 16;
518e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            LVM_INT32 incl = (((LVM_INT32)pContext->leftVolume << 16) - vl) / frameCount;
519e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            LVM_INT32 vr = (LVM_INT32)pContext->prevRightVolume << 16;
520e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            LVM_INT32 incr = (((LVM_INT32)pContext->rightVolume << 16) - vr) / frameCount;
521e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
522e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            for (int i = 0; i < frameCount; i++) {
523e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                OutFrames16[2*i] =
524e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                        clamp16((LVM_INT32)((vl >> 16) * OutFrames16[2*i]) >> 12);
525e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                OutFrames16[2*i+1] =
526e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                        clamp16((LVM_INT32)((vr >> 16) * OutFrames16[2*i+1]) >> 12);
527e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
528e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                vl += incl;
529e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                vr += incr;
530e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            }
531e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent
532e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            pContext->prevLeftVolume = pContext->leftVolume;
533e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            pContext->prevRightVolume = pContext->rightVolume;
534e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        } else if (pContext->volumeMode != REVERB_VOLUME_OFF) {
535e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            if (pContext->leftVolume != REVERB_UNIT_VOLUME ||
536e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                pContext->rightVolume != REVERB_UNIT_VOLUME) {
537e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                for (int i = 0; i < frameCount; i++) {
538e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                    OutFrames16[2*i] =
539e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                            clamp16((LVM_INT32)(pContext->leftVolume * OutFrames16[2*i]) >> 12);
540e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                    OutFrames16[2*i+1] =
541e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                            clamp16((LVM_INT32)(pContext->rightVolume * OutFrames16[2*i+1]) >> 12);
542e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent                }
543e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            }
544e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            pContext->prevLeftVolume = pContext->leftVolume;
545e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            pContext->prevRightVolume = pContext->rightVolume;
546e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent            pContext->volumeMode = REVERB_VOLUME_RAMP;
547e0aed6ddcb4e3c301b80aa26706b6052dab42c41Eric Laurent        }
548c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
549c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
550c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    #ifdef LVM_PCM
5512d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent    fwrite(OutFrames16, frameCount*sizeof(LVM_INT16)*2, 1, pContext->PcmOutPtr);
552c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    fflush(pContext->PcmOutPtr);
553c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    #endif
554c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
555c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    // Accumulate if required
556c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    if (pContext->config.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE){
5573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        //ALOGV("\tBuffer access is ACCUMULATE");
5582d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent        for (int i=0; i<frameCount*2; i++){ //always stereo here
55997344f1d8e8e95fd07d5deee2ae2492a7e4c24b0Eric Laurent            pOut[i] = clamp16((int32_t)pOut[i] + (int32_t)OutFrames16[i]);
560c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        }
561c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }else{
5623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        //ALOGV("\tBuffer access is WRITE");
5632d3bf535004f7310fe04a4b5f46b6747cdb3c93fEric Laurent        memcpy(pOut, OutFrames16, frameCount*sizeof(LVM_INT16)*2);
564c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
565c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
566c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    return 0;
567c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent}    /* end process */
568c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
569c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
570c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Reverb_free()
571c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
572c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Purpose: Free all memory associated with the Bundle.
573c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//
574c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Inputs:
575c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  pContext:   effect engine context
576c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//
577c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Outputs:
578c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//
579c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
580c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
581c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurentvoid Reverb_free(ReverbContext *pContext){
582c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
583c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    LVREV_ReturnStatus_en     LvmStatus=LVREV_SUCCESS;         /* Function call status */
584c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    LVREV_ControlParams_st    params;                        /* Control Parameters */
585c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    LVREV_MemoryTable_st      MemTab;
586c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
587c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    /* Free the algorithm memory */
588c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    LvmStatus = LVREV_GetMemoryTable(pContext->hInstance,
589c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                                   &MemTab,
590c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                                   LVM_NULL);
591c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
592c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    LVM_ERROR_CHECK(LvmStatus, "LVM_GetMemoryTable", "Reverb_free")
593c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
594c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    for (int i=0; i<LVM_NR_MEMORY_REGIONS; i++){
595c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        if (MemTab.Region[i].Size != 0){
596c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent            if (MemTab.Region[i].pBaseAddress != NULL){
5973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("\tfree() - START freeing %ld bytes for region %u at %p\n",
598c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
599c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
600c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                free(MemTab.Region[i].pBaseAddress);
601c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
6023856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("\tfree() - END   freeing %ld bytes for region %u at %p\n",
603c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
604c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent            }else{
6053856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("\tLVM_ERROR : free() - trying to free with NULL pointer %ld bytes "
606c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                        "for region %u at %p ERROR\n",
607c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent                        MemTab.Region[i].Size, i, MemTab.Region[i].pBaseAddress);
608c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent            }
609c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent        }
610c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent    }
611c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent}    /* end Reverb_free */
612c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent
613c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
6143d5188bd6abe55898f10a0edf3c05aff8aa2ef67Eric Laurent// Reverb_setConfig()
615c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//----------------------------------------------------------------------------
616c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Purpose: Set input and output audio configuration.
617c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//
618c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent// Inputs:
619c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  pContext:   effect engine context
620c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//  pConfig:    pointer to effect_config_t structure holding input and output
621c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//      configuration parameters
622c59c6fd7f859b4010d788db89b8d4d76bbb70e57Eric Laurent//
623