• 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 "LVDBE.h"
25 #include "LVDBE_Private.h"
26 #include "VectorArithmetic.h"
27 #include "AGC.h"
28 #include "LVDBE_Coeffs.h"               /* Filter coefficients */
29 
30 /********************************************************************************************/
31 /*                                                                                          */
32 /* FUNCTION:                 LVDBE_Process                                                  */
33 /*                                                                                          */
34 /* DESCRIPTION:                                                                             */
35 /*  Process function for the Bass Enhancement module.                                       */
36 /*                                                                                          */
37 /*  Data can be processed in two formats, stereo or mono-in-stereo. Data in mono            */
38 /*  format is not supported, the calling routine must convert the mono stream to            */
39 /*  mono-in-stereo.                                                                         */
40 /*                                                        ___________                       */
41 /*       ________                                        |           |    ________          */
42 /*      |        |    _____   |------------------------->|           |   |        |         */
43 /*      | 16-bit |   |     |  |    ________              |           |   | 32-bit |         */
44 /* -+-->|   to   |-->| HPF |--|   |        |    _____    | AGC Mixer |-->|   to   |--|      */
45 /*  |   | 32-bit |   |_____|  |   | Stereo |   |     |   |           |   | 16-bit |  |      */
46 /*  |   |________|            |-->|   to   |-->| BPF |-->|           |   |________|  0      */
47 /*  |                             |  Mono  |   |_____|   |___________|                \-->  */
48 /*  |                             |________|                                                */
49 /*  |                                                     _________                  0      */
50 /*  |                                                    |         |                 |      */
51 /*  |----------------------------------------------------| Volume  |-----------------|      */
52 /*                                                       | Control |                        */
53 /*                                                       |_________|                        */
54 /*                                                                                          */
55 /* PARAMETERS:                                                                              */
56 /*  hInstance                 Instance handle                                               */
57 /*  pInData                  Pointer to the input data                                      */
58 /*  pOutData                 Pointer to the output data                                     */
59 /*  NumSamples                 Number of samples in the input buffer                        */
60 /*                                                                                          */
61 /* RETURNS:                                                                                 */
62 /*  LVDBE_SUCCESS            Succeeded                                                      */
63 /*    LVDBE_TOOMANYSAMPLES    NumSamples was larger than the maximum block size             */
64 /*                                                                                          */
65 /* NOTES:                                                                                   */
66 /*  1. The input and output data must be 32-bit format. The input is scaled by a shift      */
67 /*     when converting from 16-bit format, this scaling allows for internal headroom in the */
68 /*     bass enhancement algorithm.                                                          */
69 /*  2. For a 16-bit implementation the converstion to 32-bit is removed and replaced with   */
70 /*     the headroom loss. This headroom loss is compensated in the volume control so the    */
71 /*     overall end to end gain is odB.                                                      */
72 /*                                                                                          */
73 /********************************************************************************************/
74 #ifndef BUILD_FLOAT
LVDBE_Process(LVDBE_Handle_t hInstance,const LVM_INT16 * pInData,LVM_INT16 * pOutData,LVM_UINT16 NumSamples)75 LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance,
76     const LVM_INT16 *pInData, LVM_INT16 *pOutData, LVM_UINT16 NumSamples) {
77 
78   LVDBE_Instance_t *pInstance = (LVDBE_Instance_t *) hInstance;
79   LVM_INT32 *pScratch =
80       (LVM_INT32 *) pInstance->MemoryTable.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress;
81   LVM_INT32 *pMono;
82   LVM_INT16 *pInput = (LVM_INT16 *) pInData;
83 
84   /* Scratch for Volume Control starts at offset of 2*NumSamples short values from pScratch */
85   LVM_INT16 *pScratchVol = (LVM_INT16 *) (&pScratch[NumSamples]);
86 
87   /* Scratch for Mono path starts at offset of 2*NumSamples 32-bit values from pScratch */
88   pMono = &pScratch[2 * NumSamples];
89 
90   /*
91    * Check the number of samples is not too large
92    */
93   if (NumSamples > pInstance->Capabilities.MaxBlockSize) {
94     return (LVDBE_TOOMANYSAMPLES);
95   }
96 
97   /*
98    * Check if the algorithm is enabled
99    */
100   /* DBE path is processed when DBE is ON or during On/Off transitions */
101   if ((pInstance->Params.OperatingMode == LVDBE_ON)
102       || (LVC_Mixer_GetCurrent(
103           &pInstance->pData->BypassMixer.MixerStream[0])
104           != LVC_Mixer_GetTarget(
105               &pInstance->pData->BypassMixer.MixerStream[0]))) {
106 
107     /*
108      * Convert 16-bit samples to 32-bit and scale
109      * (For a 16-bit implementation apply headroom loss here)
110      */
111     Int16LShiftToInt32_16x32(pInput, /* Source 16-bit data    */
112     pScratch, /* Dest. 32-bit data     */
113     (LVM_INT16) (2 * NumSamples), /* Left and right        */
114     LVDBE_SCALESHIFT); /* Shift scale           */
115 
116     /*
117      * Apply the high pass filter if selected
118      */
119     if (pInstance->Params.HPFSelect == LVDBE_HPF_ON) {
120       BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance      */
121       (LVM_INT32 *) pScratch, /* Source               */
122       (LVM_INT32 *) pScratch, /* Destination          */
123       (LVM_INT16) NumSamples); /* Number of samples    */
124     }
125 
126     /*
127      * Create the mono stream
128      */
129     From2iToMono_32(pScratch, /* Stereo source         */
130     pMono, /* Mono destination      */
131     (LVM_INT16) NumSamples); /* Number of samples     */
132 
133     /*
134      * Apply the band pass filter
135      */
136     BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance       */
137     (LVM_INT32 *) pMono, /* Source                */
138     (LVM_INT32 *) pMono, /* Destination           */
139     (LVM_INT16) NumSamples); /* Number of samples     */
140 
141     /*
142      * Apply the AGC and mix
143      */
144     AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer      */
145     pScratch, /* Stereo source         */
146     pMono, /* Mono band pass source */
147     pScratch, /* Stereo destination    */
148     NumSamples); /* Number of samples     */
149 
150     /*
151      * Convert 32-bit samples to 16-bit and saturate
152      * (Not required for 16-bit implemenations)
153      */
154     Int32RShiftToInt16_Sat_32x16(pScratch, /* Source 32-bit data    */
155     (LVM_INT16 *) pScratch, /* Dest. 16-bit data     */
156     (LVM_INT16) (2 * NumSamples), /* Left and right        */
157     LVDBE_SCALESHIFT); /* Shift scale           */
158 
159   }
160 
161   /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
162   if ((pInstance->Params.OperatingMode == LVDBE_OFF)
163       || (LVC_Mixer_GetCurrent(
164           &pInstance->pData->BypassMixer.MixerStream[1])
165           != LVC_Mixer_GetTarget(
166               &pInstance->pData->BypassMixer.MixerStream[1]))) {
167 
168     /*
169      * The algorithm is disabled but volume management is required to compensate for
170      * headroom and volume (if enabled)
171      */
172     LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume, pInData,
173         pScratchVol, (LVM_INT16) (2 * NumSamples)); /* Left and right          */
174 
175   }
176 
177   /*
178    * Mix DBE processed path and bypass volume path
179    */
180   LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
181       (LVM_INT16 *) pScratch, pScratchVol, pOutData,
182       (LVM_INT16) (2 * NumSamples));
183 
184   return (LVDBE_SUCCESS);
185 }
186 #else /*BUILD_FLOAT*/
LVDBE_Process(LVDBE_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT * pOutData,LVM_UINT16 NumSamples)187 LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance,
188     const LVM_FLOAT *pInData,
189     LVM_FLOAT *pOutData,
190     LVM_UINT16 NumSamples)
191 {
192 
193   LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance;
194   LVM_FLOAT *pScratch_in = (LVM_FLOAT *)pInstance->MemoryTable.Region
195   [LVDBE_MEMREGION_SCRATCH].pBaseAddress;
196   LVM_FLOAT *pScratch = pScratch_in + 2 * NumSamples;
197   LVM_FLOAT *pMono;
198   LVM_INT32 ii = 0;
199 
200   /* Scratch for Volume Control starts at offset of 4*NumSamples float values from pScratch */
201   LVM_FLOAT           *pScratchVol = (LVM_FLOAT *)(&pScratch_in[4 * NumSamples]);
202 //  LVM_INT16 *pScratchVol_int = (LVM_INT16 *)(pScratchVol);
203 
204   /* Scratch for Mono path starts at offset of 6*NumSamples 32-bit values from pScratch */
205   pMono = &pScratch_in[4 * NumSamples];
206 
207   /*
208    * Check the number of samples is not too large
209    */
210   if (NumSamples > pInstance->Capabilities.MaxBlockSize)
211   {
212     return(LVDBE_TOOMANYSAMPLES);
213   }
214 
215   /*
216    * Convert 16-bit samples to Float
217    */
218   Copy_Float(pInData, /* Source 16-bit data    */
219       pScratch_in, /* Dest. 32-bit data     */
220       (LVM_INT16)(2 * NumSamples)); /* Left and right        */
221 
222   for (ii = 0; ii < 2 * NumSamples; ii++) {
223     pScratch[ii] = pScratch_in[ii];
224   }
225   /*
226    * Check if the algorithm is enabled
227    */
228   /* DBE path is processed when DBE is ON or during On/Off transitions */
229   if ((pInstance->Params.OperatingMode == LVDBE_ON)||
230       (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[0])
231           !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[0])))
232   {
233 
234     /*
235      * Apply the high pass filter if selected
236      */
237     if (pInstance->Params.HPFSelect == LVDBE_HPF_ON)
238     {
239       BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance      */
240           (LVM_FLOAT *)pScratch, /* Source               */
241           (LVM_FLOAT *)pScratch, /* Destination          */
242           (LVM_INT16)NumSamples); /* Number of samples    */
243     }
244 
245     /*
246      * Create the mono stream
247      */
248     From2iToMono_Float((LVM_FLOAT *)pScratch, /* Stereo source         */
249         pMono, /* Mono destination      */
250         (LVM_INT16)NumSamples); /* Number of samples     */
251 
252     /*
253      * Apply the band pass filter
254      */
255     BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance       */
256         (LVM_FLOAT *)pMono, /* Source                */
257         (LVM_FLOAT *)pMono, /* Destination           */
258         (LVM_INT16)NumSamples); /* Number of samples     */
259 
260     /*
261      * Apply the AGC and mix
262      */
263     AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer      */
264         pScratch, /* Stereo source         */
265         pMono, /* Mono band pass source */
266         pScratch, /* Stereo destination    */
267         NumSamples); /* Number of samples     */
268 
269     for (ii = 0; ii < 2 * NumSamples; ii++) {
270       //TODO: replace with existing clamping function
271       if(pScratch[ii] < -1.0) {
272         pScratch[ii] = -1.0;
273       } else if(pScratch[ii] > 1.0) {
274         pScratch[ii] = 1.0;
275       }
276     }
277   }
278 
279   /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */
280   if ((pInstance->Params.OperatingMode == LVDBE_OFF)||
281       (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[1])
282           !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[1])))
283   {
284 
285     /*
286      * The algorithm is disabled but volume management is required to compensate for
287      * headroom and volume (if enabled)
288      */
289     LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume,
290         pScratch_in,
291         pScratchVol,
292         (LVM_INT16)(2 * NumSamples)); /* Left and right */
293   }
294 
295   /*
296    * Mix DBE processed path and bypass volume path
297    */
298   LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer,
299       pScratch,
300       pScratchVol,
301       pOutData,
302       (LVM_INT16)(2 * NumSamples));
303 
304   return(LVDBE_SUCCESS);
305 }
306 #endif
307