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