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