• 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 #include <system/audio.h>
24 
25 #include "LVM_Private.h"
26 #include "ScalarArithmetic.h"
27 #include "VectorArithmetic.h"
28 #include "LVM_Coeffs.h"
29 
30 /****************************************************************************************/
31 /*                                                                                      */
32 /* FUNCTION:                LVM_Process                                                 */
33 /*                                                                                      */
34 /* DESCRIPTION:                                                                         */
35 /*  Process function for the LifeVibes module.                                          */
36 /*                                                                                      */
37 /* PARAMETERS:                                                                          */
38 /*  hInstance               Instance handle                                             */
39 /*  pInData                 Pointer to the input data                                   */
40 /*  pOutData                Pointer to the output data                                  */
41 /*  NumSamples              Number of samples in the input buffer                       */
42 /*  AudioTime               Audio Time of the current input buffer in ms                */
43 /*                                                                                      */
44 /* RETURNS:                                                                             */
45 /*  LVM_SUCCESS            Succeeded                                                    */
46 /*  LVM_INVALIDNUMSAMPLES  When the NumSamples is not a valied multiple in unmanaged    */
47 /*                         buffer mode                                                  */
48 /*  LVM_ALIGNMENTERROR     When either the input our output buffers are not 32-bit      */
49 /*                         aligned in unmanaged mode                                    */
50 /*  LVM_NULLADDRESS        When one of hInstance, pInData or pOutData is NULL           */
51 /*                                                                                      */
52 /* NOTES:                                                                               */
53 /*                                                                                      */
54 /****************************************************************************************/
LVM_Process(LVM_Handle_t hInstance,const LVM_FLOAT * pInData,LVM_FLOAT * pOutData,LVM_UINT16 NumSamples,LVM_UINT32 AudioTime)55 LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance, const LVM_FLOAT* pInData,
56                                 LVM_FLOAT* pOutData, LVM_UINT16 NumSamples, LVM_UINT32 AudioTime) {
57     LVM_Instance_t* pInstance = (LVM_Instance_t*)hInstance;
58     LVM_UINT16 SampleCount = NumSamples;
59     LVM_FLOAT* pInput = (LVM_FLOAT*)pInData;
60     LVM_FLOAT* pToProcess = (LVM_FLOAT*)pInData;
61     LVM_FLOAT* pProcessed = pOutData;
62     LVM_ReturnStatus_en Status;
63     LVM_INT32 NrChannels = pInstance->NrChannels;
64     LVM_INT32 ChMask = pInstance->ChMask;
65 #define NrFrames SampleCount  // alias for clarity
66 
67     /*
68      * Check if the number of samples is zero
69      */
70     if (NumSamples == 0) {
71         return (LVM_SUCCESS);
72     }
73 
74     /*
75      * Check valid points have been given
76      */
77     if ((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL)) {
78         return (LVM_NULLADDRESS);
79     }
80 
81     /*
82      * For unmanaged mode only
83      */
84     if (pInstance->InstParams.BufferMode == LVM_UNMANAGED_BUFFERS) {
85         /*
86          * Check if the number of samples is a good multiple (unmanaged mode only)
87          */
88         if ((NumSamples % pInstance->BlickSizeMultiple) != 0) {
89             return (LVM_INVALIDNUMSAMPLES);
90         }
91 
92         /*
93          * Check the buffer alignment
94          */
95         if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0)) {
96             return (LVM_ALIGNMENTERROR);
97         }
98     }
99 
100     /*
101      * Update new parameters if necessary
102      */
103     if (pInstance->ControlPending == LVM_TRUE) {
104         Status = LVM_ApplyNewSettings(hInstance);
105         /* Update the local variable NrChannels from pInstance->NrChannels value */
106         NrChannels = pInstance->NrChannels;
107         ChMask = pInstance->ChMask;
108 
109         if (Status != LVM_SUCCESS) {
110             return Status;
111         }
112     }
113 
114     /*
115      * Process the data with managed buffers
116      */
117     while (SampleCount != 0) {
118         /*
119          * Manage the input buffer and frame processing
120          */
121         LVM_BufferIn(hInstance, pInput, &pToProcess, &pProcessed, &SampleCount);
122 
123         /*
124          * Only process data when SampleCount is none zero, a zero count can occur when
125          * the BufferIn routine is working in managed mode.
126          */
127         if (SampleCount != 0) {
128             /*
129              * Apply ConcertSound if required
130              */
131             if (pInstance->CS_Active == LVM_TRUE) {
132                 (void)LVCS_Process(pInstance->hCSInstance, /* Concert Sound instance handle */
133                                    pToProcess, pProcessed, SampleCount);
134                 pToProcess = pProcessed;
135             }
136 
137             /*
138              * Apply volume if required
139              */
140             if (pInstance->VC_Active != 0) {
141                 LVC_MixSoft_Mc_D16C31_SAT(&pInstance->VC_Volume, pToProcess, pProcessed,
142                                           (LVM_INT16)(NrFrames), NrChannels);
143                 pToProcess = pProcessed;
144             }
145 
146             /*
147              * Call N-Band equaliser if enabled
148              */
149             if (pInstance->EQNB_Active == LVM_TRUE) {
150                 LVEQNB_Process(pInstance->hEQNBInstance, /* N-Band equaliser instance handle */
151                                pToProcess, pProcessed, SampleCount);
152                 pToProcess = pProcessed;
153             }
154 
155             /*
156              * Call bass enhancement if enabled
157              */
158             if (pInstance->DBE_Active == LVM_TRUE) {
159                 LVDBE_Process(pInstance->hDBEInstance, /* Dynamic Bass Enhancement \
160                                                           instance handle */
161                               pToProcess, pProcessed, SampleCount);
162                 pToProcess = pProcessed;
163             }
164 
165             /*
166              * Bypass mode or everything off, so copy the input to the output
167              */
168             if (pToProcess != pProcessed) {
169                 Copy_Float(pToProcess,                          /* Source */
170                            pProcessed,                          /* Destination */
171                            (LVM_INT16)(NrChannels * NrFrames)); /* Copy all samples */
172             }
173 
174             /*
175              * Apply treble boost if required
176              */
177             if (pInstance->TE_Active == LVM_TRUE) {
178                 /*
179                  * Apply the filter
180                  */
181                 pInstance->pTEBiquad->process(pProcessed, pProcessed, NrFrames);
182                 for (auto i = 0; i < NrChannels * NrFrames; i++) {
183                     pProcessed[i] = LVM_Clamp(pProcessed[i]);
184                 }
185             }
186             /*
187              * Volume balance
188              */
189             LVC_MixSoft_1St_MC_float_SAT(&pInstance->VC_BalanceMix, pProcessed, pProcessed,
190                                          NrFrames, NrChannels, ChMask);
191 
192             /*
193              * Perform Parametric Spectum Analysis
194              */
195             if ((pInstance->Params.PSA_Enable == LVM_PSA_ON) &&
196                 (pInstance->InstParams.PSA_Included == LVM_PSA_ON)) {
197                 FromMcToMono_Float(pProcessed, pInstance->pPSAInput, (LVM_INT16)(NrFrames),
198                                    NrChannels);
199 
200                 LVPSA_Process(pInstance->hPSAInstance, pInstance->pPSAInput,
201                               (LVM_UINT16)(SampleCount), AudioTime);
202             }
203 
204             /*
205              * DC removal
206              */
207             DC_Mc_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance, pProcessed, pProcessed,
208                                  (LVM_INT16)NrFrames, NrChannels);
209         }
210         /*
211          * Manage the output buffer
212          */
213         LVM_BufferOut(hInstance, pOutData, &SampleCount);
214     }
215 
216     return (LVM_SUCCESS);
217 }
218