/* * Copyright (C) 2004-2010 NXP Software * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /****************************************************************************************/ /* */ /* Includes */ /* */ /****************************************************************************************/ #include "LVEQNB.h" #include "LVEQNB_Private.h" #include "VectorArithmetic.h" #include "BIQUAD.h" /****************************************************************************************/ /* */ /* Defines */ /* */ /****************************************************************************************/ #define SHIFT 13 /****************************************************************************************/ /* */ /* FUNCTION: LVEQNB_Process */ /* */ /* DESCRIPTION: */ /* Process function for the N-Band Equaliser module. */ /* */ /* PARAMETERS: */ /* hInstance Instance handle */ /* pInData Pointer to the input data */ /* pOutData Pointer to the output data */ /* NumSamples Number of samples in the input buffer */ /* */ /* RETURNS: */ /* LVEQNB_SUCCESS Succeeded */ /* LVEQNB_NULLADDRESS When hInstance, pInData or pOutData are NULL */ /* LVEQNB_ALIGNMENTERROR When pInData or pOutData are not 32-bit aligned */ /* LVEQNB_TOOMANYSAMPLES NumSamples was larger than the maximum block size */ /* */ /* NOTES: */ /* */ /****************************************************************************************/ LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t hInstance, const LVM_INT16 *pInData, LVM_INT16 *pOutData, LVM_UINT16 NumSamples) { LVM_UINT16 i; Biquad_Instance_t *pBiquad; LVEQNB_Instance_t *pInstance = (LVEQNB_Instance_t *)hInstance; LVM_INT32 *pScratch; /* Check for NULL pointers */ if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL)) { return LVEQNB_NULLADDRESS; } /* Check if the input and output data buffers are 32-bit aligned */ if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0)) { return LVEQNB_ALIGNMENTERROR; } pScratch = (LVM_INT32 *)pInstance->pFastTemporary; /* * Check the number of samples is not too large */ if (NumSamples > pInstance->Capabilities.MaxBlockSize) { return(LVEQNB_TOOMANYSAMPLES); } if (pInstance->Params.OperatingMode == LVEQNB_ON) { /* * Convert from 16-bit to 32-bit */ Int16LShiftToInt32_16x32((LVM_INT16 *)pInData, /* Source */ pScratch, /* Destination */ (LVM_INT16)(2*NumSamples), /* Left and Right */ SHIFT); /* Scaling shift */ /* * For each section execte the filter unless the gain is 0dB */ if (pInstance->NBands != 0) { for (i=0; iNBands; i++) { /* * Check if band is non-zero dB gain */ if (pInstance->pBandDefinitions[i].Gain != 0) { /* * Get the address of the biquad instance */ pBiquad = &pInstance->pEQNB_FilterState[i]; /* * Select single or double precision as required */ switch (pInstance->pBiquadType[i]) { case LVEQNB_SinglePrecision: { PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad, (LVM_INT32 *)pScratch, (LVM_INT32 *)pScratch, (LVM_INT16)NumSamples); break; } case LVEQNB_DoublePrecision: { PK_2I_D32F32C30G11_TRC_WRA_01(pBiquad, (LVM_INT32 *)pScratch, (LVM_INT32 *)pScratch, (LVM_INT16)NumSamples); break; } default: break; } } } } if(pInstance->bInOperatingModeTransition == LVM_TRUE){ /* * Convert from 32-bit to 16- bit and saturate */ Int32RShiftToInt16_Sat_32x16(pScratch, /* Source */ (LVM_INT16 *)pScratch, /* Destination */ (LVM_INT16)(2*NumSamples), /* Left and Right */ SHIFT); /* Scaling shift */ LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer, (LVM_INT16 *)pScratch, (LVM_INT16 *)pInData, (LVM_INT16 *)pScratch, (LVM_INT16)(2*NumSamples)); Copy_16((LVM_INT16*)pScratch, /* Source */ pOutData, /* Destination */ (LVM_INT16)(2*NumSamples)); /* Left and Right samples */ } else{ /* * Convert from 32-bit to 16- bit and saturate */ Int32RShiftToInt16_Sat_32x16(pScratch, /* Source */ pOutData, /* Destination */ (LVM_INT16 )(2*NumSamples), /* Left and Right */ SHIFT); /* Scaling shift */ } } else { /* * Mode is OFF so copy the data if necessary */ if (pInData != pOutData) { Copy_16(pInData, /* Source */ pOutData, /* Destination */ (LVM_INT16)(2*NumSamples)); /* Left and Right samples */ } } return(LVEQNB_SUCCESS); }