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
55LVM_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