1 /*
2 * Copyright (C) 2004-2010 NXP Software
3 * Copyright (C) 2010 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /****************************************************************************************/
19 /* */
20 /* Includes */
21 /* */
22 /****************************************************************************************/
23 #include "LVREV_Private.h"
24
25 /****************************************************************************************/
26 /* */
27 /* FUNCTION: LVREV_GetInstanceHandle */
28 /* */
29 /* DESCRIPTION: */
30 /* This function is used to create a LVREV module instance. It returns the created */
31 /* instance handle through phInstance. All parameters are set to their default, */
32 /* inactive state. */
33 /* */
34 /* PARAMETERS: */
35 /* phInstance pointer to the instance handle */
36 /* pInstanceParams Pointer to the instance parameters */
37 /* */
38 /* RETURNS: */
39 /* LVREV_SUCCESS Succeeded */
40 /* LVREV_NULLADDRESS When phInstance or pMemoryTable or pInstanceParams is NULL */
41 /* LVREV_NULLADDRESS When one of the memory regions has a NULL pointer */
42 /* */
43 /* NOTES: */
44 /* */
45 /****************************************************************************************/
LVREV_GetInstanceHandle(LVREV_Handle_t * phInstance,LVREV_InstanceParams_st * pInstanceParams)46 LVREV_ReturnStatus_en LVREV_GetInstanceHandle(LVREV_Handle_t* phInstance,
47 LVREV_InstanceParams_st* pInstanceParams) {
48 LVREV_Instance_st* pLVREV_Private;
49 LVM_INT16 i;
50 LVM_UINT16 MaxBlockSize;
51
52 /*
53 * Check for error conditions
54 */
55 /* Check for NULL pointers */
56 if ((phInstance == LVM_NULL) || (pInstanceParams == LVM_NULL)) {
57 return LVREV_NULLADDRESS;
58 }
59 /*
60 * Check all instance parameters are in range
61 */
62 /* Check for a non-zero block size */
63 if (pInstanceParams->MaxBlockSize == 0) {
64 return LVREV_OUTOFRANGE;
65 }
66
67 /* Check for a valid number of delay lines */
68 if ((pInstanceParams->NumDelays != LVREV_DELAYLINES_1) &&
69 (pInstanceParams->NumDelays != LVREV_DELAYLINES_2) &&
70 (pInstanceParams->NumDelays != LVREV_DELAYLINES_4)) {
71 return LVREV_OUTOFRANGE;
72 }
73
74 /*
75 * Set the instance handle if not already initialised
76 */
77 if (*phInstance == LVM_NULL) {
78 *phInstance = new LVREV_Instance_st{};
79 }
80 pLVREV_Private = (LVREV_Instance_st*)*phInstance;
81
82 if (pInstanceParams->NumDelays == LVREV_DELAYLINES_4) {
83 MaxBlockSize = LVREV_MAX_AP_DELAY[3];
84 } else if (pInstanceParams->NumDelays == LVREV_DELAYLINES_2) {
85 MaxBlockSize = LVREV_MAX_AP_DELAY[1];
86 } else {
87 MaxBlockSize = LVREV_MAX_AP_DELAY[0];
88 }
89
90 if (MaxBlockSize > pInstanceParams->MaxBlockSize) {
91 MaxBlockSize = pInstanceParams->MaxBlockSize;
92 }
93
94 /*
95 * Set the data, coefficient and temporary memory pointers
96 */
97 for (size_t i = 0; i < pInstanceParams->NumDelays; i++) {
98 pLVREV_Private->pDelay_T[i] = (LVM_FLOAT*)calloc(LVREV_MAX_T_DELAY[i], sizeof(LVM_FLOAT));
99 /* Scratch for each delay line output */
100 pLVREV_Private->pScratchDelayLine[i] = (LVM_FLOAT*)calloc(MaxBlockSize, sizeof(LVM_FLOAT));
101 }
102 /* All-pass delay buffer addresses and sizes */
103 for (size_t i = 0; i < LVREV_DELAYLINES_4; i++) {
104 pLVREV_Private->T[i] = LVREV_MAX_T_DELAY[i];
105 }
106 pLVREV_Private->AB_Selection = 1; /* Select smoothing A to B */
107
108 /* General purpose scratch */
109 pLVREV_Private->pScratch = (LVM_FLOAT*)calloc(MaxBlockSize, sizeof(LVM_FLOAT));
110 /* Mono->stereo input save for end mix */
111 pLVREV_Private->pInputSave = (LVM_FLOAT*)calloc(FCC_2 * MaxBlockSize, sizeof(LVM_FLOAT));
112
113 /*
114 * Save the instance parameters in the instance structure
115 */
116 pLVREV_Private->InstanceParams = *pInstanceParams;
117
118 /*
119 * Set the parameters to invalid
120 */
121 pLVREV_Private->CurrentParams.SampleRate = LVM_FS_INVALID;
122 pLVREV_Private->CurrentParams.OperatingMode = LVM_MODE_DUMMY;
123 pLVREV_Private->CurrentParams.SourceFormat = LVM_SOURCE_DUMMY;
124
125 pLVREV_Private->bControlPending = LVM_FALSE;
126 pLVREV_Private->bFirstControl = LVM_TRUE;
127 pLVREV_Private->bDisableReverb = LVM_FALSE;
128
129 /*
130 * Set mixer parameters
131 */
132 pLVREV_Private->BypassMixer.CallbackParam2 = 0;
133 pLVREV_Private->BypassMixer.pCallbackHandle2 = pLVREV_Private;
134 pLVREV_Private->BypassMixer.pGeneralPurpose2 = LVM_NULL;
135 pLVREV_Private->BypassMixer.pCallBack2 = BypassMixer_Callback;
136 pLVREV_Private->BypassMixer.CallbackSet2 = LVM_FALSE;
137 pLVREV_Private->BypassMixer.Current2 = 0;
138 pLVREV_Private->BypassMixer.Target2 = 0;
139 pLVREV_Private->BypassMixer.CallbackParam1 = 0;
140 pLVREV_Private->BypassMixer.pCallbackHandle1 = LVM_NULL;
141 pLVREV_Private->BypassMixer.pGeneralPurpose1 = LVM_NULL;
142 pLVREV_Private->BypassMixer.pCallBack1 = LVM_NULL;
143 pLVREV_Private->BypassMixer.CallbackSet1 = LVM_FALSE;
144 pLVREV_Private->BypassMixer.Current1 = 0x00000000;
145 pLVREV_Private->BypassMixer.Target1 = 0x00000000;
146
147 pLVREV_Private->RoomSizeInms = 100; // 100 msec
148
149 /*
150 * Set the output gain mixer parameters
151 */
152 pLVREV_Private->GainMixer.CallbackParam = 0;
153 pLVREV_Private->GainMixer.pCallbackHandle = LVM_NULL;
154 pLVREV_Private->GainMixer.pGeneralPurpose = LVM_NULL;
155 pLVREV_Private->GainMixer.pCallBack = LVM_NULL;
156 pLVREV_Private->GainMixer.CallbackSet = LVM_FALSE;
157 pLVREV_Private->GainMixer.Current = 0.03125f; // 0x03ffffff;
158 pLVREV_Private->GainMixer.Target = 0.03125f; // 0x03ffffff;
159
160 /*
161 * Set the All-Pass Filter mixers
162 */
163 for (i = 0; i < 4; i++) {
164 pLVREV_Private->pOffsetA[i] = pLVREV_Private->pDelay_T[i];
165 pLVREV_Private->pOffsetB[i] = pLVREV_Private->pDelay_T[i];
166 /* Delay tap selection mixer */
167 pLVREV_Private->Mixer_APTaps[i].CallbackParam2 = 0;
168 pLVREV_Private->Mixer_APTaps[i].pCallbackHandle2 = LVM_NULL;
169 pLVREV_Private->Mixer_APTaps[i].pGeneralPurpose2 = LVM_NULL;
170 pLVREV_Private->Mixer_APTaps[i].pCallBack2 = LVM_NULL;
171 pLVREV_Private->Mixer_APTaps[i].CallbackSet2 = LVM_FALSE;
172 pLVREV_Private->Mixer_APTaps[i].Current2 = 0;
173 pLVREV_Private->Mixer_APTaps[i].Target2 = 0;
174 pLVREV_Private->Mixer_APTaps[i].CallbackParam1 = 0;
175 pLVREV_Private->Mixer_APTaps[i].pCallbackHandle1 = LVM_NULL;
176 pLVREV_Private->Mixer_APTaps[i].pGeneralPurpose1 = LVM_NULL;
177 pLVREV_Private->Mixer_APTaps[i].pCallBack1 = LVM_NULL;
178 pLVREV_Private->Mixer_APTaps[i].CallbackSet1 = LVM_FALSE;
179 pLVREV_Private->Mixer_APTaps[i].Current1 = 0;
180 pLVREV_Private->Mixer_APTaps[i].Target1 = 1;
181 /* Feedforward mixer */
182 pLVREV_Private->Mixer_SGFeedforward[i].CallbackParam = 0;
183 pLVREV_Private->Mixer_SGFeedforward[i].pCallbackHandle = LVM_NULL;
184 pLVREV_Private->Mixer_SGFeedforward[i].pGeneralPurpose = LVM_NULL;
185 pLVREV_Private->Mixer_SGFeedforward[i].pCallBack = LVM_NULL;
186 pLVREV_Private->Mixer_SGFeedforward[i].CallbackSet = LVM_FALSE;
187 pLVREV_Private->Mixer_SGFeedforward[i].Current = 0;
188 pLVREV_Private->Mixer_SGFeedforward[i].Target = 0;
189 /* Feedback mixer */
190 pLVREV_Private->Mixer_SGFeedback[i].CallbackParam = 0;
191 pLVREV_Private->Mixer_SGFeedback[i].pCallbackHandle = LVM_NULL;
192 pLVREV_Private->Mixer_SGFeedback[i].pGeneralPurpose = LVM_NULL;
193 pLVREV_Private->Mixer_SGFeedback[i].pCallBack = LVM_NULL;
194 pLVREV_Private->Mixer_SGFeedback[i].CallbackSet = LVM_FALSE;
195 pLVREV_Private->Mixer_SGFeedback[i].Current = 0;
196 pLVREV_Private->Mixer_SGFeedback[i].Target = 0;
197 /* Feedback gain mixer */
198 pLVREV_Private->FeedbackMixer[i].CallbackParam = 0;
199 pLVREV_Private->FeedbackMixer[i].pCallbackHandle = LVM_NULL;
200 pLVREV_Private->FeedbackMixer[i].pGeneralPurpose = LVM_NULL;
201 pLVREV_Private->FeedbackMixer[i].pCallBack = LVM_NULL;
202 pLVREV_Private->FeedbackMixer[i].CallbackSet = LVM_FALSE;
203 pLVREV_Private->FeedbackMixer[i].Current = 0;
204 pLVREV_Private->FeedbackMixer[i].Target = 0;
205 }
206 /* Delay tap index */
207 for (size_t i = 0; i < LVREV_DELAYLINES_4; i++) {
208 pLVREV_Private->A_DelaySize[i] = LVREV_MAX_AP_DELAY[i];
209 pLVREV_Private->B_DelaySize[i] = LVREV_MAX_AP_DELAY[i];
210 }
211
212 pLVREV_Private->pRevHPFBiquad.reset(
213 new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
214 pLVREV_Private->pRevLPFBiquad.reset(
215 new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
216 for (int i = 0; i < LVREV_DELAYLINES_4; i++) {
217 pLVREV_Private->revLPFBiquad[i].reset(
218 new android::audio_utils::BiquadFilter<LVM_FLOAT>(LVM_MAX_CHANNELS));
219 }
220
221 LVREV_ClearAudioBuffers(*phInstance);
222
223 return LVREV_SUCCESS;
224 }
225
226 /****************************************************************************************/
227 /* */
228 /* FUNCTION: LVREV_FreeInstance */
229 /* */
230 /* DESCRIPTION: */
231 /* This function is used to free the internal allocations of the module. */
232 /* */
233 /* PARAMETERS: */
234 /* hInstance Instance handle */
235 /* */
236 /* RETURNS: */
237 /* LVREV_SUCCESS free instance succeeded */
238 /* LVREV_NULLADDRESS Instance is NULL */
239 /* */
240 /****************************************************************************************/
LVREV_FreeInstance(LVREV_Handle_t hInstance)241 LVREV_ReturnStatus_en LVREV_FreeInstance(LVREV_Handle_t hInstance) {
242 if (hInstance == LVM_NULL) {
243 return LVREV_NULLADDRESS;
244 }
245
246 LVREV_Instance_st* pLVREV_Private = (LVREV_Instance_st*)hInstance;
247
248 for (size_t i = 0; i < pLVREV_Private->InstanceParams.NumDelays; i++) {
249 if (pLVREV_Private->pDelay_T[i]) {
250 free(pLVREV_Private->pDelay_T[i]);
251 pLVREV_Private->pDelay_T[i] = LVM_NULL;
252 }
253 if (pLVREV_Private->pScratchDelayLine[i]) {
254 free(pLVREV_Private->pScratchDelayLine[i]);
255 pLVREV_Private->pScratchDelayLine[i] = LVM_NULL;
256 }
257 }
258 if (pLVREV_Private->pScratch) {
259 free(pLVREV_Private->pScratch);
260 pLVREV_Private->pScratch = LVM_NULL;
261 }
262 if (pLVREV_Private->pInputSave) {
263 free(pLVREV_Private->pInputSave);
264 pLVREV_Private->pInputSave = LVM_NULL;
265 }
266
267 delete pLVREV_Private;
268 return LVREV_SUCCESS;
269 }
270 /* End of file */
271