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
44LVREV_ReturnStatus_en LVREV_ApplyNewSettings (LVREV_Instance_st     *pPrivate)
45{
46
47    LVM_Mode_en  OperatingMode;
48    LVM_INT32    NumberOfDelayLines;
49
50
51    /* Check for NULL pointer */
52    if(pPrivate == LVM_NULL)
53    {
54        return LVREV_NULLADDRESS;
55    }
56
57    OperatingMode = pPrivate->NewParams.OperatingMode;
58
59    if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_4)
60    {
61        NumberOfDelayLines = 4;
62    }
63    else if(pPrivate->InstanceParams.NumDelays == LVREV_DELAYLINES_2)
64    {
65        NumberOfDelayLines = 2;
66    }
67    else
68    {
69        NumberOfDelayLines = 1;
70    }
71
72    /*
73     * Update the high pass filter coefficients
74     */
75    if((pPrivate->NewParams.HPF        != pPrivate->CurrentParams.HPF)        ||
76       (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
77       (pPrivate->bFirstControl        == LVM_TRUE))
78    {
79        LVM_INT32       Omega;
80        FO_C32_Coefs_t  Coeffs;
81
82        Omega = LVM_GetOmega(pPrivate->NewParams.HPF, pPrivate->NewParams.SampleRate);
83        LVM_FO_HPF(Omega, &Coeffs);
84        FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->HPCoefs, &pPrivate->pFastData->HPTaps, &Coeffs);
85        LoadConst_32(0,
86            (void *)&pPrivate->pFastData->HPTaps, /* Destination Cast to void: no dereferencing in function*/
87            sizeof(Biquad_1I_Order1_Taps_t)/sizeof(LVM_INT32));
88    }
89
90
91    /*
92     * Update the low pass filter coefficients
93     */
94    if((pPrivate->NewParams.LPF        != pPrivate->CurrentParams.LPF)        ||
95       (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
96       (pPrivate->bFirstControl        == LVM_TRUE))
97    {
98        LVM_INT32       Omega;
99        FO_C32_Coefs_t  Coeffs;
100
101
102        Coeffs.A0 = 0x7FFFFFFF;
103        Coeffs.A1 = 0;
104        Coeffs.B1 = 0;
105        if(pPrivate->NewParams.LPF <= (LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1))
106        {
107            Omega = LVM_GetOmega(pPrivate->NewParams.LPF, pPrivate->NewParams.SampleRate);
108
109            /*
110             * Do not apply filter if w =2*pi*fc/fs >= 2.9
111             */
112            if(Omega<=LVREV_2_9_INQ29)
113            {
114                LVM_FO_LPF(Omega, &Coeffs);
115            }
116        }
117        FO_1I_D32F32Cll_TRC_WRA_01_Init( &pPrivate->pFastCoef->LPCoefs, &pPrivate->pFastData->LPTaps, &Coeffs);
118        LoadConst_32(0,
119            (void *)&pPrivate->pFastData->LPTaps,        /* Destination Cast to void: no dereferencing in function*/
120            sizeof(Biquad_1I_Order1_Taps_t)/sizeof(LVM_INT32));
121    }
122
123
124    /*
125     * Calculate the room size parameter
126     */
127    if( pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize)
128    {
129        /* Room size range is 10ms to 200ms
130         * 0%   -- 10ms
131         * 50%  -- 65ms
132         * 100% -- 120ms
133         */
134        pPrivate->RoomSizeInms = 10 + (((pPrivate->NewParams.RoomSize*11) + 5)/10);
135    }
136
137
138    /*
139     * Update the T delay number of samples and the all pass delay number of samples
140     */
141    if( (pPrivate->NewParams.RoomSize   != pPrivate->CurrentParams.RoomSize)   ||
142        (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
143        (pPrivate->bFirstControl        == LVM_TRUE))
144    {
145
146        LVM_UINT32  Temp;
147        LVM_INT32   APDelaySize;
148        LVM_INT32   Fs = LVM_GetFsFromTable(pPrivate->NewParams.SampleRate);
149        LVM_UINT32  DelayLengthSamples = (LVM_UINT32)(Fs * pPrivate->RoomSizeInms);
150        LVM_INT16   i;
151        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};
152        LVM_INT16   MaxT_Delay[]  = {LVREV_MAX_T0_DELAY, LVREV_MAX_T1_DELAY, LVREV_MAX_T2_DELAY, LVREV_MAX_T3_DELAY};
153        LVM_INT16   MaxAP_Delay[] = {LVREV_MAX_AP0_DELAY, LVREV_MAX_AP1_DELAY, LVREV_MAX_AP2_DELAY, LVREV_MAX_AP3_DELAY};
154
155
156        /*
157         * For each delay line
158         */
159        for (i=0; i<NumberOfDelayLines; i++)
160        {
161            if (i != 0)
162            {
163                LVM_INT32 Temp1;  /* to avoid QAC warning on type conversion */
164                LVM_INT32 Temp2;  /* to avoid QAC warning on type conversion */
165
166                Temp2=(LVM_INT32)DelayLengthSamples;
167                MUL32x16INTO32(Temp2, ScaleTable[i], Temp1, 15)
168                Temp=(LVM_UINT32)Temp1;
169            }
170            else
171            {
172               Temp = DelayLengthSamples;
173            }
174            APDelaySize = Temp  / 1500;
175
176
177            /*
178             * Set the fixed delay
179             */
180            Temp                  = (MaxT_Delay[i] - MaxAP_Delay[i]) * Fs / 48000;
181            pPrivate->Delay_AP[i] = pPrivate->T[i] - Temp;
182
183
184            /*
185             * Set the tap selection
186             */
187            if (pPrivate->AB_Selection)
188            {
189                /* Smooth from tap A to tap B */
190                pPrivate->pOffsetB[i]             = &pPrivate->pDelay_T[i][pPrivate->T[i] - Temp - APDelaySize];
191                pPrivate->B_DelaySize[i]          = APDelaySize;
192                pPrivate->Mixer_APTaps[i].Target1 = 0;
193                pPrivate->Mixer_APTaps[i].Target2 = 0x7fffffff;
194            }
195            else
196            {
197                /* Smooth from tap B to tap A */
198                pPrivate->pOffsetA[i]             = &pPrivate->pDelay_T[i][pPrivate->T[i] - Temp - APDelaySize];
199                pPrivate->A_DelaySize[i]          = APDelaySize;
200                pPrivate->Mixer_APTaps[i].Target2 = 0;
201                pPrivate->Mixer_APTaps[i].Target1 = 0x7fffffff;
202            }
203
204            /*
205             * Set the maximum block size to the smallest delay size
206             */
207            pPrivate->MaxBlkLen   = Temp;
208            if (pPrivate->MaxBlkLen > pPrivate->A_DelaySize[i])
209            {
210                pPrivate->MaxBlkLen = pPrivate->A_DelaySize[i];
211            }
212            if (pPrivate->MaxBlkLen > pPrivate->B_DelaySize[i])
213            {
214                pPrivate->MaxBlkLen = pPrivate->B_DelaySize[i];
215            }
216        }
217        if (pPrivate->AB_Selection)
218        {
219            pPrivate->AB_Selection = 0;
220        }
221        else
222        {
223            pPrivate->AB_Selection = 1;
224        }
225
226
227        /*
228         * Limit the maximum block length
229         */
230        pPrivate->MaxBlkLen=pPrivate->MaxBlkLen-2;                                  /* Just as a precausion, but no problem if we remove this line      */
231        if(pPrivate->MaxBlkLen > pPrivate->InstanceParams.MaxBlockSize)
232        {
233            pPrivate->MaxBlkLen = (LVM_INT32)pPrivate->InstanceParams.MaxBlockSize;
234        }
235    }
236
237
238    /*
239     * Update the low pass filter coefficient
240     */
241    if( (pPrivate->NewParams.Damping    != pPrivate->CurrentParams.Damping)    ||
242        (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
243        (pPrivate->bFirstControl        == LVM_TRUE))
244    {
245
246        LVM_INT32       Temp;
247        LVM_INT32       Omega;
248        FO_C32_Coefs_t  Coeffs;
249        LVM_INT16       i;
250        LVM_INT16       Damping      = (LVM_INT16)((pPrivate->NewParams.Damping * 100) + 1000);
251        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};
252
253
254        /*
255         * For each filter
256         */
257        for (i=0; i<NumberOfDelayLines; i++)
258        {
259            if (i != 0)
260            {
261                MUL32x16INTO32(ScaleTable[i], Damping, Temp, 15)
262            }
263            else
264            {
265                Temp = Damping;
266            }
267            if(Temp <= (LVM_FsTable[pPrivate->NewParams.SampleRate] >> 1))
268            {
269                Omega = LVM_GetOmega((LVM_UINT16)Temp, pPrivate->NewParams.SampleRate);
270                LVM_FO_LPF(Omega, &Coeffs);
271            }
272            else
273            {
274                Coeffs.A0 = 0x7FF00000;
275                Coeffs.A1 = 0;
276                Coeffs.B1 = 0;
277            }
278            FO_1I_D32F32Cll_TRC_WRA_01_Init(&pPrivate->pFastCoef->RevLPCoefs[i], &pPrivate->pFastData->RevLPTaps[i], &Coeffs);
279        }
280    }
281
282
283    /*
284     * Update All-pass filter mixer time constants
285     */
286    if( (pPrivate->NewParams.RoomSize   != pPrivate->CurrentParams.RoomSize)   ||
287        (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
288        (pPrivate->NewParams.Density    != pPrivate->CurrentParams.Density))
289    {
290        LVM_INT16   i;
291        LVM_INT32   Alpha    = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_ALLPASS_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), 1);
292        LVM_INT32   AlphaTap = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_ALLPASS_TAP_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), 1);
293
294        for (i=0; i<4; i++)
295        {
296            pPrivate->Mixer_APTaps[i].Alpha1       = AlphaTap;
297            pPrivate->Mixer_APTaps[i].Alpha2       = AlphaTap;
298            pPrivate->Mixer_SGFeedback[i].Alpha    = Alpha;
299            pPrivate->Mixer_SGFeedforward[i].Alpha = Alpha;
300        }
301    }
302
303
304    /*
305     * Update the feed back gain
306     */
307    if( (pPrivate->NewParams.RoomSize   != pPrivate->CurrentParams.RoomSize)   ||
308        (pPrivate->NewParams.SampleRate != pPrivate->CurrentParams.SampleRate) ||
309        (pPrivate->NewParams.T60        != pPrivate->CurrentParams.T60)        ||
310        (pPrivate->bFirstControl        == LVM_TRUE))
311    {
312
313        LVM_INT32               G[4];                       /* Feedback gain (Q7.24) */
314
315        if(pPrivate->NewParams.T60 == 0)
316        {
317            G[3] = 0;
318            G[2] = 0;
319            G[1] = 0;
320            G[0] = 0;
321        }
322        else
323        {
324            LVM_INT32   Temp1;
325            LVM_INT32   Temp2;
326            LVM_INT16   i;
327            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};
328
329
330            /*
331             * For each delay line
332             */
333            for (i=0; i<NumberOfDelayLines; i++)
334            {
335                Temp1 = (3 * pPrivate->RoomSizeInms * ScaleTable[i]) / pPrivate->NewParams.T60;
336                if(Temp1 >= (4 << 15))
337                {
338                    G[i] = 0;
339                }
340                else if((Temp1 >= (2 << 15)))
341                {
342                    Temp2 = LVM_Power10(-(Temp1 << 14));
343                    Temp1 = LVM_Power10(-(Temp1 << 14));
344                    MUL32x32INTO32(Temp1,Temp2,Temp1,24)
345                }
346                else
347                {
348                    Temp1 = LVM_Power10(-(Temp1 << 15));
349                }
350                if (NumberOfDelayLines == 1)
351                {
352                    G[i] = Temp1;
353                }
354                else
355                {
356                    LVM_INT32   TempG;
357                    MUL32x16INTO32(Temp1,ONE_OVER_SQRT_TWO,TempG,15)
358                    G[i]=TempG;
359                }
360            }
361        }
362
363        /* Set up the feedback mixers for four delay lines */
364        pPrivate->FeedbackMixer[0].Target=G[0]<<7;
365        pPrivate->FeedbackMixer[1].Target=G[1]<<7;
366        pPrivate->FeedbackMixer[2].Target=G[2]<<7;
367        pPrivate->FeedbackMixer[3].Target=G[3]<<7;
368    }
369
370
371    /*
372     * Calculate the gain correction
373     */
374    if((pPrivate->NewParams.RoomSize != pPrivate->CurrentParams.RoomSize) ||
375       (pPrivate->NewParams.Level    != pPrivate->CurrentParams.Level)    ||
376       (pPrivate->NewParams.T60      != pPrivate->CurrentParams.T60) )
377    {
378        LVM_INT32 Index=0;
379        LVM_INT32 i=0;
380        LVM_INT32 Gain=0;
381        LVM_INT32 RoomSize=0;
382        LVM_INT32 T60;
383        LVM_INT32 Coefs[5];
384
385        if(pPrivate->NewParams.RoomSize==0)
386        {
387            RoomSize=1;
388        }
389        else
390        {
391            RoomSize=(LVM_INT32)pPrivate->NewParams.RoomSize;
392        }
393
394        if(pPrivate->NewParams.T60<100)
395        {
396            T60 = 100 * LVREV_T60_SCALE;
397        }
398        else
399        {
400            T60 = pPrivate->NewParams.T60 * LVREV_T60_SCALE;
401        }
402
403        /* Find the nearest room size in table */
404        for(i=0;i<24;i++)
405        {
406            if(RoomSize<= LVREV_GainPolyTable[i][0])
407            {
408                Index=i;
409                break;
410            }
411        }
412
413
414        if(RoomSize==LVREV_GainPolyTable[Index][0])
415        {
416            /* Take table values if the room size is in table */
417            for(i=1;i<5;i++)
418            {
419                Coefs[i-1]=LVREV_GainPolyTable[Index][i];
420            }
421            Coefs[4]=0;
422            Gain=LVM_Polynomial(3,Coefs,T60);       /* Q.24 result */
423        }
424        else
425        {
426            /* Interpolate the gain between nearest room sizes */
427
428            LVM_INT32 Gain1,Gain2;
429            LVM_INT32 Tot_Dist,Dist;
430
431            Tot_Dist=LVREV_GainPolyTable[Index][0]-LVREV_GainPolyTable[Index-1][0];
432            Dist=RoomSize-LVREV_GainPolyTable[Index-1][0];
433
434
435            /* Get gain for first */
436            for(i=1;i<5;i++)
437            {
438                Coefs[i-1]=LVREV_GainPolyTable[Index-1][i];
439            }
440            Coefs[4]=0;
441
442            Gain1=LVM_Polynomial(3,Coefs,T60);      /* Q.24 result */
443
444            /* Get gain for second */
445            for(i=1;i<5;i++)
446            {
447                Coefs[i-1]=LVREV_GainPolyTable[Index][i];
448            }
449            Coefs[4]=0;
450
451            Gain2=LVM_Polynomial(3,Coefs,T60);      /* Q.24 result */
452
453            /* Linear Interpolate the gain */
454            Gain = Gain1+ (((Gain2-Gain1)*Dist)/(Tot_Dist));
455        }
456
457
458        /*
459         * Get the inverse of gain: Q.15
460         * Gain is mostly above one except few cases, take only gains above 1
461         */
462        if(Gain < 16777216L)
463        {
464            pPrivate->Gain= 32767;
465        }
466        else
467        {
468            pPrivate->Gain=(LVM_INT16)(LVM_MAXINT_32/(Gain>>8));
469        }
470
471
472        Index=((32767*100)/(100+pPrivate->NewParams.Level));
473        pPrivate->Gain=(LVM_INT16)((pPrivate->Gain*Index)>>15);
474        pPrivate->GainMixer.Target = pPrivate->Gain*Index;
475    }
476
477
478    /*
479     * Update the all pass comb filter coefficient
480     */
481    if( (pPrivate->NewParams.Density != pPrivate->CurrentParams.Density) ||
482        (pPrivate->bFirstControl     == LVM_TRUE))
483    {
484        LVM_INT16   i;
485        LVM_INT32   b = pPrivate->NewParams.Density * LVREV_B_8_on_1000;
486
487        for (i=0;i<4; i++)
488        {
489            pPrivate->Mixer_SGFeedback[i].Target    = b;
490            pPrivate->Mixer_SGFeedforward[i].Target = b;
491        }
492    }
493
494
495    /*
496     * Update the bypass mixer time constant
497     */
498    if((pPrivate->NewParams.SampleRate   != pPrivate->CurrentParams.SampleRate)   ||
499       (pPrivate->bFirstControl          == LVM_TRUE))
500    {
501        LVM_UINT16   NumChannels = 1;                       /* Assume MONO format */
502        LVM_INT32    Alpha;
503
504        Alpha = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_FEEDBACKMIXER_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), NumChannels);
505        pPrivate->FeedbackMixer[0].Alpha=Alpha;
506        pPrivate->FeedbackMixer[1].Alpha=Alpha;
507        pPrivate->FeedbackMixer[2].Alpha=Alpha;
508        pPrivate->FeedbackMixer[3].Alpha=Alpha;
509
510        NumChannels = 2;                                    /* Always stereo output */
511        pPrivate->BypassMixer.Alpha1 = (LVM_INT32)LVM_Mixer_TimeConstant(LVREV_BYPASSMIXER_TC, LVM_GetFsFromTable(pPrivate->NewParams.SampleRate), NumChannels);
512        pPrivate->BypassMixer.Alpha2 = pPrivate->BypassMixer.Alpha1;
513        pPrivate->GainMixer.Alpha    = pPrivate->BypassMixer.Alpha1;
514    }
515
516
517    /*
518     * Update the bypass mixer targets
519     */
520    if( (pPrivate->NewParams.Level != pPrivate->CurrentParams.Level) &&
521        (pPrivate->NewParams.OperatingMode == LVM_MODE_ON))
522    {
523        pPrivate->BypassMixer.Target2 = ((LVM_INT32)(pPrivate->NewParams.Level * 32767)/100)<<16;
524        pPrivate->BypassMixer.Target1 = 0x00000000;
525        if ((pPrivate->NewParams.Level == 0) && (pPrivate->bFirstControl == LVM_FALSE))
526        {
527            pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE;
528        }
529        if (pPrivate->NewParams.Level != 0)
530        {
531            pPrivate->bDisableReverb = LVM_FALSE;
532        }
533    }
534
535    if(pPrivate->NewParams.OperatingMode != pPrivate->CurrentParams.OperatingMode)
536    {
537        if(pPrivate->NewParams.OperatingMode == LVM_MODE_ON)
538        {
539            pPrivate->BypassMixer.Target2 = ((LVM_INT32)(pPrivate->NewParams.Level * 32767)/100)<<16;
540            pPrivate->BypassMixer.Target1 = 0x00000000;
541
542            pPrivate->BypassMixer.CallbackSet2 = LVM_FALSE;
543            OperatingMode                      = LVM_MODE_ON;
544            if (pPrivate->NewParams.Level == 0)
545            {
546                pPrivate->bDisableReverb = LVM_TRUE;
547            }
548            else
549            {
550                pPrivate->bDisableReverb = LVM_FALSE;
551            }
552        }
553        else if (pPrivate->bFirstControl == LVM_FALSE)
554        {
555            pPrivate->BypassMixer.Target2 = 0x00000000;
556            pPrivate->BypassMixer.Target1 = 0x00000000;
557            pPrivate->BypassMixer.CallbackSet2 = LVM_TRUE;
558            pPrivate->GainMixer.Target    = 0x03FFFFFF;
559            OperatingMode = LVM_MODE_ON;
560        }
561        else
562        {
563            OperatingMode = LVM_MODE_OFF;
564        }
565    }
566
567
568    /*
569     * If it is the first call to ApplyNew settings force the current to the target to begin immediate playback of the effect
570     */
571    if(pPrivate->bFirstControl == LVM_TRUE)
572    {
573        pPrivate->BypassMixer.Current1 = pPrivate->BypassMixer.Target1;
574        pPrivate->BypassMixer.Current2 = pPrivate->BypassMixer.Target2;
575    }
576
577
578    /*
579     * Copy the new parameters
580     */
581    pPrivate->CurrentParams = pPrivate->NewParams;
582    pPrivate->CurrentParams.OperatingMode = OperatingMode;
583
584
585    /*
586     * Update flag
587     */
588    if(pPrivate->bFirstControl == LVM_TRUE)
589    {
590        pPrivate->bFirstControl = LVM_FALSE;
591    }
592
593
594    return LVREV_SUCCESS;
595}
596
597
598/****************************************************************************************/
599/*                                                                                      */
600/* FUNCTION:                BypassMixer_Callback                                        */
601/*                                                                                      */
602/* DESCRIPTION:                                                                         */
603/*  Controls the On to Off operating mode transition                                    */
604/*                                                                                      */
605/* PARAMETERS:                                                                          */
606/*  pPrivate                Pointer to the instance private parameters                  */
607/*                                                                                      */
608/* RETURNS:                                                                             */
609/*  LVREV_Success           Succeeded                                                   */
610/*  LVREV_NULLADDRESS       When pPrivate is NULL                                       */
611/*                                                                                      */
612/* NOTES:                                                                               */
613/*                                                                                      */
614/****************************************************************************************/
615LVM_INT32 BypassMixer_Callback (void *pCallbackData,
616                                void *pGeneralPurpose,
617                                LVM_INT16 GeneralPurpose )
618{
619
620    LVREV_Instance_st     *pLVREV_Private = (LVREV_Instance_st *)pCallbackData;
621
622
623    /*
624     * Avoid build warnings
625     */
626    (void)pGeneralPurpose;
627    (void)GeneralPurpose;
628
629
630    /*
631     * Turn off
632     */
633    pLVREV_Private->CurrentParams.OperatingMode = LVM_MODE_OFF;
634    pLVREV_Private->bDisableReverb              = LVM_TRUE;
635    LVREV_ClearAudioBuffers((LVREV_Handle_t)pCallbackData);
636
637
638    return 0;
639}
640
641/* End of file */
642
643