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