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 #include "Filter.h"
25
26 /****************************************************************************************/
27 /* */
28 /* FUNCTION: LVREV_ApplyNewSettings */
29 /* */
30 /* DESCRIPTION: */
31 /* Applies the new control parameters */
32 /* */
33 /* PARAMETERS: */
34 /* pPrivate Pointer to the instance private parameters */
35 /* */
36 /* RETURNS: */
37 /* LVREV_Success Succeeded */
38 /* LVREV_NULLADDRESS When pPrivate is NULL */
39 /* */
40 /* NOTES: */
41 /* */
42 /****************************************************************************************/
43
44 #ifndef BUILD_FLOAT
LVREV_ApplyNewSettings(LVREV_Instance_st * pPrivate)45 LVREV_ReturnStatus_en LVREV_ApplyNewSettings (LVREV_Instance_st *pPrivate)
46 {
47
48 LVM_Mode_en OperatingMode;
49 LVM_INT32 NumberOfDelayLines;
50
51
52 /* Check for NULL pointer */
53 if(pPrivate == LVM_NULL)
54 {
55 return LVREV_NULLADDRESS;
56 }
57
58 OperatingMode = pPrivate->NewParams.OperatingMode;
59
60 if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
61 {
62 NumberOfDelayLines = 4;
63 }
64 else if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_2)
65 {
66 NumberOfDelayLines = 2;
67 }
68 else
69 {
70 NumberOfDelayLines = 1;
71 }
72
73 /*
74 * Update the high pass filter coefficients
75 */
76 if((pPrivate->NewParams.HPF != pPrivate->CurrentParams.HPF) ||
77 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
78 (pPrivate->bFirstControl == LVM_TRUE))
79 {
80 LVM_INT32 Omega;
81 FO_C32_Coefs_t Coeffs;
82
83 Omega = LVM_GetOmega(pPrivate->NewParams.HPF, pPrivate->NewParams.SampleRate);
84 LVM_FO_HPF(Omega, &Coeffs);
85 FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->HPCoefs, &pPrivate->pFastData->HPTaps, &Coeffs);
86 LoadConst_32(0,
87 (void *)&pPrivate->pFastData->HPTaps, /* Destination Cast to void: no dereferencing in function*/
88 sizeof(Biquad_1I_Order1_Taps_t)/sizeof(LVM_INT32));
89 }
90
91
92 /*
93 * Update the low pass filter coefficients
94 */
95 if((pPrivate->NewParams.LPF != pPrivate->CurrentParams.LPF) ||
96 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
97 (pPrivate->bFirstControl == LVM_TRUE))
98 {
99 LVM_INT32 Omega;
100 FO_C32_Coefs_t Coeffs;
101
102
103 Coeffs.A0 = 0x7FFFFFFF;
104 Coeffs.A1 = 0;
105 Coeffs.B1 = 0;
106 if(pPrivate->NewParams.LPF <= (LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1))
107 {
108 Omega = LVM_GetOmega(pPrivate->NewParams.LPF, pPrivate->NewParams.SampleRate);
109
110 /*
111 * Do not apply filter if w =2*pi*fc/fs >= 2.9
112 */
113 if(Omega<=LVREV_2_9_INQ29)
114 {
115 LVM_FO_LPF(Omega, &Coeffs);
116 }
117 }
118 FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->LPCoefs, &pPrivate->pFastData->LPTaps, &Coeffs);
119 LoadConst_32(0,
120 (void *)&pPrivate->pFastData->LPTaps, /* Destination Cast to void: no dereferencing in function*/
121 sizeof(Biquad_1I_Order1_Taps_t)/sizeof(LVM_INT32));
122 }
123
124
125 /*
126 * Calculate the room size parameter
127 */
128 if( pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize)
129 {
130 /* Room size range is 10ms to 200ms
131 * 0% -- 10ms
132 * 50% -- 65ms
133 * 100% -- 120ms
134 */
135 pPrivate->RoomSizeInms = 10 + (((pPrivate->NewParams.RoomSize*11) + 5)/10);
136 }
137
138
139 /*
140 * Update the T delay number of samples and the all pass delay number of samples
141 */
142 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
143 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
144 (pPrivate->bFirstControl == LVM_TRUE))
145 {
146
147 LVM_UINT32 Temp;
148 LVM_INT32 APDelaySize;
149 LVM_INT32 Fs = LVM_GetFsFromTable(pPrivate->NewParams.SampleRate);
150 LVM_UINT32 DelayLengthSamples = (LVM_UINT32)(Fs * pPrivate->RoomSizeInms);
151 LVM_INT16 i;
152 LVM_INT16 ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4, LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4};
153 LVM_INT16 MaxT_Delay[] = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, LVREV_MAX_T2_DELAY, LVREV_MAX_T3_DELAY};
154 LVM_INT16 MaxAP_Delay[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY, LVREV_MAX_AP2_DELAY, LVREV_MAX_AP3_DELAY};
155
156
157 /*
158 * For each delay line
159 */
160 for (i=0; i<NumberOfDelayLines; i++)
161 {
162 if (i != 0)
163 {
164 LVM_INT32 Temp1; /* to avoid QAC warning on type conversion */
165 LVM_INT32 Temp2; /* to avoid QAC warning on type conversion */
166
167 Temp2=(LVM_INT32)DelayLengthSamples;
168 MUL32x16INTO32(Temp2, ScaleTable[i], Temp1, 15)
169 Temp=(LVM_UINT32)Temp1;
170 }
171 else
172 {
173 Temp = DelayLengthSamples;
174 }
175 APDelaySize = Temp / 1500;
176
177
178 /*
179 * Set the fixed delay
180 */
181 Temp = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 48000;
182 pPrivate->Delay_AP[i] = pPrivate->T[i] - Temp;
183
184
185 /*
186 * Set the tap selection
187 */
188 if (pPrivate->AB_Selection)
189 {
190 /* Smooth from tap A to tap B */
191 pPrivate->pOffsetB[i] = &pPrivate->pDelay_T[i][pPrivate->T[i] - Temp - APDelaySize];
192 pPrivate->B_DelaySize[i] = APDelaySize;
193 pPrivate->Mixer_APTaps[i].Target1 = 0;
194 pPrivate->Mixer_APTaps[i].Target2 = 0x7fffffff;
195 }
196 else
197 {
198 /* Smooth from tap B to tap A */
199 pPrivate->pOffsetA[i] = &pPrivate->pDelay_T[i][pPrivate->T[i] - Temp - APDelaySize];
200 pPrivate->A_DelaySize[i] = APDelaySize;
201 pPrivate->Mixer_APTaps[i].Target2 = 0;
202 pPrivate->Mixer_APTaps[i].Target1 = 0x7fffffff;
203 }
204
205 /*
206 * Set the maximum block size to the smallest delay size
207 */
208 pPrivate->MaxBlkLen = Temp;
209 if (pPrivate->MaxBlkLen > pPrivate->A_DelaySize[i])
210 {
211 pPrivate->MaxBlkLen = pPrivate->A_DelaySize[i];
212 }
213 if (pPrivate->MaxBlkLen > pPrivate->B_DelaySize[i])
214 {
215 pPrivate->MaxBlkLen = pPrivate->B_DelaySize[i];
216 }
217 }
218 if (pPrivate->AB_Selection)
219 {
220 pPrivate->AB_Selection = 0;
221 }
222 else
223 {
224 pPrivate->AB_Selection = 1;
225 }
226
227
228 /*
229 * Limit the maximum block length
230 */
231 pPrivate->MaxBlkLen=pPrivate->MaxBlkLen-2; /* Just as a precausion, but no problem if we remove this line */
232 if(pPrivate->MaxBlkLen > pPrivate->InstanceParams.MaxBlockSize)
233 {
234 pPrivate->MaxBlkLen = (LVM_INT32)pPrivate->InstanceParams.MaxBlockSize;
235 }
236 }
237
238
239 /*
240 * Update the low pass filter coefficient
241 */
242 if( (pPrivate->NewParams.Damping != pPrivate->CurrentParams.Damping) ||
243 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
244 (pPrivate->bFirstControl == LVM_TRUE))
245 {
246
247 LVM_INT32 Temp;
248 LVM_INT32 Omega;
249 FO_C32_Coefs_t Coeffs;
250 LVM_INT16 i;
251 LVM_INT16 Damping = (LVM_INT16)((pPrivate->NewParams.Damping * 100) + 1000);
252 LVM_INT32 ScaleTable[] = {LVREV_T_3_Power_0_on_4, LVREV_T_3_Power_1_on_4, LVREV_T_3_Power_2_on_4, LVREV_T_3_Power_3_on_4};
253
254
255 /*
256 * For each filter
257 */
258 for (i=0; i<NumberOfDelayLines; i++)
259 {
260 if (i != 0)
261 {
262 MUL32x16INTO32(ScaleTable[i], Damping, Temp, 15)
263 }
264 else
265 {
266 Temp = Damping;
267 }
268 if(Temp <= (LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1))
269 {
270 Omega = LVM_GetOmega((LVM_UINT16)Temp, pPrivate->NewParams.SampleRate);
271 LVM_FO_LPF(Omega, &Coeffs);
272 }
273 else
274 {
275 Coeffs.A0 = 0x7FF00000;
276 Coeffs.A1 = 0;
277 Coeffs.B1 = 0;
278 }
279 FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->RevLPCoefs[i], &pPrivate->pFastData->RevLPTaps[i], &Coeffs);
280 }
281 }
282
283
284 /*
285 * Update All-pass filter mixer time constants
286 */
287 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
288 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
289 (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density))
290 {
291 LVM_INT16 i;
292 LVM_INT32 Alpha = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_ALLPASS_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), 1);
293 LVM_INT32 AlphaTap = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_ALLPASS_TAP_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), 1);
294
295 for (i=0; i<4; i++)
296 {
297 pPrivate->Mixer_APTaps[i].Alpha1 = AlphaTap;
298 pPrivate->Mixer_APTaps[i].Alpha2 = AlphaTap;
299 pPrivate->Mixer_SGFeedback[i].Alpha = Alpha;
300 pPrivate->Mixer_SGFeedforward[i].Alpha = Alpha;
301 }
302 }
303
304
305 /*
306 * Update the feed back gain
307 */
308 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
309 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
310 (pPrivate->NewParams.T60 != pPrivate->CurrentParams.T60) ||
311 (pPrivate->bFirstControl == LVM_TRUE))
312 {
313
314 LVM_INT32 G[4]; /* Feedback gain (Q7.24) */
315
316 if(pPrivate->NewParams.T60 == 0)
317 {
318 G[3] = 0;
319 G[2] = 0;
320 G[1] = 0;
321 G[0] = 0;
322 }
323 else
324 {
325 LVM_INT32 Temp1;
326 LVM_INT32 Temp2;
327 LVM_INT16 i;
328 LVM_INT16 ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4, LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4};
329
330
331 /*
332 * For each delay line
333 */
334 for (i=0; i<NumberOfDelayLines; i++)
335 {
336 Temp1 = (3 * pPrivate->RoomSizeInms * ScaleTable[i]) / pPrivate->NewParams.T60;
337 if(Temp1 >= (4 << 15))
338 {
339 G[i] = 0;
340 }
341 else if((Temp1 >= (2 << 15)))
342 {
343 Temp2 = LVM_Power10(-(Temp1 << 14));
344 Temp1 = LVM_Power10(-(Temp1 << 14));
345 MUL32x32INTO32(Temp1,Temp2,Temp1,24)
346 }
347 else
348 {
349 Temp1 = LVM_Power10(-(Temp1 << 15));
350 }
351 if (NumberOfDelayLines == 1)
352 {
353 G[i] = Temp1;
354 }
355 else
356 {
357 LVM_INT32 TempG;
358 MUL32x16INTO32(Temp1,ONE_OVER_SQRT_TWO,TempG,15)
359 G[i]=TempG;
360 }
361 }
362 }
363
364 /* Set up the feedback mixers for four delay lines */
365 pPrivate->FeedbackMixer[0].Target=G[0]<<7;
366 pPrivate->FeedbackMixer[1].Target=G[1]<<7;
367 pPrivate->FeedbackMixer[2].Target=G[2]<<7;
368 pPrivate->FeedbackMixer[3].Target=G[3]<<7;
369 }
370
371
372 /*
373 * Calculate the gain correction
374 */
375 if((pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
376 (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) ||
377 (pPrivate->NewParams.T60 != pPrivate->CurrentParams.T60) )
378 {
379 LVM_INT32 Index=0;
380 LVM_INT32 i=0;
381 LVM_INT32 Gain=0;
382 LVM_INT32 RoomSize=0;
383 LVM_INT32 T60;
384 LVM_INT32 Coefs[5];
385
386 if(pPrivate->NewParams.RoomSize==0)
387 {
388 RoomSize=1;
389 }
390 else
391 {
392 RoomSize=(LVM_INT32)pPrivate->NewParams.RoomSize;
393 }
394
395 if(pPrivate->NewParams.T60<100)
396 {
397 T60 = 100 * LVREV_T60_SCALE;
398 }
399 else
400 {
401 T60 = pPrivate->NewParams.T60 * LVREV_T60_SCALE;
402 }
403
404 /* Find the nearest room size in table */
405 for(i=0;i<24;i++)
406 {
407 if(RoomSize<= LVREV_GainPolyTable[i][0])
408 {
409 Index=i;
410 break;
411 }
412 }
413
414
415 if(RoomSize==LVREV_GainPolyTable[Index][0])
416 {
417 /* Take table values if the room size is in table */
418 for(i=1;i<5;i++)
419 {
420 Coefs[i-1]=LVREV_GainPolyTable[Index][i];
421 }
422 Coefs[4]=0;
423 Gain=LVM_Polynomial(3,Coefs,T60); /* Q.24 result */
424 }
425 else
426 {
427 /* Interpolate the gain between nearest room sizes */
428
429 LVM_INT32 Gain1,Gain2;
430 LVM_INT32 Tot_Dist,Dist;
431
432 Tot_Dist=LVREV_GainPolyTable[Index][0]-LVREV_GainPolyTable[Index-1][0];
433 Dist=RoomSize-LVREV_GainPolyTable[Index-1][0];
434
435
436 /* Get gain for first */
437 for(i=1;i<5;i++)
438 {
439 Coefs[i-1]=LVREV_GainPolyTable[Index-1][i];
440 }
441 Coefs[4]=0;
442
443 Gain1=LVM_Polynomial(3,Coefs,T60); /* Q.24 result */
444
445 /* Get gain for second */
446 for(i=1;i<5;i++)
447 {
448 Coefs[i-1]=LVREV_GainPolyTable[Index][i];
449 }
450 Coefs[4]=0;
451
452 Gain2=LVM_Polynomial(3,Coefs,T60); /* Q.24 result */
453
454 /* Linear Interpolate the gain */
455 Gain = Gain1+ (((Gain2-Gain1)*Dist)/(Tot_Dist));
456 }
457
458
459 /*
460 * Get the inverse of gain: Q.15
461 * Gain is mostly above one except few cases, take only gains above 1
462 */
463 if(Gain < 16777216L)
464 {
465 pPrivate->Gain= 32767;
466 }
467 else
468 {
469 pPrivate->Gain=(LVM_INT16)(LVM_MAXINT_32/(Gain>>8));
470 }
471
472
473 Index=((32767*100)/(100+pPrivate->NewParams.Level));
474 pPrivate->Gain=(LVM_INT16)((pPrivate->Gain*Index)>>15);
475 pPrivate->GainMixer.Target = pPrivate->Gain*Index;
476 }
477
478
479 /*
480 * Update the all pass comb filter coefficient
481 */
482 if( (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density) ||
483 (pPrivate->bFirstControl == LVM_TRUE))
484 {
485 LVM_INT16 i;
486 LVM_INT32 b = pPrivate->NewParams.Density * LVREV_B_8_on_1000;
487
488 for (i=0;i<4; i++)
489 {
490 pPrivate->Mixer_SGFeedback[i].Target = b;
491 pPrivate->Mixer_SGFeedforward[i].Target = b;
492 }
493 }
494
495
496 /*
497 * Update the bypass mixer time constant
498 */
499 if((pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
500 (pPrivate->bFirstControl == LVM_TRUE))
501 {
502 LVM_UINT16 NumChannels = 1; /* Assume MONO format */
503 LVM_INT32 Alpha;
504
505 Alpha = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_FEEDBACKMIXER_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), NumChannels);
506 pPrivate->FeedbackMixer[0].Alpha=Alpha;
507 pPrivate->FeedbackMixer[1].Alpha=Alpha;
508 pPrivate->FeedbackMixer[2].Alpha=Alpha;
509 pPrivate->FeedbackMixer[3].Alpha=Alpha;
510
511 NumChannels = 2; /* Always stereo output */
512 pPrivate->BypassMixer.Alpha1 = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_BYPASSMIXER_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), NumChannels);
513 pPrivate->BypassMixer.Alpha2 = pPrivate->BypassMixer.Alpha1;
514 pPrivate->GainMixer.Alpha = pPrivate->BypassMixer.Alpha1;
515 }
516
517
518 /*
519 * Update the bypass mixer targets
520 */
521 if( (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) &&
522 (pPrivate->NewParams.OperatingMode == LVM_MODE_ON))
523 {
524 pPrivate->BypassMixer.Target2 = ((LVM_INT32)(pPrivate->NewParams.Level * 32767)/100)<<16;
525 pPrivate->BypassMixer.Target1 = 0x00000000;
526 if ((pPrivate->NewParams.Level == 0) && (pPrivate->bFirstControl == LVM_FALSE))
527 {
528 pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE;
529 }
530 if (pPrivate->NewParams.Level != 0)
531 {
532 pPrivate->bDisableReverb = LVM_FALSE;
533 }
534 }
535
536 if(pPrivate->NewParams.OperatingMode != pPrivate->CurrentParams.OperatingMode)
537 {
538 if(pPrivate->NewParams.OperatingMode == LVM_MODE_ON)
539 {
540 pPrivate->BypassMixer.Target2 = ((LVM_INT32)(pPrivate->NewParams.Level * 32767)/100)<<16;
541 pPrivate->BypassMixer.Target1 = 0x00000000;
542
543 pPrivate->BypassMixer.CallbackSet2 = LVM_FALSE;
544 OperatingMode = LVM_MODE_ON;
545 if (pPrivate->NewParams.Level == 0)
546 {
547 pPrivate->bDisableReverb = LVM_TRUE;
548 }
549 else
550 {
551 pPrivate->bDisableReverb = LVM_FALSE;
552 }
553 }
554 else if (pPrivate->bFirstControl == LVM_FALSE)
555 {
556 pPrivate->BypassMixer.Target2 = 0x00000000;
557 pPrivate->BypassMixer.Target1 = 0x00000000;
558 pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE;
559 pPrivate->GainMixer.Target = 0x03FFFFFF;
560 OperatingMode = LVM_MODE_ON;
561 }
562 else
563 {
564 OperatingMode = LVM_MODE_OFF;
565 }
566 }
567
568
569 /*
570 * If it is the first call to ApplyNew settings force the current to the target to begin immediate playback of the effect
571 */
572 if(pPrivate->bFirstControl == LVM_TRUE)
573 {
574 pPrivate->BypassMixer.Current1 = pPrivate->BypassMixer.Target1;
575 pPrivate->BypassMixer.Current2 = pPrivate->BypassMixer.Target2;
576 }
577
578
579 /*
580 * Copy the new parameters
581 */
582 pPrivate->CurrentParams = pPrivate->NewParams;
583 pPrivate->CurrentParams.OperatingMode = OperatingMode;
584
585
586 /*
587 * Update flag
588 */
589 if(pPrivate->bFirstControl == LVM_TRUE)
590 {
591 pPrivate->bFirstControl = LVM_FALSE;
592 }
593
594
595 return LVREV_SUCCESS;
596 }
597 #else /* BUILD_FLOAT*/
LVREV_ApplyNewSettings(LVREV_Instance_st * pPrivate)598 LVREV_ReturnStatus_en LVREV_ApplyNewSettings (LVREV_Instance_st *pPrivate)
599 {
600
601 LVM_Mode_en OperatingMode;
602 LVM_INT32 NumberOfDelayLines;
603
604
605 /* Check for NULL pointer */
606 if(pPrivate == LVM_NULL)
607 {
608 return LVREV_NULLADDRESS;
609 }
610
611 OperatingMode = pPrivate->NewParams.OperatingMode;
612
613 if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
614 {
615 NumberOfDelayLines = 4;
616 }
617 else if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_2)
618 {
619 NumberOfDelayLines = 2;
620 }
621 else
622 {
623 NumberOfDelayLines = 1;
624 }
625
626 /*
627 * Update the high pass filter coefficients
628 */
629 if((pPrivate->NewParams.HPF != pPrivate->CurrentParams.HPF) ||
630 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
631 (pPrivate->bFirstControl == LVM_TRUE))
632 {
633 LVM_FLOAT Omega;
634 FO_FLOAT_Coefs_t Coeffs;
635
636 Omega = LVM_GetOmega(pPrivate->NewParams.HPF, pPrivate->NewParams.SampleRate);
637 LVM_FO_HPF(Omega, &Coeffs);
638 FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->HPCoefs,
639 &pPrivate->pFastData->HPTaps, &Coeffs);
640 LoadConst_Float(0,
641 (void *)&pPrivate->pFastData->HPTaps, /* Destination Cast to void: \
642 no dereferencing in function*/
643 sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
644 }
645
646
647 /*
648 * Update the low pass filter coefficients
649 */
650 if((pPrivate->NewParams.LPF != pPrivate->CurrentParams.LPF) ||
651 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
652 (pPrivate->bFirstControl == LVM_TRUE))
653 {
654 LVM_FLOAT Omega;
655 FO_FLOAT_Coefs_t Coeffs;
656
657 Coeffs.A0 = 1;
658 Coeffs.A1 = 0;
659 Coeffs.B1 = 0;
660 if(pPrivate->NewParams.LPF <= (LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1))
661 {
662 Omega = LVM_GetOmega(pPrivate->NewParams.LPF, pPrivate->NewParams.SampleRate);
663
664 /*
665 * Do not apply filter if w =2*pi*fc/fs >= 2.9
666 */
667 if(Omega <= (LVM_FLOAT)LVREV_2_9_INQ29)
668 {
669 LVM_FO_LPF(Omega, &Coeffs);
670 }
671 }
672 FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->LPCoefs,
673 &pPrivate->pFastData->LPTaps, &Coeffs);
674 LoadConst_Float(0,
675 (void *)&pPrivate->pFastData->LPTaps, /* Destination Cast to void: \
676 no dereferencing in function*/
677 sizeof(Biquad_1I_Order1_FLOAT_Taps_t) / sizeof(LVM_FLOAT));
678 }
679
680
681 /*
682 * Calculate the room size parameter
683 */
684 if( pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize)
685 {
686 /* Room size range is 10ms to 200ms
687 * 0% -- 10ms
688 * 50% -- 65ms
689 * 100% -- 120ms
690 */
691 pPrivate->RoomSizeInms = 10 + (((pPrivate->NewParams.RoomSize*11) + 5) / 10);
692 }
693
694
695 /*
696 * Update the T delay number of samples and the all pass delay number of samples
697 */
698 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
699 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
700 (pPrivate->bFirstControl == LVM_TRUE))
701 {
702
703 LVM_UINT32 Temp;
704 LVM_INT32 APDelaySize;
705 LVM_INT32 Fs = LVM_GetFsFromTable(pPrivate->NewParams.SampleRate);
706 LVM_UINT32 DelayLengthSamples = (LVM_UINT32)(Fs * pPrivate->RoomSizeInms);
707 LVM_INT16 i;
708 LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4, \
709 LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4};
710 LVM_INT16 MaxT_Delay[] = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, \
711 LVREV_MAX_T2_DELAY, LVREV_MAX_T3_DELAY};
712 LVM_INT16 MaxAP_Delay[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY, \
713 LVREV_MAX_AP2_DELAY, LVREV_MAX_AP3_DELAY};
714
715
716 /*
717 * For each delay line
718 */
719 for (i = 0; i < NumberOfDelayLines; i++)
720 {
721 if (i != 0)
722 {
723 LVM_FLOAT Temp1; /* to avoid QAC warning on type conversion */
724
725 Temp1=(LVM_FLOAT)DelayLengthSamples;
726 Temp = (LVM_UINT32)(Temp1 * ScaleTable[i]);
727 }
728 else
729 {
730 Temp = DelayLengthSamples;
731 }
732 APDelaySize = Temp / 1500;
733
734
735 /*
736 * Set the fixed delay
737 */
738
739 #ifdef HIGHER_FS
740 Temp = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 192000;
741 #else
742 Temp = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 48000;
743 #endif
744 pPrivate->Delay_AP[i] = pPrivate->T[i] - Temp;
745
746
747 /*
748 * Set the tap selection
749 */
750 if (pPrivate->AB_Selection)
751 {
752 /* Smooth from tap A to tap B */
753 pPrivate->pOffsetB[i] = &pPrivate->pDelay_T[i][pPrivate->T[i] - \
754 Temp - APDelaySize];
755 pPrivate->B_DelaySize[i] = APDelaySize;
756 pPrivate->Mixer_APTaps[i].Target1 = 0;
757 pPrivate->Mixer_APTaps[i].Target2 = 1.0f;
758 }
759 else
760 {
761 /* Smooth from tap B to tap A */
762 pPrivate->pOffsetA[i] = &pPrivate->pDelay_T[i][pPrivate->T[i] - \
763 Temp - APDelaySize];
764 pPrivate->A_DelaySize[i] = APDelaySize;
765 pPrivate->Mixer_APTaps[i].Target2 = 0;
766 pPrivate->Mixer_APTaps[i].Target1 = 1.0f;
767 }
768
769 /*
770 * Set the maximum block size to the smallest delay size
771 */
772 pPrivate->MaxBlkLen = Temp;
773 if (pPrivate->MaxBlkLen > pPrivate->A_DelaySize[i])
774 {
775 pPrivate->MaxBlkLen = pPrivate->A_DelaySize[i];
776 }
777 if (pPrivate->MaxBlkLen > pPrivate->B_DelaySize[i])
778 {
779 pPrivate->MaxBlkLen = pPrivate->B_DelaySize[i];
780 }
781 }
782 if (pPrivate->AB_Selection)
783 {
784 pPrivate->AB_Selection = 0;
785 }
786 else
787 {
788 pPrivate->AB_Selection = 1;
789 }
790
791
792 /*
793 * Limit the maximum block length
794 */
795 /* Just as a precausion, but no problem if we remove this line */
796 pPrivate->MaxBlkLen = pPrivate->MaxBlkLen - 2;
797 if(pPrivate->MaxBlkLen > pPrivate->InstanceParams.MaxBlockSize)
798 {
799 pPrivate->MaxBlkLen = (LVM_INT32)pPrivate->InstanceParams.MaxBlockSize;
800 }
801 }
802
803
804
805 /*
806 * Update the low pass filter coefficient
807 */
808 if( (pPrivate->NewParams.Damping != pPrivate->CurrentParams.Damping) ||
809 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
810 (pPrivate->bFirstControl == LVM_TRUE))
811 {
812
813 LVM_INT32 Temp;
814 LVM_FLOAT Omega;
815 FO_FLOAT_Coefs_t Coeffs;
816 LVM_INT16 i;
817 LVM_INT16 Damping = (LVM_INT16)((pPrivate->NewParams.Damping * 100) + 1000);
818 LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_0_on_4, LVREV_T_3_Power_1_on_4,
819 LVREV_T_3_Power_2_on_4, LVREV_T_3_Power_3_on_4};
820
821
822 /*
823 * For each filter
824 */
825 for (i = 0; i < NumberOfDelayLines; i++)
826 {
827 if (i != 0)
828 {
829 Temp = (LVM_INT32)(ScaleTable[i] * Damping);
830 }
831 else
832 {
833 Temp = Damping;
834 }
835 if(Temp <= (LVM_INT32)(LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1))
836 {
837 Omega = LVM_GetOmega(Temp, pPrivate->NewParams.SampleRate);
838 LVM_FO_LPF(Omega, &Coeffs);
839 }
840 else
841 {
842 Coeffs.A0 = 1;
843 Coeffs.A1 = 0;
844 Coeffs.B1 = 0;
845 }
846 FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->RevLPCoefs[i],
847 &pPrivate->pFastData->RevLPTaps[i], &Coeffs);
848 }
849 }
850
851
852 /*
853 * Update All-pass filter mixer time constants
854 */
855 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
856 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
857 (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density))
858 {
859 LVM_INT16 i;
860 LVM_FLOAT Alpha;
861 LVM_FLOAT AlphaTap;
862
863 Alpha = LVM_Mixer_TimeConstant(LVREV_ALLPASS_TC,
864 LVM_GetFsFromTable(pPrivate->NewParams.SampleRate),
865 1);
866
867 AlphaTap = LVM_Mixer_TimeConstant(LVREV_ALLPASS_TAP_TC,
868 LVM_GetFsFromTable(pPrivate->NewParams.SampleRate),
869 1);
870
871 for (i = 0; i < 4; i++)
872 {
873 pPrivate->Mixer_APTaps[i].Alpha1 = AlphaTap;
874 pPrivate->Mixer_APTaps[i].Alpha2 = AlphaTap;
875 pPrivate->Mixer_SGFeedback[i].Alpha = Alpha;
876 pPrivate->Mixer_SGFeedforward[i].Alpha = Alpha;
877 }
878 }
879
880
881 /*
882 * Update the feed back gain
883 */
884 if( (pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
885 (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
886 (pPrivate->NewParams.T60 != pPrivate->CurrentParams.T60) ||
887 (pPrivate->bFirstControl == LVM_TRUE))
888 {
889
890 LVM_FLOAT G[4]; /* Feedback gain (Q7.24) */
891
892 if(pPrivate->NewParams.T60 == 0)
893 {
894 G[3] = 0;
895 G[2] = 0;
896 G[1] = 0;
897 G[0] = 0;
898 }
899 else
900 {
901 LVM_FLOAT Temp1;
902 LVM_FLOAT Temp2;
903 LVM_INT16 i;
904 LVM_FLOAT ScaleTable[] = {LVREV_T_3_Power_minus0_on_4, LVREV_T_3_Power_minus1_on_4,
905 LVREV_T_3_Power_minus2_on_4, LVREV_T_3_Power_minus3_on_4};
906
907
908 /*
909 * For each delay line
910 */
911 for (i = 0; i < NumberOfDelayLines; i++)
912 {
913 Temp1 = (3 * pPrivate->RoomSizeInms * ScaleTable[i]) / pPrivate->NewParams.T60;
914 if(Temp1 >= (4))
915 {
916 G[i] = 0;
917 }
918 else if((Temp1 >= (2)))
919 {
920 Temp2 = LVM_Power10(-(Temp1 / 2.0f));
921 Temp1 = LVM_Power10(-(Temp1 / 2.0f));
922 Temp1 = Temp1 * Temp2;
923 }
924 else
925 {
926 Temp1 = LVM_Power10(-(Temp1));
927 }
928 if (NumberOfDelayLines == 1)
929 {
930 G[i] = Temp1;
931 }
932 else
933 {
934 LVM_FLOAT TempG;
935 TempG = Temp1 * ONE_OVER_SQRT_TWO;
936 G[i]=TempG;
937 }
938 }
939 }
940
941 /* Set up the feedback mixers for four delay lines */
942 pPrivate->FeedbackMixer[0].Target=G[0];
943 pPrivate->FeedbackMixer[1].Target=G[1];
944 pPrivate->FeedbackMixer[2].Target=G[2];
945 pPrivate->FeedbackMixer[3].Target=G[3];
946 }
947
948
949 /*
950 * Calculate the gain correction
951 */
952 if((pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
953 (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) ||
954 (pPrivate->NewParams.T60 != pPrivate->CurrentParams.T60) )
955 {
956 LVM_INT32 Index=0;
957 LVM_FLOAT Index_FLOAT;
958 LVM_INT32 i=0;
959 LVM_FLOAT Gain=0;
960 LVM_INT32 RoomSize=0;
961 LVM_FLOAT T60;
962 LVM_FLOAT Coefs[5];
963
964
965 if(pPrivate->NewParams.RoomSize == 0)
966 {
967 RoomSize = 1;
968 }
969 else
970 {
971 RoomSize = (LVM_INT32)pPrivate->NewParams.RoomSize;
972 }
973
974
975 if(pPrivate->NewParams.T60 < 100)
976 {
977 T60 = 100 * LVREV_T60_SCALE;
978 }
979 else
980 {
981 T60 = pPrivate->NewParams.T60 * LVREV_T60_SCALE;
982 }
983
984 /* Find the nearest room size in table */
985 for(i = 0; i < 24; i++)
986 {
987 if(RoomSize <= LVREV_GainPolyTable[i][0])
988 {
989 Index = i;
990 break;
991 }
992 }
993
994
995 if(RoomSize == LVREV_GainPolyTable[Index][0])
996 {
997 /* Take table values if the room size is in table */
998 for(i = 1; i < 5; i++)
999 {
1000 Coefs[i-1] = LVREV_GainPolyTable[Index][i];
1001 }
1002 Coefs[4] = 0;
1003 Gain = LVM_Polynomial(3, Coefs, T60); /* Q.24 result */
1004 }
1005 else
1006 {
1007 /* Interpolate the gain between nearest room sizes */
1008
1009 LVM_FLOAT Gain1,Gain2;
1010 LVM_INT32 Tot_Dist,Dist;
1011
1012 Tot_Dist = (LVM_UINT32)LVREV_GainPolyTable[Index][0] - \
1013 (LVM_UINT32)LVREV_GainPolyTable[Index-1][0];
1014 Dist = RoomSize - (LVM_UINT32)LVREV_GainPolyTable[Index - 1][0];
1015
1016
1017 /* Get gain for first */
1018 for(i = 1; i < 5; i++)
1019 {
1020 Coefs[i-1] = LVREV_GainPolyTable[Index-1][i];
1021 }
1022 Coefs[4] = 0;
1023
1024 Gain1 = LVM_Polynomial(3, Coefs, T60); /* Q.24 result */
1025
1026 /* Get gain for second */
1027 for(i = 1; i < 5; i++)
1028 {
1029 Coefs[i-1] = LVREV_GainPolyTable[Index][i];
1030 }
1031 Coefs[4] = 0;
1032
1033 Gain2 = LVM_Polynomial(3, Coefs, T60); /* Q.24 result */
1034
1035 /* Linear Interpolate the gain */
1036 Gain = Gain1 + (((Gain2 - Gain1) * Dist) / (Tot_Dist));
1037 }
1038
1039
1040 /*
1041 * Get the inverse of gain: Q.15
1042 * Gain is mostly above one except few cases, take only gains above 1
1043 */
1044 if(Gain < 1)
1045 {
1046 pPrivate->Gain = 1;
1047 }
1048 else
1049 {
1050 pPrivate->Gain = 1 / Gain;
1051 }
1052
1053 Index_FLOAT = 100.0f / (LVM_FLOAT)(100 + pPrivate->NewParams.Level);
1054 pPrivate->Gain = pPrivate->Gain * Index_FLOAT;
1055 pPrivate->GainMixer.Target = (pPrivate->Gain*Index_FLOAT) / 2;
1056 }
1057
1058
1059 /*
1060 * Update the all pass comb filter coefficient
1061 */
1062 if( (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density) ||
1063 (pPrivate->bFirstControl == LVM_TRUE))
1064 {
1065 LVM_INT16 i;
1066 LVM_FLOAT b = (LVM_FLOAT)pPrivate->NewParams.Density * LVREV_B_8_on_1000;
1067
1068 for (i = 0; i < 4; i++)
1069 {
1070 pPrivate->Mixer_SGFeedback[i].Target = b;
1071 pPrivate->Mixer_SGFeedforward[i].Target = b;
1072 }
1073 }
1074
1075
1076 /*
1077 * Update the bypass mixer time constant
1078 */
1079 if((pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
1080 (pPrivate->bFirstControl == LVM_TRUE))
1081 {
1082 LVM_UINT16 NumChannels = 1; /* Assume MONO format */
1083 LVM_FLOAT Alpha;
1084
1085 Alpha = LVM_Mixer_TimeConstant(LVREV_FEEDBACKMIXER_TC,
1086 LVM_GetFsFromTable(pPrivate->NewParams.SampleRate),
1087 NumChannels);
1088 pPrivate->FeedbackMixer[0].Alpha = Alpha;
1089 pPrivate->FeedbackMixer[1].Alpha = Alpha;
1090 pPrivate->FeedbackMixer[2].Alpha = Alpha;
1091 pPrivate->FeedbackMixer[3].Alpha = Alpha;
1092
1093 NumChannels = 2; /* Always stereo output */
1094 pPrivate->BypassMixer.Alpha1 = LVM_Mixer_TimeConstant(LVREV_BYPASSMIXER_TC,
1095 LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), NumChannels);
1096 pPrivate->BypassMixer.Alpha2 = pPrivate->BypassMixer.Alpha1;
1097 pPrivate->GainMixer.Alpha = pPrivate->BypassMixer.Alpha1;
1098 }
1099
1100
1101 /*
1102 * Update the bypass mixer targets
1103 */
1104 if( (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) &&
1105 (pPrivate->NewParams.OperatingMode == LVM_MODE_ON))
1106 {
1107 pPrivate->BypassMixer.Target2 = (LVM_FLOAT)(pPrivate->NewParams.Level ) / 100.0f;
1108 pPrivate->BypassMixer.Target1 = 0x00000000;
1109 if ((pPrivate->NewParams.Level == 0) && (pPrivate->bFirstControl == LVM_FALSE))
1110 {
1111 pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE;
1112 }
1113 if (pPrivate->NewParams.Level != 0)
1114 {
1115 pPrivate->bDisableReverb = LVM_FALSE;
1116 }
1117 }
1118
1119 if(pPrivate->NewParams.OperatingMode != pPrivate->CurrentParams.OperatingMode)
1120 {
1121 if(pPrivate->NewParams.OperatingMode == LVM_MODE_ON)
1122 {
1123 pPrivate->BypassMixer.Target2 = (LVM_FLOAT)(pPrivate->NewParams.Level ) / 100.0f;
1124 pPrivate->BypassMixer.Target1 = 0x00000000;
1125
1126 pPrivate->BypassMixer.CallbackSet2 = LVM_FALSE;
1127 OperatingMode = LVM_MODE_ON;
1128 if (pPrivate->NewParams.Level == 0)
1129 {
1130 pPrivate->bDisableReverb = LVM_TRUE;
1131 }
1132 else
1133 {
1134 pPrivate->bDisableReverb = LVM_FALSE;
1135 }
1136 }
1137 else if (pPrivate->bFirstControl == LVM_FALSE)
1138 {
1139 pPrivate->BypassMixer.Target2 = 0x00000000;
1140 pPrivate->BypassMixer.Target1 = 0x00000000;
1141 pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE;
1142 pPrivate->GainMixer.Target = 0.03125f;
1143 OperatingMode = LVM_MODE_ON;
1144 }
1145 else
1146 {
1147 OperatingMode = LVM_MODE_OFF;
1148 }
1149 }
1150
1151
1152 /* If it is the first call to ApplyNew settings force the current to the target \
1153 to begin immediate playback of the effect */
1154 if(pPrivate->bFirstControl == LVM_TRUE)
1155 {
1156 pPrivate->BypassMixer.Current1 = pPrivate->BypassMixer.Target1;
1157 pPrivate->BypassMixer.Current2 = pPrivate->BypassMixer.Target2;
1158 }
1159
1160
1161 /*
1162 * Copy the new parameters
1163 */
1164 pPrivate->CurrentParams = pPrivate->NewParams;
1165 pPrivate->CurrentParams.OperatingMode = OperatingMode;
1166
1167
1168 /*
1169 * Update flag
1170 */
1171 if(pPrivate->bFirstControl == LVM_TRUE)
1172 {
1173 pPrivate->bFirstControl = LVM_FALSE;
1174 }
1175
1176
1177 return LVREV_SUCCESS;
1178 }
1179 #endif /*BUILD_FLOAT*/
1180 /****************************************************************************************/
1181 /* */
1182 /* FUNCTION: BypassMixer_Callback */
1183 /* */
1184 /* DESCRIPTION: */
1185 /* Controls the On to Off operating mode transition */
1186 /* */
1187 /* PARAMETERS: */
1188 /* pPrivate Pointer to the instance private parameters */
1189 /* */
1190 /* RETURNS: */
1191 /* LVREV_Success Succeeded */
1192 /* LVREV_NULLADDRESS When pPrivate is NULL */
1193 /* */
1194 /* NOTES: */
1195 /* */
1196 /****************************************************************************************/
BypassMixer_Callback(void * pCallbackData,void * pGeneralPurpose,LVM_INT16 GeneralPurpose)1197 LVM_INT32 BypassMixer_Callback (void *pCallbackData,
1198 void *pGeneralPurpose,
1199 LVM_INT16 GeneralPurpose )
1200 {
1201
1202 LVREV_Instance_st *pLVREV_Private = (LVREV_Instance_st *)pCallbackData;
1203
1204
1205 /*
1206 * Avoid build warnings
1207 */
1208 (void)pGeneralPurpose;
1209 (void)GeneralPurpose;
1210
1211
1212 /*
1213 * Turn off
1214 */
1215 pLVREV_Private->CurrentParams.OperatingMode = LVM_MODE_OFF;
1216 pLVREV_Private->bDisableReverb = LVM_TRUE;
1217 LVREV_ClearAudioBuffers((LVREV_Handle_t)pCallbackData);
1218
1219
1220 return 0;
1221 }
1222
1223 /* End of file */
1224
1225