LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t hInstance, const LVM_FLOAT *pInData, LVM_FLOAT *pOutData, LVM_UINT16 NumSamples) { LVM_UINT16 i; Biquad_FLOAT_Instance_t *pBiquad; LVEQNB_Instance_t *pInstance = (LVEQNB_Instance_t *)hInstance; LVM_FLOAT *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_FLOAT *)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) { /* * Copy input data in to scratch buffer */ Copy_Float((LVM_FLOAT *)pInData, /* Source */ pScratch, /* Destination */ (LVM_INT16)(2 * NumSamples)); /* Left and Right */ /* * For each section execte the filter unless the gain is 0dB */ if (pInstance->NBands != 0) { for (i = 0; i < pInstance->NBands; 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_Float[i]; /* * Select single or double precision as required */ switch (pInstance->pBiquadType[i]) { case LVEQNB_SinglePrecision_Float: { PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad, (LVM_FLOAT *)pScratch, (LVM_FLOAT *)pScratch, (LVM_INT16)NumSamples); break; } default: break; } } } } if(pInstance->bInOperatingModeTransition == LVM_TRUE){ LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer, (LVM_FLOAT *)pScratch, (LVM_FLOAT *)pInData, (LVM_FLOAT *)pScratch, (LVM_INT16)(2 * NumSamples)); Copy_Float((LVM_FLOAT*)pScratch, /* Source */ pOutData, /* Destination */ (LVM_INT16)(2 * NumSamples)); /* Left and Right samples */ } else{ Copy_Float(pScratch, /* Source */ pOutData, /* Destination */ (LVM_INT16 )(2 * NumSamples)); /* Left and Right */ } } else { /* * Mode is OFF so copy the data if necessary */ if (pInData != pOutData) { Copy_Float(pInData, /* Source */ pOutData, /* Destination */ (LVM_INT16)(2 * NumSamples)); /* Left and Right samples */ } } return(LVEQNB_SUCCESS); }
LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance, const LVM_INT16 *pInData, LVM_INT16 *pOutData, LVM_UINT16 NumSamples) { LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance; LVM_INT32 *pScratch = (LVM_INT32 *)pInstance->MemoryTable.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress; LVM_INT32 *pMono; LVM_INT16 *pInput = (LVM_INT16 *)pInData; /* Scratch for Volume Control starts at offset of 2*NumSamples short values from pScratch */ LVM_INT16 *pScratchVol = (LVM_INT16 *)(&pScratch[NumSamples]); /* Scratch for Mono path starts at offset of 2*NumSamples 32-bit values from pScratch */ pMono = &pScratch[2*NumSamples]; /* * Check the number of samples is not too large */ if (NumSamples > pInstance->Capabilities.MaxBlockSize) { return(LVDBE_TOOMANYSAMPLES); } /* * Check if the algorithm is enabled */ /* DBE path is processed when DBE is ON or during On/Off transitions */ if ((pInstance->Params.OperatingMode == LVDBE_ON)|| (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[0]) !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[0]))) { /* * Convert 16-bit samples to 32-bit and scale * (For a 16-bit implementation apply headroom loss here) */ Int16LShiftToInt32_16x32(pInput, /* Source 16-bit data */ pScratch, /* Dest. 32-bit data */ (LVM_INT16)(2*NumSamples), /* Left and right */ LVDBE_SCALESHIFT); /* Shift scale */ /* * Apply the high pass filter if selected */ if (pInstance->Params.HPFSelect == LVDBE_HPF_ON) { BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance */ (LVM_INT32 *)pScratch, /* Source */ (LVM_INT32 *)pScratch, /* Destination */ (LVM_INT16)NumSamples); /* Number of samples */ } /* * Create the mono stream */ From2iToMono_32(pScratch, /* Stereo source */ pMono, /* Mono destination */ (LVM_INT16)NumSamples); /* Number of samples */ /* * Apply the band pass filter */ BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance */ (LVM_INT32 *)pMono, /* Source */ (LVM_INT32 *)pMono, /* Destination */ (LVM_INT16)NumSamples); /* Number of samples */ /* * Apply the AGC and mix */ AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer */ pScratch, /* Stereo source */ pMono, /* Mono band pass source */ pScratch, /* Stereo destination */ NumSamples); /* Number of samples */ /* * Convert 32-bit samples to 16-bit and saturate * (Not required for 16-bit implemenations) */ Int32RShiftToInt16_Sat_32x16(pScratch, /* Source 32-bit data */ (LVM_INT16 *)pScratch, /* Dest. 16-bit data */ (LVM_INT16)(2*NumSamples), /* Left and right */ LVDBE_SCALESHIFT); /* Shift scale */ } /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */ if ((pInstance->Params.OperatingMode == LVDBE_OFF)|| (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[1]) !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[1]))) { /* * The algorithm is disabled but volume management is required to compensate for * headroom and volume (if enabled) */ LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume, pInData, pScratchVol, (LVM_INT16)(2*NumSamples)); /* Left and right */ } /* * Mix DBE processed path and bypass volume path */ LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer, (LVM_INT16 *) pScratch, pScratchVol, pOutData, (LVM_INT16)(2*NumSamples)); return(LVDBE_SUCCESS); }