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 "LVDBE.h" 25 #include "LVDBE_Private.h" 26 #include "VectorArithmetic.h" 27 #include "AGC.h" 28 #include "LVDBE_Coeffs.h" /* Filter coefficients */ 29 30 31 /********************************************************************************************/ 32 /* */ 33 /* FUNCTION: LVDBE_Process */ 34 /* */ 35 /* DESCRIPTION: */ 36 /* Process function for the Bass Enhancement module. */ 37 /* */ 38 /* Data can be processed in two formats, stereo or mono-in-stereo. Data in mono */ 39 /* format is not supported, the calling routine must convert the mono stream to */ 40 /* mono-in-stereo. */ 41 /* ___________ */ 42 /* ________ | | ________ */ 43 /* | | _____ |------------------------->| | | | */ 44 /* | 16-bit | | | | ________ | | | 32-bit | */ 45 /* -+-->| to |-->| HPF |--| | | _____ | AGC Mixer |-->| to |--| */ 46 /* | | 32-bit | |_____| | | Stereo | | | | | | 16-bit | | */ 47 /* | |________| |-->| to |-->| BPF |-->| | |________| 0 */ 48 /* | | Mono | |_____| |___________| \--> */ 49 /* | |________| */ 50 /* | _________ 0 */ 51 /* | | | | */ 52 /* |----------------------------------------------------| Volume |-----------------| */ 53 /* | Control | */ 54 /* |_________| */ 55 /* */ 56 /* PARAMETERS: */ 57 /* hInstance Instance handle */ 58 /* pInData Pointer to the input data */ 59 /* pOutData Pointer to the output data */ 60 /* NumSamples Number of samples in the input buffer */ 61 /* */ 62 /* RETURNS: */ 63 /* LVDBE_SUCCESS Succeeded */ 64 /* LVDBE_TOOMANYSAMPLES NumSamples was larger than the maximum block size */ 65 /* */ 66 /* NOTES: */ 67 /* 1. The input and output data must be 32-bit format. The input is scaled by a shift */ 68 /* when converting from 16-bit format, this scaling allows for internal headroom in the */ 69 /* bass enhancement algorithm. */ 70 /* 2. For a 16-bit implementation the converstion to 32-bit is removed and replaced with */ 71 /* the headroom loss. This headroom loss is compensated in the volume control so the */ 72 /* overall end to end gain is odB. */ 73 /* */ 74 /********************************************************************************************/ 75 76 LVDBE_ReturnStatus_en LVDBE_Process(LVDBE_Handle_t hInstance, 77 const LVM_INT16 *pInData, 78 LVM_INT16 *pOutData, 79 LVM_UINT16 NumSamples) 80 { 81 82 LVDBE_Instance_t *pInstance =(LVDBE_Instance_t *)hInstance; 83 LVM_INT32 *pScratch = (LVM_INT32 *)pInstance->MemoryTable.Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress; 84 LVM_INT32 *pMono; 85 LVM_INT16 *pInput = (LVM_INT16 *)pInData; 86 87 88 /* Scratch for Volume Control starts at offset of 2*NumSamples short values from pScratch */ 89 LVM_INT16 *pScratchVol = (LVM_INT16 *)(&pScratch[NumSamples]); 90 91 /* Scratch for Mono path starts at offset of 2*NumSamples 32-bit values from pScratch */ 92 pMono = &pScratch[2*NumSamples]; 93 94 /* 95 * Check the number of samples is not too large 96 */ 97 if (NumSamples > pInstance->Capabilities.MaxBlockSize) 98 { 99 return(LVDBE_TOOMANYSAMPLES); 100 } 101 102 /* 103 * Check if the algorithm is enabled 104 */ 105 /* DBE path is processed when DBE is ON or during On/Off transitions */ 106 if ((pInstance->Params.OperatingMode == LVDBE_ON)|| 107 (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[0]) 108 !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[0]))) 109 { 110 111 /* 112 * Convert 16-bit samples to 32-bit and scale 113 * (For a 16-bit implementation apply headroom loss here) 114 */ 115 Int16LShiftToInt32_16x32(pInput, /* Source 16-bit data */ 116 pScratch, /* Dest. 32-bit data */ 117 (LVM_INT16)(2*NumSamples), /* Left and right */ 118 LVDBE_SCALESHIFT); /* Shift scale */ 119 120 121 /* 122 * Apply the high pass filter if selected 123 */ 124 if (pInstance->Params.HPFSelect == LVDBE_HPF_ON) 125 { 126 BQ_2I_D32F32C30_TRC_WRA_01(&pInstance->pCoef->HPFInstance,/* Filter instance */ 127 (LVM_INT32 *)pScratch, /* Source */ 128 (LVM_INT32 *)pScratch, /* Destination */ 129 (LVM_INT16)NumSamples); /* Number of samples */ 130 } 131 132 133 /* 134 * Create the mono stream 135 */ 136 From2iToMono_32(pScratch, /* Stereo source */ 137 pMono, /* Mono destination */ 138 (LVM_INT16)NumSamples); /* Number of samples */ 139 140 141 /* 142 * Apply the band pass filter 143 */ 144 BP_1I_D32F32C30_TRC_WRA_02(&pInstance->pCoef->BPFInstance, /* Filter instance */ 145 (LVM_INT32 *)pMono, /* Source */ 146 (LVM_INT32 *)pMono, /* Destination */ 147 (LVM_INT16)NumSamples); /* Number of samples */ 148 149 150 /* 151 * Apply the AGC and mix 152 */ 153 AGC_MIX_VOL_2St1Mon_D32_WRA(&pInstance->pData->AGCInstance, /* Instance pointer */ 154 pScratch, /* Stereo source */ 155 pMono, /* Mono band pass source */ 156 pScratch, /* Stereo destination */ 157 NumSamples); /* Number of samples */ 158 159 /* 160 * Convert 32-bit samples to 16-bit and saturate 161 * (Not required for 16-bit implemenations) 162 */ 163 Int32RShiftToInt16_Sat_32x16(pScratch, /* Source 32-bit data */ 164 (LVM_INT16 *)pScratch, /* Dest. 16-bit data */ 165 (LVM_INT16)(2*NumSamples), /* Left and right */ 166 LVDBE_SCALESHIFT); /* Shift scale */ 167 168 } 169 170 /* Bypass Volume path is processed when DBE is OFF or during On/Off transitions */ 171 if ((pInstance->Params.OperatingMode == LVDBE_OFF)|| 172 (LVC_Mixer_GetCurrent(&pInstance->pData->BypassMixer.MixerStream[1]) 173 !=LVC_Mixer_GetTarget(&pInstance->pData->BypassMixer.MixerStream[1]))) 174 { 175 176 /* 177 * The algorithm is disabled but volume management is required to compensate for 178 * headroom and volume (if enabled) 179 */ 180 LVC_MixSoft_1St_D16C31_SAT(&pInstance->pData->BypassVolume, 181 pInData, 182 pScratchVol, 183 (LVM_INT16)(2*NumSamples)); /* Left and right */ 184 185 } 186 187 /* 188 * Mix DBE processed path and bypass volume path 189 */ 190 LVC_MixSoft_2St_D16C31_SAT(&pInstance->pData->BypassMixer, 191 (LVM_INT16 *) pScratch, 192 pScratchVol, 193 pOutData, 194 (LVM_INT16)(2*NumSamples)); 195 196 return(LVDBE_SUCCESS); 197 } 198 199 200 201 202 203 204 205 206 207 208