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 24#include "LVEQNB.h" 25#include "LVEQNB_Private.h" 26#include "VectorArithmetic.h" 27#include "BIQUAD.h" 28 29 30/****************************************************************************************/ 31/* */ 32/* Defines */ 33/* */ 34/****************************************************************************************/ 35 36#define SHIFT 13 37 38/****************************************************************************************/ 39/* */ 40/* FUNCTION: LVEQNB_Process */ 41/* */ 42/* DESCRIPTION: */ 43/* Process function for the N-Band Equaliser module. */ 44/* */ 45/* PARAMETERS: */ 46/* hInstance Instance handle */ 47/* pInData Pointer to the input data */ 48/* pOutData Pointer to the output data */ 49/* NumSamples Number of samples in the input buffer */ 50/* */ 51/* RETURNS: */ 52/* LVEQNB_SUCCESS Succeeded */ 53/* LVEQNB_NULLADDRESS When hInstance, pInData or pOutData are NULL */ 54/* LVEQNB_ALIGNMENTERROR When pInData or pOutData are not 32-bit aligned */ 55/* LVEQNB_TOOMANYSAMPLES NumSamples was larger than the maximum block size */ 56/* */ 57/* NOTES: */ 58/* */ 59/****************************************************************************************/ 60 61LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t hInstance, 62 const LVM_INT16 *pInData, 63 LVM_INT16 *pOutData, 64 LVM_UINT16 NumSamples) 65{ 66 67 LVM_UINT16 i; 68 Biquad_Instance_t *pBiquad; 69 LVEQNB_Instance_t *pInstance = (LVEQNB_Instance_t *)hInstance; 70 LVM_INT32 *pScratch; 71 72 73 /* Check for NULL pointers */ 74 if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL)) 75 { 76 return LVEQNB_NULLADDRESS; 77 } 78 79 /* Check if the input and output data buffers are 32-bit aligned */ 80 if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0)) 81 { 82 return LVEQNB_ALIGNMENTERROR; 83 } 84 85 pScratch = (LVM_INT32 *)pInstance->pFastTemporary; 86 87 /* 88 * Check the number of samples is not too large 89 */ 90 if (NumSamples > pInstance->Capabilities.MaxBlockSize) 91 { 92 return(LVEQNB_TOOMANYSAMPLES); 93 } 94 95 if (pInstance->Params.OperatingMode == LVEQNB_ON) 96 { 97 /* 98 * Convert from 16-bit to 32-bit 99 */ 100 Int16LShiftToInt32_16x32((LVM_INT16 *)pInData, /* Source */ 101 pScratch, /* Destination */ 102 (LVM_INT16)(2*NumSamples), /* Left and Right */ 103 SHIFT); /* Scaling shift */ 104 105 /* 106 * For each section execte the filter unless the gain is 0dB 107 */ 108 if (pInstance->NBands != 0) 109 { 110 for (i=0; i<pInstance->NBands; i++) 111 { 112 /* 113 * Check if band is non-zero dB gain 114 */ 115 if (pInstance->pBandDefinitions[i].Gain != 0) 116 { 117 /* 118 * Get the address of the biquad instance 119 */ 120 pBiquad = &pInstance->pEQNB_FilterState[i]; 121 122 123 /* 124 * Select single or double precision as required 125 */ 126 switch (pInstance->pBiquadType[i]) 127 { 128 case LVEQNB_SinglePrecision: 129 { 130 PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad, 131 (LVM_INT32 *)pScratch, 132 (LVM_INT32 *)pScratch, 133 (LVM_INT16)NumSamples); 134 break; 135 } 136 137 case LVEQNB_DoublePrecision: 138 { 139 PK_2I_D32F32C30G11_TRC_WRA_01(pBiquad, 140 (LVM_INT32 *)pScratch, 141 (LVM_INT32 *)pScratch, 142 (LVM_INT16)NumSamples); 143 break; 144 } 145 default: 146 break; 147 } 148 } 149 } 150 } 151 152 153 if(pInstance->bInOperatingModeTransition == LVM_TRUE){ 154 /* 155 * Convert from 32-bit to 16- bit and saturate 156 */ 157 Int32RShiftToInt16_Sat_32x16(pScratch, /* Source */ 158 (LVM_INT16 *)pScratch, /* Destination */ 159 (LVM_INT16)(2*NumSamples), /* Left and Right */ 160 SHIFT); /* Scaling shift */ 161 162 LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer, 163 (LVM_INT16 *)pScratch, 164 (LVM_INT16 *)pInData, 165 (LVM_INT16 *)pScratch, 166 (LVM_INT16)(2*NumSamples)); 167 168 Copy_16((LVM_INT16*)pScratch, /* Source */ 169 pOutData, /* Destination */ 170 (LVM_INT16)(2*NumSamples)); /* Left and Right samples */ 171 } 172 else{ 173 174 /* 175 * Convert from 32-bit to 16- bit and saturate 176 */ 177 Int32RShiftToInt16_Sat_32x16(pScratch, /* Source */ 178 pOutData, /* Destination */ 179 (LVM_INT16 )(2*NumSamples), /* Left and Right */ 180 SHIFT); /* Scaling shift */ 181 } 182 } 183 else 184 { 185 /* 186 * Mode is OFF so copy the data if necessary 187 */ 188 if (pInData != pOutData) 189 { 190 Copy_16(pInData, /* Source */ 191 pOutData, /* Destination */ 192 (LVM_INT16)(2*NumSamples)); /* Left and Right samples */ 193 } 194 } 195 196 197 198 return(LVEQNB_SUCCESS); 199 200} 201