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 #ifdef BUILD_FLOAT 55 LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance, 56 const LVM_FLOAT *pInData, 57 LVM_FLOAT *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_FLOAT *pInput = (LVM_FLOAT *)pInData; 65 LVM_FLOAT *pToProcess = (LVM_FLOAT *)pInData; 66 LVM_FLOAT *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_Float(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 \ 199 instance handle */ 200 pToProcess, 201 pProcessed, 202 SampleCount); 203 pToProcess = pProcessed; 204 } 205 206 /* 207 * Bypass mode or everything off, so copy the input to the output 208 */ 209 if (pToProcess != pProcessed) 210 { 211 Copy_Float(pToProcess, /* Source */ 212 pProcessed, /* Destination */ 213 (LVM_INT16)(2 * SampleCount)); /* Left and right */ 214 } 215 216 /* 217 * Apply treble boost if required 218 */ 219 if (pInstance->TE_Active == LVM_TRUE) 220 { 221 /* 222 * Apply the filter 223 */ 224 FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State, 225 pProcessed, 226 pProcessed, 227 (LVM_INT16)SampleCount); 228 229 } 230 231 /* 232 * Volume balance 233 */ 234 LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix, 235 pProcessed, 236 pProcessed, 237 SampleCount); 238 239 /* 240 * Perform Parametric Spectum Analysis 241 */ 242 if ((pInstance->Params.PSA_Enable == LVM_PSA_ON) && 243 (pInstance->InstParams.PSA_Included == LVM_PSA_ON)) 244 { 245 From2iToMono_Float(pProcessed, 246 pInstance->pPSAInput, 247 (LVM_INT16)(SampleCount)); 248 249 LVPSA_Process(pInstance->hPSAInstance, 250 pInstance->pPSAInput, 251 (LVM_UINT16)(SampleCount), 252 AudioTime); 253 } 254 255 256 /* 257 * DC removal 258 */ 259 DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance, 260 pProcessed, 261 pProcessed, 262 (LVM_INT16)SampleCount); 263 264 265 } 266 267 /* 268 * Manage the output buffer 269 */ 270 LVM_BufferOut(hInstance, 271 pOutData, 272 &SampleCount); 273 274 } 275 276 return(LVM_SUCCESS); 277 } 278 #else 279 LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance, 280 const LVM_INT16 *pInData, 281 LVM_INT16 *pOutData, 282 LVM_UINT16 NumSamples, 283 LVM_UINT32 AudioTime) 284 { 285 286 LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance; 287 LVM_UINT16 SampleCount = NumSamples; 288 LVM_INT16 *pInput = (LVM_INT16 *)pInData; 289 LVM_INT16 *pToProcess = (LVM_INT16 *)pInData; 290 LVM_INT16 *pProcessed = pOutData; 291 LVM_ReturnStatus_en Status; 292 293 /* 294 * Check if the number of samples is zero 295 */ 296 if (NumSamples == 0) 297 { 298 return(LVM_SUCCESS); 299 } 300 301 302 /* 303 * Check valid points have been given 304 */ 305 if ((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL)) 306 { 307 return (LVM_NULLADDRESS); 308 } 309 310 /* 311 * For unmanaged mode only 312 */ 313 if(pInstance->InstParams.BufferMode == LVM_UNMANAGED_BUFFERS) 314 { 315 /* 316 * Check if the number of samples is a good multiple (unmanaged mode only) 317 */ 318 if((NumSamples % pInstance->BlickSizeMultiple) != 0) 319 { 320 return(LVM_INVALIDNUMSAMPLES); 321 } 322 323 /* 324 * Check the buffer alignment 325 */ 326 if((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0)) 327 { 328 return(LVM_ALIGNMENTERROR); 329 } 330 } 331 332 333 /* 334 * Update new parameters if necessary 335 */ 336 if (pInstance->ControlPending == LVM_TRUE) 337 { 338 Status = LVM_ApplyNewSettings(hInstance); 339 340 if(Status != LVM_SUCCESS) 341 { 342 return Status; 343 } 344 } 345 346 347 /* 348 * Convert from Mono if necessary 349 */ 350 if (pInstance->Params.SourceFormat == LVM_MONO) 351 { 352 MonoTo2I_16(pInData, /* Source */ 353 pOutData, /* Destination */ 354 (LVM_INT16)NumSamples); /* Number of input samples */ 355 pInput = pOutData; 356 pToProcess = pOutData; 357 } 358 359 360 /* 361 * Process the data with managed buffers 362 */ 363 while (SampleCount != 0) 364 { 365 /* 366 * Manage the input buffer and frame processing 367 */ 368 LVM_BufferIn(hInstance, 369 pInput, 370 &pToProcess, 371 &pProcessed, 372 &SampleCount); 373 374 /* 375 * Only process data when SampleCount is none zero, a zero count can occur when 376 * the BufferIn routine is working in managed mode. 377 */ 378 if (SampleCount != 0) 379 { 380 381 /* 382 * Apply ConcertSound if required 383 */ 384 if (pInstance->CS_Active == LVM_TRUE) 385 { 386 (void)LVCS_Process(pInstance->hCSInstance, /* Concert Sound instance handle */ 387 pToProcess, 388 pProcessed, 389 SampleCount); 390 pToProcess = pProcessed; 391 } 392 393 /* 394 * Apply volume if required 395 */ 396 if (pInstance->VC_Active!=0) 397 { 398 LVC_MixSoft_1St_D16C31_SAT(&pInstance->VC_Volume, 399 pToProcess, 400 pProcessed, 401 (LVM_INT16)(2*SampleCount)); /* Left and right*/ 402 pToProcess = pProcessed; 403 } 404 405 /* 406 * Call N-Band equaliser if enabled 407 */ 408 if (pInstance->EQNB_Active == LVM_TRUE) 409 { 410 LVEQNB_Process(pInstance->hEQNBInstance, /* N-Band equaliser instance handle */ 411 pToProcess, 412 pProcessed, 413 SampleCount); 414 pToProcess = pProcessed; 415 } 416 417 /* 418 * Call bass enhancement if enabled 419 */ 420 if (pInstance->DBE_Active == LVM_TRUE) 421 { 422 LVDBE_Process(pInstance->hDBEInstance, /* Dynamic Bass Enhancement instance handle */ 423 pToProcess, 424 pProcessed, 425 SampleCount); 426 pToProcess = pProcessed; 427 } 428 429 /* 430 * Bypass mode or everything off, so copy the input to the output 431 */ 432 if (pToProcess != pProcessed) 433 { 434 Copy_16(pToProcess, /* Source */ 435 pProcessed, /* Destination */ 436 (LVM_INT16)(2*SampleCount)); /* Left and right */ 437 } 438 439 /* 440 * Apply treble boost if required 441 */ 442 if (pInstance->TE_Active == LVM_TRUE) 443 { 444 /* 445 * Apply the filter 446 */ 447 FO_2I_D16F32C15_LShx_TRC_WRA_01(&pInstance->pTE_State->TrebleBoost_State, 448 pProcessed, 449 pProcessed, 450 (LVM_INT16)SampleCount); 451 452 } 453 454 /* 455 * Volume balance 456 */ 457 LVC_MixSoft_1St_2i_D16C31_SAT(&pInstance->VC_BalanceMix, 458 pProcessed, 459 pProcessed, 460 SampleCount); 461 462 /* 463 * Perform Parametric Spectum Analysis 464 */ 465 if ((pInstance->Params.PSA_Enable == LVM_PSA_ON)&&(pInstance->InstParams.PSA_Included==LVM_PSA_ON)) 466 { 467 From2iToMono_16(pProcessed, 468 pInstance->pPSAInput, 469 (LVM_INT16) (SampleCount)); 470 471 LVPSA_Process(pInstance->hPSAInstance, 472 pInstance->pPSAInput, 473 (LVM_UINT16) (SampleCount), 474 AudioTime); 475 } 476 477 478 /* 479 * DC removal 480 */ 481 DC_2I_D16_TRC_WRA_01(&pInstance->DC_RemovalInstance, 482 pProcessed, 483 pProcessed, 484 (LVM_INT16)SampleCount); 485 486 487 } 488 489 /* 490 * Manage the output buffer 491 */ 492 LVM_BufferOut(hInstance, 493 pOutData, 494 &SampleCount); 495 496 } 497 498 return(LVM_SUCCESS); 499 } 500 #endif