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 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((((LVM_UINT32)pInData % 4) != 0) || (((LVM_UINT32)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