• 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 "LVEQNB.h"
25 #include "LVEQNB_Private.h"
26 #include "VectorArithmetic.h"
27 #include "BIQUAD.h"
28 
29 
30 /****************************************************************************************/
31 /*                                                                                      */
32 /*  Defines                                                                             */
33 /*                                                                                      */
34 /****************************************************************************************/
35 
36 #define SHIFT       13
37 
38 /****************************************************************************************/
39 /*                                                                                      */
40 /* FUNCTION:                LVEQNB_Process                                              */
41 /*                                                                                      */
42 /* DESCRIPTION:                                                                         */
43 /*  Process function for the N-Band Equaliser module.                                   */
44 /*                                                                                      */
45 /* PARAMETERS:                                                                          */
46 /*  hInstance               Instance handle                                             */
47 /*  pInData                 Pointer to the input data                                   */
48 /*  pOutData                Pointer to the output data                                  */
49 /*  NumSamples              Number of samples in the input buffer                       */
50 /*                                                                                      */
51 /* RETURNS:                                                                             */
52 /*  LVEQNB_SUCCESS          Succeeded                                                   */
53 /*  LVEQNB_NULLADDRESS      When hInstance, pInData or pOutData are NULL                */
54 /*  LVEQNB_ALIGNMENTERROR   When pInData or pOutData are not 32-bit aligned             */
55 /*  LVEQNB_TOOMANYSAMPLES   NumSamples was larger than the maximum block size           */
56 /*                                                                                      */
57 /* NOTES:                                                                               */
58 /*                                                                                      */
59 /****************************************************************************************/
60 #ifdef BUILD_FLOAT
LVEQNB_Process(LVEQNB_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT * pOutData,LVM_UINT16 NumSamples)61 LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
62                                       const LVM_FLOAT       *pInData,
63                                       LVM_FLOAT             *pOutData,
64                                       LVM_UINT16            NumSamples)
65 {
66 
67     LVM_UINT16          i;
68     Biquad_FLOAT_Instance_t   *pBiquad;
69     LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t  *)hInstance;
70     LVM_FLOAT           *pScratch;
71 
72 
73      /* Check for NULL pointers */
74     if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
75     {
76         return LVEQNB_NULLADDRESS;
77     }
78 
79     /* Check if the input and output data buffers are 32-bit aligned */
80     if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
81     {
82         return LVEQNB_ALIGNMENTERROR;
83     }
84 
85     pScratch  = (LVM_FLOAT *)pInstance->pFastTemporary;
86 
87     /*
88     * Check the number of samples is not too large
89     */
90     if (NumSamples > pInstance->Capabilities.MaxBlockSize)
91     {
92         return(LVEQNB_TOOMANYSAMPLES);
93     }
94 
95     if (pInstance->Params.OperatingMode == LVEQNB_ON)
96     {
97         /*
98          * Copy input data in to scratch buffer
99          */
100 
101         Copy_Float((LVM_FLOAT *)pInData,      /* Source */
102                    pScratch,                  /* Destination */
103                    (LVM_INT16)(2 * NumSamples)); /* Left and Right */
104         /*
105          * For each section execte the filter unless the gain is 0dB
106          */
107         if (pInstance->NBands != 0)
108         {
109             for (i = 0; i < pInstance->NBands; i++)
110             {
111                 /*
112                  * Check if band is non-zero dB gain
113                  */
114                 if (pInstance->pBandDefinitions[i].Gain != 0)
115                 {
116                     /*
117                      * Get the address of the biquad instance
118                      */
119                     pBiquad = &pInstance->pEQNB_FilterState_Float[i];
120 
121 
122                     /*
123                      * Select single or double precision as required
124                      */
125                     switch (pInstance->pBiquadType[i])
126                     {
127                         case LVEQNB_SinglePrecision_Float:
128                         {
129                             PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
130                                                           (LVM_FLOAT *)pScratch,
131                                                           (LVM_FLOAT *)pScratch,
132                                                           (LVM_INT16)NumSamples);
133                             break;
134                         }
135                         default:
136                             break;
137                     }
138                 }
139             }
140         }
141 
142 
143         if(pInstance->bInOperatingModeTransition == LVM_TRUE){
144             LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
145                                        (LVM_FLOAT *)pScratch,
146                                        (LVM_FLOAT *)pInData,
147                                        (LVM_FLOAT *)pScratch,
148                                        (LVM_INT16)(2 * NumSamples));
149             Copy_Float((LVM_FLOAT*)pScratch,                           /* Source */
150                        pOutData,                                       /* Destination */
151                        (LVM_INT16)(2 * NumSamples));                     /* Left and Right samples */
152         }
153         else{
154             Copy_Float(pScratch,              /* Source */
155                        pOutData,              /* Destination */
156                        (LVM_INT16 )(2 * NumSamples)); /* Left and Right */
157         }
158     }
159     else
160     {
161         /*
162          * Mode is OFF so copy the data if necessary
163          */
164         if (pInData != pOutData)
165         {
166             Copy_Float(pInData,                                    /* Source */
167                        pOutData,                                   /* Destination */
168                        (LVM_INT16)(2 * NumSamples));                 /* Left and Right samples */
169         }
170     }
171     return(LVEQNB_SUCCESS);
172 
173 }
174 #else
LVEQNB_Process(LVEQNB_Handle_t hInstance,const LVM_INT16 * pInData,LVM_INT16 * pOutData,LVM_UINT16 NumSamples)175 LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
176                                       const LVM_INT16       *pInData,
177                                       LVM_INT16             *pOutData,
178                                       LVM_UINT16            NumSamples)
179 {
180 
181     LVM_UINT16          i;
182     Biquad_Instance_t   *pBiquad;
183     LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t  *)hInstance;
184     LVM_INT32           *pScratch;
185 
186 
187      /* Check for NULL pointers */
188     if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
189     {
190         return LVEQNB_NULLADDRESS;
191     }
192 
193     /* Check if the input and output data buffers are 32-bit aligned */
194     if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
195     {
196         return LVEQNB_ALIGNMENTERROR;
197     }
198 
199     pScratch  = (LVM_INT32 *)pInstance->pFastTemporary;
200 
201     /*
202     * Check the number of samples is not too large
203     */
204     if (NumSamples > pInstance->Capabilities.MaxBlockSize)
205     {
206         return(LVEQNB_TOOMANYSAMPLES);
207     }
208 
209     if (pInstance->Params.OperatingMode == LVEQNB_ON)
210     {
211         /*
212          * Convert from 16-bit to 32-bit
213          */
214         Int16LShiftToInt32_16x32((LVM_INT16 *)pInData,      /* Source */
215                                  pScratch,                  /* Destination */
216                                  (LVM_INT16)(2*NumSamples), /* Left and Right */
217                                  SHIFT);                    /* Scaling shift */
218 
219         /*
220          * For each section execte the filter unless the gain is 0dB
221          */
222         if (pInstance->NBands != 0)
223         {
224             for (i=0; i<pInstance->NBands; i++)
225             {
226                 /*
227                  * Check if band is non-zero dB gain
228                  */
229                 if (pInstance->pBandDefinitions[i].Gain != 0)
230                 {
231                     /*
232                      * Get the address of the biquad instance
233                      */
234                     pBiquad = &pInstance->pEQNB_FilterState[i];
235 
236 
237                     /*
238                      * Select single or double precision as required
239                      */
240                     switch (pInstance->pBiquadType[i])
241                     {
242                         case LVEQNB_SinglePrecision:
243                         {
244                             PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
245                                                           (LVM_INT32 *)pScratch,
246                                                           (LVM_INT32 *)pScratch,
247                                                           (LVM_INT16)NumSamples);
248                             break;
249                         }
250 
251                         case LVEQNB_DoublePrecision:
252                         {
253                             PK_2I_D32F32C30G11_TRC_WRA_01(pBiquad,
254                                                           (LVM_INT32 *)pScratch,
255                                                           (LVM_INT32 *)pScratch,
256                                                           (LVM_INT16)NumSamples);
257                             break;
258                         }
259                         default:
260                             break;
261                     }
262                 }
263             }
264         }
265 
266 
267         if(pInstance->bInOperatingModeTransition == LVM_TRUE){
268                 /*
269                  * Convert from 32-bit to 16- bit and saturate
270                  */
271                 Int32RShiftToInt16_Sat_32x16(pScratch,                      /* Source */
272                                              (LVM_INT16 *)pScratch,         /* Destination */
273                                              (LVM_INT16)(2*NumSamples),     /* Left and Right */
274                                              SHIFT);                        /* Scaling shift */
275 
276                 LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
277                                                 (LVM_INT16 *)pScratch,
278                                                 (LVM_INT16 *)pInData,
279                                                 (LVM_INT16 *)pScratch,
280                                                 (LVM_INT16)(2*NumSamples));
281 
282                 Copy_16((LVM_INT16*)pScratch,                           /* Source */
283                         pOutData,                                       /* Destination */
284                         (LVM_INT16)(2*NumSamples));                     /* Left and Right samples */
285         }
286         else{
287 
288             /*
289              * Convert from 32-bit to 16- bit and saturate
290              */
291             Int32RShiftToInt16_Sat_32x16(pScratch,              /* Source */
292                                          pOutData,              /* Destination */
293                                          (LVM_INT16 )(2*NumSamples), /* Left and Right */
294                                          SHIFT);                /* Scaling shift */
295         }
296     }
297     else
298     {
299         /*
300          * Mode is OFF so copy the data if necessary
301          */
302         if (pInData != pOutData)
303         {
304             Copy_16(pInData,                                    /* Source */
305                     pOutData,                                   /* Destination */
306                     (LVM_INT16)(2*NumSamples));                 /* Left and Right samples */
307         }
308     }
309 
310 
311 
312     return(LVEQNB_SUCCESS);
313 
314 }
315 #endif