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 /*                                                                                      */
21 /*  Includes                                                                            */
22 /*                                                                                      */
23 /****************************************************************************************/
24 
25 #include "LVM_Private.h"
26 #include "VectorArithmetic.h"
27 #include "LVM_Coeffs.h"
28 
29 /****************************************************************************************/
30 /*                                                                                      */
31 /* FUNCTION:                LVM_Process                                                 */
32 /*                                                                                      */
33 /* DESCRIPTION:                                                                         */
34 /*  Process function for the LifeVibes module.                                          */
35 /*                                                                                      */
36 /* PARAMETERS:                                                                          */
37 /*  hInstance               Instance handle                                             */
38 /*  pInData                 Pointer to the input data                                   */
39 /*  pOutData                Pointer to the output data                                  */
40 /*  NumSamples              Number of samples in the input buffer                       */
41 /*  AudioTime               Audio Time of the current input buffer in ms                */
42 /*                                                                                      */
43 /* RETURNS:                                                                             */
44 /*  LVM_SUCCESS            Succeeded                                                    */
45 /*  LVM_INVALIDNUMSAMPLES  When the NumSamples is not a valied multiple in unmanaged    */
46 /*                         buffer mode                                                  */
47 /*  LVM_ALIGNMENTERROR     When either the input our output buffers are not 32-bit      */
48 /*                         aligned in unmanaged mode                                    */
49 /*  LVM_NULLADDRESS        When one of hInstance, pInData or pOutData is NULL           */
50 /*                                                                                      */
51 /* NOTES:                                                                               */
52 /*                                                                                      */
53 /****************************************************************************************/
54 
LVM_Process(LVM_Handle_t hInstance,const LVM_INT16 * pInData,LVM_INT16 * pOutData,LVM_UINT16 NumSamples,LVM_UINT32 AudioTime)55 LVM_ReturnStatus_en LVM_Process(LVM_Handle_t                hInstance,
56                                 const LVM_INT16             *pInData,
57                                 LVM_INT16                   *pOutData,
58                                 LVM_UINT16                  NumSamples,
59                                 LVM_UINT32                  AudioTime)
60 {
61 
62     LVM_Instance_t      *pInstance  = (LVM_Instance_t  *)hInstance;
63     LVM_UINT16          SampleCount = NumSamples;
64     LVM_INT16           *pInput     = (LVM_INT16 *)pInData;
65     LVM_INT16           *pToProcess = (LVM_INT16 *)pInData;
66     LVM_INT16           *pProcessed = pOutData;
67     LVM_ReturnStatus_en  Status;
68 
69     /*
70      * Check if the number of samples is zero
71      */
72     if (NumSamples == 0)
73     {
74         return(LVM_SUCCESS);
75     }
76 
77 
78     /*
79      * Check valid points have been given
80      */
81     if ((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
82     {
83         return (LVM_NULLADDRESS);
84     }
85 
86     /*
87      * For unmanaged mode only
88      */
89     if(pInstance->InstParams.BufferMode == LVM_UNMANAGED_BUFFERS)
90     {
91          /*
92          * Check if the number of samples is a good multiple (unmanaged mode only)
93          */
94         if((NumSamples % pInstance->BlickSizeMultiple) != 0)
95         {
96             return(LVM_INVALIDNUMSAMPLES);
97         }
98 
99         /*
100          * Check the buffer alignment
101          */
102         if((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
103         {
104             return(LVM_ALIGNMENTERROR);
105         }
106     }
107 
108 
109     /*
110      * Update new parameters if necessary
111      */
112     if (pInstance->ControlPending == LVM_TRUE)
113     {
114         Status = LVM_ApplyNewSettings(hInstance);
115 
116         if(Status != LVM_SUCCESS)
117         {
118             return Status;
119         }
120     }
121 
122 
123     /*
124      * Convert from Mono if necessary
125      */
126     if (pInstance->Params.SourceFormat == LVM_MONO)
127     {
128         MonoTo2I_16(pInData,                                /* Source */
129                     pOutData,                               /* Destination */
130                     (LVM_INT16)NumSamples);                 /* Number of input samples */
131         pInput     = pOutData;
132         pToProcess = pOutData;
133     }
134 
135 
136     /*
137      * Process the data with managed buffers
138      */
139     while (SampleCount != 0)
140     {
141         /*
142          * Manage the input buffer and frame processing
143          */
144         LVM_BufferIn(hInstance,
145                      pInput,
146                      &pToProcess,
147                      &pProcessed,
148                      &SampleCount);
149 
150         /*
151          * Only process data when SampleCount is none zero, a zero count can occur when
152          * the BufferIn routine is working in managed mode.
153          */
154         if (SampleCount != 0)
155         {
156 
157             /*
158              * Apply ConcertSound if required
159              */
160             if (pInstance->CS_Active == LVM_TRUE)
161             {
162                 (void)LVCS_Process(pInstance->hCSInstance,          /* Concert Sound instance handle */
163                                    pToProcess,
164                                    pProcessed,
165                                    SampleCount);
166                 pToProcess = pProcessed;
167             }
168 
169             /*
170              * Apply volume if required
171              */
172             if (pInstance->VC_Active!=0)
173             {
174                 LVC_MixSoft_1St_D16C31_SAT(&pInstance->VC_Volume,
175                                        pToProcess,
176                                        pProcessed,
177                                        (LVM_INT16)(2*SampleCount));     /* Left and right*/
178                 pToProcess = pProcessed;
179             }
180 
181             /*
182              * Call N-Band equaliser if enabled
183              */
184             if (pInstance->EQNB_Active == LVM_TRUE)
185             {
186                 LVEQNB_Process(pInstance->hEQNBInstance,        /* N-Band equaliser instance handle */
187                                pToProcess,
188                                pProcessed,
189                                SampleCount);
190                 pToProcess = pProcessed;
191             }
192 
193             /*
194              * Call bass enhancement if enabled
195              */
196             if (pInstance->DBE_Active == LVM_TRUE)
197             {
198                 LVDBE_Process(pInstance->hDBEInstance,          /* Dynamic Bass Enhancement instance handle */
199                               pToProcess,
200                               pProcessed,
201                               SampleCount);
202                 pToProcess = pProcessed;
203             }
204 
205             /*
206              * Bypass mode or everything off, so copy the input to the output
207              */
208             if (pToProcess != pProcessed)
209             {
210                 Copy_16(pToProcess,                             /* Source */
211                         pProcessed,                             /* Destination */
212                         (LVM_INT16)(2*SampleCount));            /* Left and right */
213             }
214 
215             /*
216              * Apply treble boost if required
217              */
218             if (pInstance->TE_Active == LVM_TRUE)
219             {
220                 /*
221                  * Apply the filter
222                  */
223                 FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
224                                            pProcessed,
225                                            pProcessed,
226                                            (LVM_INT16)SampleCount);
227 
228             }
229 
230             /*
231              * Volume balance
232              */
233             LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix,
234                                             pProcessed,
235                                             pProcessed,
236                                             SampleCount);
237 
238             /*
239              * Perform Parametric Spectum Analysis
240              */
241             if ((pInstance->Params.PSA_Enable == LVM_PSA_ON)&&(pInstance->InstParams.PSA_Included==LVM_PSA_ON))
242             {
243                     From2iToMono_16(pProcessed,
244                              pInstance->pPSAInput,
245                             (LVM_INT16) (SampleCount));
246 
247                     LVPSA_Process(pInstance->hPSAInstance,
248                             pInstance->pPSAInput,
249                             (LVM_UINT16) (SampleCount),
250                             AudioTime);
251             }
252 
253 
254             /*
255              * DC removal
256              */
257             DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
258                                  pProcessed,
259                                  pProcessed,
260                                  (LVM_INT16)SampleCount);
261 
262 
263         }
264 
265         /*
266          * Manage the output buffer
267          */
268         LVM_BufferOut(hInstance,
269                       pOutData,
270                       &SampleCount);
271 
272     }
273 
274     return(LVM_SUCCESS);
275 }
276