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 
LVEQNB_Process(LVEQNB_Handle_t hInstance,const LVM_INT16 * pInData,LVM_INT16 * pOutData,LVM_UINT16 NumSamples)61 LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t       hInstance,
62                                       const LVM_INT16       *pInData,
63                                       LVM_INT16             *pOutData,
64                                       LVM_UINT16            NumSamples)
65 {
66 
67     LVM_UINT16          i;
68     Biquad_Instance_t   *pBiquad;
69     LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t  *)hInstance;
70     LVM_INT32           *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_INT32 *)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          * Convert from 16-bit to 32-bit
99          */
100         Int16LShiftToInt32_16x32((LVM_INT16 *)pInData,      /* Source */
101                                  pScratch,                  /* Destination */
102                                  (LVM_INT16)(2*NumSamples), /* Left and Right */
103                                  SHIFT);                    /* Scaling shift */
104 
105         /*
106          * For each section execte the filter unless the gain is 0dB
107          */
108         if (pInstance->NBands != 0)
109         {
110             for (i=0; i<pInstance->NBands; i++)
111             {
112                 /*
113                  * Check if band is non-zero dB gain
114                  */
115                 if (pInstance->pBandDefinitions[i].Gain != 0)
116                 {
117                     /*
118                      * Get the address of the biquad instance
119                      */
120                     pBiquad = &pInstance->pEQNB_FilterState[i];
121 
122 
123                     /*
124                      * Select single or double precision as required
125                      */
126                     switch (pInstance->pBiquadType[i])
127                     {
128                         case LVEQNB_SinglePrecision:
129                         {
130                             PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
131                                                           (LVM_INT32 *)pScratch,
132                                                           (LVM_INT32 *)pScratch,
133                                                           (LVM_INT16)NumSamples);
134                             break;
135                         }
136 
137                         case LVEQNB_DoublePrecision:
138                         {
139                             PK_2I_D32F32C30G11_TRC_WRA_01(pBiquad,
140                                                           (LVM_INT32 *)pScratch,
141                                                           (LVM_INT32 *)pScratch,
142                                                           (LVM_INT16)NumSamples);
143                             break;
144                         }
145                         default:
146                             break;
147                     }
148                 }
149             }
150         }
151 
152 
153         if(pInstance->bInOperatingModeTransition == LVM_TRUE){
154                 /*
155                  * Convert from 32-bit to 16- bit and saturate
156                  */
157                 Int32RShiftToInt16_Sat_32x16(pScratch,                      /* Source */
158                                              (LVM_INT16 *)pScratch,         /* Destination */
159                                              (LVM_INT16)(2*NumSamples),     /* Left and Right */
160                                              SHIFT);                        /* Scaling shift */
161 
162                 LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
163                                                 (LVM_INT16 *)pScratch,
164                                                 (LVM_INT16 *)pInData,
165                                                 (LVM_INT16 *)pScratch,
166                                                 (LVM_INT16)(2*NumSamples));
167 
168                 Copy_16((LVM_INT16*)pScratch,                           /* Source */
169                         pOutData,                                       /* Destination */
170                         (LVM_INT16)(2*NumSamples));                     /* Left and Right samples */
171         }
172         else{
173 
174             /*
175              * Convert from 32-bit to 16- bit and saturate
176              */
177             Int32RShiftToInt16_Sat_32x16(pScratch,              /* Source */
178                                          pOutData,              /* Destination */
179                                          (LVM_INT16 )(2*NumSamples), /* Left and Right */
180                                          SHIFT);                /* Scaling shift */
181         }
182     }
183     else
184     {
185         /*
186          * Mode is OFF so copy the data if necessary
187          */
188         if (pInData != pOutData)
189         {
190             Copy_16(pInData,                                    /* Source */
191                     pOutData,                                   /* Destination */
192                     (LVM_INT16)(2*NumSamples));                 /* Left and Right samples */
193         }
194     }
195 
196 
197 
198     return(LVEQNB_SUCCESS);
199 
200 }
201