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 #include <system/audio.h>
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 /****************************************************************************************/
LVM_Process(LVM_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT * pOutData,LVM_UINT16 NumSamples,LVM_UINT32 AudioTime)54 LVM_ReturnStatus_en LVM_Process(LVM_Handle_t                hInstance,
55                                 const LVM_FLOAT             *pInData,
56                                 LVM_FLOAT                   *pOutData,
57                                 LVM_UINT16                  NumSamples,
58                                 LVM_UINT32                  AudioTime)
59 {
60 
61     LVM_Instance_t      *pInstance  = (LVM_Instance_t  *)hInstance;
62     LVM_UINT16          SampleCount = NumSamples;
63     LVM_FLOAT           *pInput     = (LVM_FLOAT *)pInData;
64     LVM_FLOAT           *pToProcess = (LVM_FLOAT *)pInData;
65     LVM_FLOAT           *pProcessed = pOutData;
66     LVM_ReturnStatus_en  Status;
67 #ifdef SUPPORT_MC
68     LVM_INT32           NrChannels  = pInstance->NrChannels;
69     LVM_INT32           ChMask      = pInstance->ChMask;
70 #define NrFrames SampleCount  // alias for clarity
71 #endif
72 
73     /*
74      * Check if the number of samples is zero
75      */
76     if (NumSamples == 0)
77     {
78         return(LVM_SUCCESS);
79     }
80 
81     /*
82      * Check valid points have been given
83      */
84     if ((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
85     {
86         return (LVM_NULLADDRESS);
87     }
88 
89     /*
90      * For unmanaged mode only
91      */
92     if(pInstance->InstParams.BufferMode == LVM_UNMANAGED_BUFFERS)
93     {
94          /*
95          * Check if the number of samples is a good multiple (unmanaged mode only)
96          */
97         if((NumSamples % pInstance->BlickSizeMultiple) != 0)
98         {
99             return(LVM_INVALIDNUMSAMPLES);
100         }
101 
102         /*
103          * Check the buffer alignment
104          */
105         if((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
106         {
107             return(LVM_ALIGNMENTERROR);
108         }
109     }
110 
111     /*
112      * Update new parameters if necessary
113      */
114     if (pInstance->ControlPending == LVM_TRUE)
115     {
116         Status = LVM_ApplyNewSettings(hInstance);
117 #ifdef SUPPORT_MC
118         /* Update the local variable NrChannels from pInstance->NrChannels value */
119         NrChannels = pInstance->NrChannels;
120         ChMask     = pInstance->ChMask;
121 #endif
122 
123         if(Status != LVM_SUCCESS)
124         {
125             return Status;
126         }
127     }
128 
129     /*
130      * Convert from Mono if necessary
131      */
132     if (pInstance->Params.SourceFormat == LVM_MONO)
133     {
134         MonoTo2I_Float(pInData,                                /* Source */
135                        pOutData,                               /* Destination */
136                        (LVM_INT16)NumSamples);                 /* Number of input samples */
137         pInput     = pOutData;
138         pToProcess = pOutData;
139 #ifdef SUPPORT_MC
140         NrChannels = 2;
141         ChMask     = AUDIO_CHANNEL_OUT_STEREO;
142 #endif
143     }
144 
145     /*
146      * Process the data with managed buffers
147      */
148     while (SampleCount != 0)
149     {
150         /*
151          * Manage the input buffer and frame processing
152          */
153         LVM_BufferIn(hInstance,
154                      pInput,
155                      &pToProcess,
156                      &pProcessed,
157                      &SampleCount);
158 
159         /*
160          * Only process data when SampleCount is none zero, a zero count can occur when
161          * the BufferIn routine is working in managed mode.
162          */
163         if (SampleCount != 0)
164         {
165             /*
166              * Apply ConcertSound if required
167              */
168             if (pInstance->CS_Active == LVM_TRUE)
169             {
170                 (void)LVCS_Process(pInstance->hCSInstance,     /* Concert Sound instance handle */
171                                    pToProcess,
172                                    pProcessed,
173                                    SampleCount);
174                 pToProcess = pProcessed;
175             }
176 
177             /*
178              * Apply volume if required
179              */
180             if (pInstance->VC_Active!=0)
181             {
182 #ifdef SUPPORT_MC
183                 LVC_MixSoft_Mc_D16C31_SAT(&pInstance->VC_Volume,
184                                        pToProcess,
185                                        pProcessed,
186                                        (LVM_INT16)(NrFrames),
187                                        NrChannels);
188 #else
189                 LVC_MixSoft_1St_D16C31_SAT(&pInstance->VC_Volume,
190                                        pToProcess,
191                                        pProcessed,
192                                        (LVM_INT16)(2 * SampleCount));     /* Left and right*/
193 #endif
194                 pToProcess = pProcessed;
195             }
196 
197             /*
198              * Call N-Band equaliser if enabled
199              */
200             if (pInstance->EQNB_Active == LVM_TRUE)
201             {
202                 LVEQNB_Process(pInstance->hEQNBInstance,    /* N-Band equaliser instance handle */
203                                pToProcess,
204                                pProcessed,
205                                SampleCount);
206                 pToProcess = pProcessed;
207             }
208 
209             /*
210              * Call bass enhancement if enabled
211              */
212             if (pInstance->DBE_Active == LVM_TRUE)
213             {
214                 LVDBE_Process(pInstance->hDBEInstance,       /* Dynamic Bass Enhancement \
215                                                                 instance handle */
216                               pToProcess,
217                               pProcessed,
218                               SampleCount);
219                 pToProcess = pProcessed;
220             }
221 
222             /*
223              * Bypass mode or everything off, so copy the input to the output
224              */
225             if (pToProcess != pProcessed)
226             {
227 #ifdef SUPPORT_MC
228                 Copy_Float(pToProcess,                             /* Source */
229                            pProcessed,                             /* Destination */
230                            (LVM_INT16)(NrChannels * NrFrames));    /* Copy all samples */
231 #else
232                 Copy_Float(pToProcess,                             /* Source */
233                            pProcessed,                             /* Destination */
234                            (LVM_INT16)(2 * SampleCount));          /* Left and right */
235 #endif
236             }
237 
238             /*
239              * Apply treble boost if required
240              */
241             if (pInstance->TE_Active == LVM_TRUE)
242             {
243                 /*
244                  * Apply the filter
245                  */
246 #ifdef SUPPORT_MC
247                 FO_Mc_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
248                                            pProcessed,
249                                            pProcessed,
250                                            (LVM_INT16)NrFrames,
251                                            (LVM_INT16)NrChannels);
252 #else
253                 FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State,
254                                            pProcessed,
255                                            pProcessed,
256                                            (LVM_INT16)SampleCount);
257 #endif
258 
259             }
260 #ifdef SUPPORT_MC
261             /*
262              * Volume balance
263              */
264             LVC_MixSoft_1St_MC_float_SAT(&pInstance->VC_BalanceMix,
265                                           pProcessed,
266                                           pProcessed,
267                                           NrFrames,
268                                           NrChannels,
269                                           ChMask);
270 #else
271             /*
272              * Volume balance
273              */
274             LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix,
275                                           pProcessed,
276                                           pProcessed,
277                                           SampleCount);
278 #endif
279 
280             /*
281              * Perform Parametric Spectum Analysis
282              */
283             if ((pInstance->Params.PSA_Enable == LVM_PSA_ON) &&
284                                             (pInstance->InstParams.PSA_Included == LVM_PSA_ON))
285             {
286 #ifdef SUPPORT_MC
287                 FromMcToMono_Float(pProcessed,
288                                    pInstance->pPSAInput,
289                                    (LVM_INT16)(NrFrames),
290                                    NrChannels);
291 #else
292                 From2iToMono_Float(pProcessed,
293                                    pInstance->pPSAInput,
294                                    (LVM_INT16)(SampleCount));
295 #endif
296 
297                 LVPSA_Process(pInstance->hPSAInstance,
298                         pInstance->pPSAInput,
299                         (LVM_UINT16)(SampleCount),
300                         AudioTime);
301             }
302 
303             /*
304              * DC removal
305              */
306 #ifdef SUPPORT_MC
307             DC_Mc_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
308                                  pProcessed,
309                                  pProcessed,
310                                  (LVM_INT16)NrFrames,
311                                  NrChannels);
312 #else
313             DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance,
314                                  pProcessed,
315                                  pProcessed,
316                                  (LVM_INT16)SampleCount);
317 #endif
318         }
319         /*
320          * Manage the output buffer
321          */
322         LVM_BufferOut(hInstance,
323                       pOutData,
324                       &SampleCount);
325 
326     }
327 
328     return(LVM_SUCCESS);
329 }
330