LVDBE_Control.c revision 2c8e5cab3faa6d360e222b7a6c40a80083d021ac
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     $Author: nxp007753 $
21     $Revision: 1223 $
22     $Date: 2010-07-15 14:27:01 +0200 (Thu, 15 Jul 2010) $
23
24*****************************************************************************************/
25
26/****************************************************************************************/
27/*                                                                                      */
28/*    Includes                                                                          */
29/*                                                                                      */
30/****************************************************************************************/
31
32#include "LVDBE.h"
33#include "LVDBE_Private.h"
34#include "VectorArithmetic.h"
35#include "LVDBE_Coeffs.h"
36#include "LVDBE_Tables.h"
37
38/****************************************************************************************/
39/*                                                                                      */
40/* FUNCTION:                  LVDBE_GetParameters                                       */
41/*                                                                                      */
42/* DESCRIPTION:                                                                         */
43/*    Request the Dynamic Bass Enhancement parameters. The current parameter set is     */
44/*  returned via the parameter pointer.                                                 */
45/*                                                                                      */
46/* PARAMETERS:                                                                          */
47/*  hInstance                   Instance handle                                         */
48/*  pParams                  Pointer to an empty parameter structure                    */
49/*                                                                                      */
50/* RETURNS:                                                                             */
51/*  LVDBE_SUCCESS            Always succeeds                                            */
52/*                                                                                      */
53/* NOTES:                                                                               */
54/*  1.    This function may be interrupted by the LVDBE_Process function                */
55/*                                                                                      */
56/****************************************************************************************/
57
58LVDBE_ReturnStatus_en LVDBE_GetParameters(LVDBE_Handle_t        hInstance,
59                                            LVDBE_Params_t        *pParams)
60{
61
62    LVDBE_Instance_t    *pInstance =(LVDBE_Instance_t  *)hInstance;
63
64    *pParams = pInstance->Params;
65
66    return(LVDBE_SUCCESS);
67}
68
69
70/************************************************************************************/
71/*                                                                                  */
72/* FUNCTION:                  LVDBE_GetCapabilities                                 */
73/*                                                                                  */
74/* DESCRIPTION: Dynamic Bass Enhnacement capabilities. The current capabilities are */
75/* returned via the pointer.                                                        */
76/*                                                                                  */
77/* PARAMETERS:                                                                      */
78/*  hInstance                   Instance handle                                     */
79/*  pCapabilities              Pointer to an empty capability structure             */
80/*                                                                                  */
81/* RETURNS:                                                                         */
82/*  LVDBE_Success             Always succeeds                                       */
83/*                                                                                  */
84/* NOTES:                                                                           */
85/*  1.    This function may be interrupted by the LVDBE_Process function            */
86/*                                                                                  */
87/************************************************************************************/
88
89LVDBE_ReturnStatus_en LVDBE_GetCapabilities(LVDBE_Handle_t            hInstance,
90                                              LVDBE_Capabilities_t    *pCapabilities)
91{
92
93    LVDBE_Instance_t    *pInstance =(LVDBE_Instance_t  *)hInstance;
94
95    *pCapabilities = pInstance->Capabilities;
96
97    return(LVDBE_SUCCESS);
98}
99
100
101/************************************************************************************/
102/*                                                                                  */
103/* FUNCTION:            LVDBE_SetFilters                                            */
104/*                                                                                  */
105/* DESCRIPTION:                                                                     */
106/*  Sets the filter coefficients and clears the data history                        */
107/*                                                                                  */
108/* PARAMETERS:                                                                      */
109/*  pInstance           Pointer to the instance                                     */
110/*  pParams             Initialisation parameters                                   */
111/*                                                                                  */
112/************************************************************************************/
113
114void    LVDBE_SetFilters(LVDBE_Instance_t     *pInstance,
115                         LVDBE_Params_t       *pParams)
116{
117
118    /*
119     * Calculate the table offsets
120     */
121    LVM_UINT16 Offset = (LVM_UINT16)((LVM_UINT16)pParams->SampleRate + (LVM_UINT16)(pParams->CentreFrequency * (1+LVDBE_FS_48000)));
122
123
124    /*
125     * Setup the high pass filter
126     */
127    LoadConst_16(0,                                                         /* Clear the history, value 0 */
128                 (LVM_INT16 *)&pInstance->pData->HPFTaps,                   /* Destination */
129                 sizeof(pInstance->pData->HPFTaps)/sizeof(LVM_INT16));      /* Number of words */
130    BQ_2I_D32F32Cll_TRC_WRA_01_Init(&pInstance->pCoef->HPFInstance,         /* Initialise the filter */
131                                    &pInstance->pData->HPFTaps,
132                                    (BQ_C32_Coefs_t *)&LVDBE_HPF_Table[Offset]);
133
134
135    /*
136     * Setup the band pass filter
137     */
138    LoadConst_16(0,                                                         /* Clear the history, value 0 */
139                 (LVM_INT16 *)&pInstance->pData->BPFTaps,                   /* Destination */
140                 sizeof(pInstance->pData->BPFTaps)/sizeof(LVM_INT16));      /* Number of words */
141    BP_1I_D32F32Cll_TRC_WRA_02_Init(&pInstance->pCoef->BPFInstance,         /* Initialise the filter */
142                                    &pInstance->pData->BPFTaps,
143                                    (BP_C32_Coefs_t *)&LVDBE_BPF_Table[Offset]);
144
145}
146
147
148
149/************************************************************************************/
150/*                                                                                  */
151/* FUNCTION:            LVDBE_SetAGC                                                */
152/*                                                                                  */
153/* DESCRIPTION:                                                                     */
154/*  Sets the AGC gain level and attack and decay times constants.                   */
155/*                                                                                  */
156/* PARAMETERS:                                                                      */
157/*  pInstance           Pointer to the instance                                     */
158/*  pParams             Initialisation parameters                                   */
159/*                                                                                  */
160/************************************************************************************/
161
162void    LVDBE_SetAGC(LVDBE_Instance_t     *pInstance,
163                     LVDBE_Params_t       *pParams)
164{
165
166    /*
167     * Get the attack and decay time constants
168     */
169    pInstance->pData->AGCInstance.AGC_Attack = LVDBE_AGC_ATTACK_Table[(LVM_UINT16)pParams->SampleRate];  /* Attack multiplier */
170    pInstance->pData->AGCInstance.AGC_Decay  = LVDBE_AGC_DECAY_Table[(LVM_UINT16)pParams->SampleRate];   /* Decay multipler */
171
172
173    /*
174     * Get the boost gain
175     */
176    if (pParams->HPFSelect == LVDBE_HPF_ON)
177    {
178        pInstance->pData->AGCInstance.AGC_MaxGain   = LVDBE_AGC_HPFGAIN_Table[(LVM_UINT16)pParams->EffectLevel];  /* High pass filter on */
179    }
180    else
181    {
182        pInstance->pData->AGCInstance.AGC_MaxGain   = LVDBE_AGC_GAIN_Table[(LVM_UINT16)pParams->EffectLevel];     /* High pass filter off */
183    }
184    pInstance->pData->AGCInstance.AGC_GainShift = AGC_GAIN_SHIFT;
185    pInstance->pData->AGCInstance.AGC_Target = AGC_TARGETLEVEL;
186
187}
188
189
190/************************************************************************************/
191/*                                                                                  */
192/* FUNCTION:            LVDBE_SetVolume                                             */
193/*                                                                                  */
194/* DESCRIPTION:                                                                     */
195/*  Converts the input volume demand from dBs to linear.                            */
196/*                                                                                  */
197/* PARAMETERS:                                                                      */
198/*  pInstance           Pointer to the instance                                     */
199/*  pParams             Initialisation parameters                                   */
200/*                                                                                  */
201/* NOTES:                                                                           */
202/*  1. The volume should have the following settings:                               */
203/*                                                                                  */
204/*          DBE         Vol Control           Volume setting                        */
205/*          ===         ===========         ===================                     */
206/*          Off             Off                 HeadroomdB                          */
207/*          Off             On              VolumedB+HeadroomdB                     */
208/*          On              Off                 HeadroomdB                          */
209/*          On              On              VolumedB+HeadroomdB                     */
210/*                                                                                  */
211/************************************************************************************/
212
213void    LVDBE_SetVolume(LVDBE_Instance_t     *pInstance,
214                        LVDBE_Params_t       *pParams)
215{
216
217    LVM_UINT16      dBShifts;                                   /* 6dB shifts */
218    LVM_UINT16      dBOffset;                                   /* Table offset */
219    LVM_INT16       Volume = 0;                                 /* Required volume in dBs */
220
221    /*
222     * Apply the volume if enabled
223     */
224    if (pParams->VolumeControl == LVDBE_VOLUME_ON)
225    {
226        /*
227         * Limit the gain to the maximum allowed
228         */
229        if  (pParams->VolumedB > VOLUME_MAX)
230        {
231            Volume = VOLUME_MAX;
232        }
233        else
234        {
235            Volume = pParams->VolumedB;
236        }
237    }
238
239
240    /*
241     * Calculate the required gain and shifts
242     */
243    dBOffset = (LVM_UINT16)(6 + Volume % 6);                    /* Get the dBs 0-5 */
244    dBShifts = (LVM_UINT16)(Volume / -6);                       /* Get the 6dB shifts */
245
246
247    /*
248     * When DBE is enabled use AGC volume
249     */
250    pInstance->pData->AGCInstance.Target = ((LVM_INT32)LVDBE_VolumeTable[dBOffset] << 16);
251    pInstance->pData->AGCInstance.Target = pInstance->pData->AGCInstance.Target >> dBShifts;
252
253    pInstance->pData->AGCInstance.VolumeTC    = LVDBE_VolumeTCTable[(LVM_UINT16)pParams->SampleRate];   /* Volume update time constant */
254    pInstance->pData->AGCInstance.VolumeShift = VOLUME_SHIFT+1;
255
256    /*
257     * When DBE is disabled use the bypass volume control
258     */
259    if(dBShifts > 0)
260    {
261        LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],(((LVM_INT32)LVDBE_VolumeTable[dBOffset]) >> dBShifts));
262    }
263    else
264    {
265        LVC_Mixer_SetTarget(&pInstance->pData->BypassVolume.MixerStream[0],(LVM_INT32)LVDBE_VolumeTable[dBOffset]);
266    }
267
268    pInstance->pData->BypassVolume.MixerStream[0].CallbackSet = 1;
269    LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->pData->BypassVolume.MixerStream[0],
270                                LVDBE_MIXER_TC,
271                                (LVM_Fs_en)pInstance->Params.SampleRate,
272                                2);
273}
274
275
276/****************************************************************************************/
277/*                                                                                      */
278/* FUNCTION:                LVDBE_Control                                               */
279/*                                                                                      */
280/* DESCRIPTION:                                                                         */
281/*  Sets or changes the Bass Enhancement parameters. Changing the parameters while the  */
282/*  module is processing signals may have the following side effects:                   */
283/*                                                                                      */
284/*  General parameters:                                                                 */
285/*  ===================                                                                 */
286/*  OperatingMode:      Changing the mode of operation may cause a change in volume     */
287/*                      level or cause pops and clicks.                                 */
288/*                                                                                      */
289/*  SampleRate:         Changing the sample rate may cause pops and clicks.             */
290/*                                                                                      */
291/*  EffectLevel:        Changing the effect level may cause pops and clicks             */
292/*                                                                                      */
293/*  CentreFrequency:    Changing the centre frequency may cause pops and clicks         */
294/*                                                                                      */
295/*  HPFSelect:          Selecting/de-selecting the high pass filter may cause pops and  */
296/*                      clicks                                                          */
297/*                                                                                      */
298/*  VolumedB            Changing the volume setting will have no side effects           */
299/*                                                                                      */
300/*                                                                                      */
301/* PARAMETERS:                                                                          */
302/*  hInstance               Instance handle                                             */
303/*  pParams                 Pointer to a parameter structure                            */
304/*                                                                                      */
305/* RETURNS:                                                                             */
306/*  LVDBE_SUCCESS           Always succeeds                                             */
307/*                                                                                      */
308/* NOTES:                                                                               */
309/*  1.  This function must not be interrupted by the LVDBE_Process function             */
310/*                                                                                      */
311/****************************************************************************************/
312
313LVDBE_ReturnStatus_en LVDBE_Control(LVDBE_Handle_t         hInstance,
314                                      LVDBE_Params_t         *pParams)
315{
316
317    LVDBE_Instance_t    *pInstance =(LVDBE_Instance_t  *)hInstance;
318
319
320    /*
321     * Update the filters
322     */
323    if ((pInstance->Params.SampleRate != pParams->SampleRate) ||
324        (pInstance->Params.CentreFrequency != pParams->CentreFrequency))
325    {
326        LVDBE_SetFilters(pInstance,                     /* Instance pointer */
327                         pParams);                      /* New parameters */
328    }
329
330
331    /*
332     * Update the AGC is the effect level has changed
333     */
334    if ((pInstance->Params.SampleRate != pParams->SampleRate) ||
335        (pInstance->Params.EffectLevel != pParams->EffectLevel) ||
336        (pInstance->Params.HPFSelect != pParams->HPFSelect))
337    {
338        LVDBE_SetAGC(pInstance,                         /* Instance pointer */
339                     pParams);                          /* New parameters */
340    }
341
342
343    /*
344     * Update the Volume if the volume demand has changed
345     */
346    if ((pInstance->Params.VolumedB != pParams->VolumedB) ||
347        (pInstance->Params.SampleRate != pParams->SampleRate) ||
348        (pInstance->Params.HeadroomdB != pParams->HeadroomdB) ||
349        (pInstance->Params.VolumeControl != pParams->VolumeControl))
350    {
351        LVDBE_SetVolume(pInstance,                      /* Instance pointer */
352                       pParams);                        /* New parameters */
353    }
354
355    if (pInstance->Params.OperatingMode==LVDBE_ON && pParams->OperatingMode==LVDBE_OFF)
356    {
357        LVDBE_Params_t  Params  = *pParams;             /* make local copy of params */
358        Params.EffectLevel      = 0;                    /* zero effect level before switching off module*/
359        pInstance->bTransitionOnToOff  = LVM_TRUE;             /* Set the CallBack */
360        LVDBE_SetAGC(pInstance,                         /* Instance pointer */
361                     &Params);                          /* New parameters */
362    }
363    if (pInstance->Params.OperatingMode==LVDBE_OFF && pParams->OperatingMode==LVDBE_ON)
364    {
365        pInstance->bTransitionOnToOff  = LVM_FALSE;     /* Set the CallBack */
366        LVDBE_SetAGC(pInstance,                         /* Instance pointer */
367                     pParams);                          /* New parameters */
368    }
369
370    /*
371     * Update the instance parameters
372     */
373    pInstance->Params = *pParams;
374
375
376    return(LVDBE_SUCCESS);
377}
378