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 27 /****************************************************************************************/ 28 /* */ 29 /* FUNCTION: LVDBE_Memory */ 30 /* */ 31 /* DESCRIPTION: */ 32 /* This function is used for memory allocation and free. It can be called in */ 33 /* two ways: */ 34 /* */ 35 /* hInstance = NULL Returns the memory requirements */ 36 /* hInstance = Instance handle Returns the memory requirements and */ 37 /* allocated base addresses for the instance */ 38 /* */ 39 /* When this function is called for memory allocation (hInstance=NULL) the memory */ 40 /* base address pointers are NULL on return. */ 41 /* */ 42 /* When the function is called for free (hInstance = Instance Handle) the memory */ 43 /* table returns the allocated memory and base addresses used during initialisation. */ 44 /* */ 45 /* PARAMETERS: */ 46 /* hInstance Instance Handle */ 47 /* pMemoryTable Pointer to an empty memory definition table */ 48 /* pCapabilities Pointer to the instance capabilities */ 49 /* */ 50 /* RETURNS: */ 51 /* LVDBE_SUCCESS Succeeded */ 52 /* */ 53 /* NOTES: */ 54 /* 1. This function may be interrupted by the LVDBE_Process function */ 55 /* */ 56 /****************************************************************************************/ 57 58 LVDBE_ReturnStatus_en LVDBE_Memory(LVDBE_Handle_t hInstance, 59 LVDBE_MemTab_t *pMemoryTable, 60 LVDBE_Capabilities_t *pCapabilities) 61 { 62 63 LVM_UINT32 ScratchSize; 64 LVDBE_Instance_t *pInstance = (LVDBE_Instance_t *)hInstance; 65 66 67 /* 68 * Fill in the memory table 69 */ 70 if (hInstance == LVM_NULL) 71 { 72 /* 73 * Instance memory 74 */ 75 pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Size = sizeof(LVDBE_Instance_t); 76 pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Alignment = LVDBE_INSTANCE_ALIGN; 77 pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Type = LVDBE_PERSISTENT; 78 pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress = LVM_NULL; 79 80 /* 81 * Data memory 82 */ 83 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size = sizeof(LVDBE_Data_t); 84 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Alignment = LVDBE_PERSISTENT_DATA_ALIGN; 85 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Type = LVDBE_PERSISTENT_DATA; 86 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL; 87 88 /* 89 * Coef memory 90 */ 91 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size = sizeof(LVDBE_Coef_t); 92 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Alignment = LVDBE_PERSISTENT_COEF_ALIGN; 93 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Type = LVDBE_PERSISTENT_COEF; 94 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL; 95 96 /* 97 * Scratch memory 98 */ 99 ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize); 100 pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Size = ScratchSize; 101 pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Alignment = LVDBE_SCRATCH_ALIGN; 102 pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Type = LVDBE_SCRATCH; 103 pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress = LVM_NULL; 104 } 105 else 106 { 107 /* Read back memory allocation table */ 108 *pMemoryTable = pInstance->MemoryTable; 109 } 110 111 return(LVDBE_SUCCESS); 112 } 113 114 115 /****************************************************************************************/ 116 /* */ 117 /* FUNCTION: LVDBE_Init */ 118 /* */ 119 /* DESCRIPTION: */ 120 /* Create and initialisation function for the Dynamic Bass Enhancement module */ 121 /* */ 122 /* This function can be used to create an algorithm instance by calling with */ 123 /* hInstance set to NULL. In this case the algorithm returns the new instance */ 124 /* handle. */ 125 /* */ 126 /* This function can be used to force a full re-initialisation of the algorithm */ 127 /* by calling with hInstance = Instance Handle. In this case the memory table */ 128 /* should be correct for the instance, this can be ensured by calling the function */ 129 /* DBE_Memory before calling this function. */ 130 /* */ 131 /* PARAMETERS: */ 132 /* hInstance Instance handle */ 133 /* pMemoryTable Pointer to the memory definition table */ 134 /* pCapabilities Pointer to the instance capabilities */ 135 /* */ 136 /* RETURNS: */ 137 /* LVDBE_SUCCESS Initialisation succeeded */ 138 /* LVDBE_ALIGNMENTERROR Instance or scratch memory on incorrect alignment */ 139 /* LVDBE_NULLADDRESS Instance or scratch memory has a NULL pointer */ 140 /* */ 141 /* NOTES: */ 142 /* 1. The instance handle is the pointer to the base address of the first memory */ 143 /* region. */ 144 /* 2. This function must not be interrupted by the LVDBE_Process function */ 145 /* */ 146 /****************************************************************************************/ 147 148 LVDBE_ReturnStatus_en LVDBE_Init(LVDBE_Handle_t *phInstance, 149 LVDBE_MemTab_t *pMemoryTable, 150 LVDBE_Capabilities_t *pCapabilities) 151 { 152 153 LVDBE_Instance_t *pInstance; 154 LVMixer3_1St_st *pMixer_Instance; 155 LVMixer3_2St_st *pBypassMixer_Instance; 156 LVM_INT16 i; 157 LVM_INT32 MixGain; 158 159 160 /* 161 * Set the instance handle if not already initialised 162 */ 163 if (*phInstance == LVM_NULL) 164 { 165 *phInstance = (LVDBE_Handle_t)pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress; 166 } 167 pInstance =(LVDBE_Instance_t *)*phInstance; 168 169 170 /* 171 * Check the memory table for NULL pointers and incorrectly aligned data 172 */ 173 for (i=0; i<LVDBE_NR_MEMORY_REGIONS; i++) 174 { 175 if (pMemoryTable->Region[i].Size!=0) 176 { 177 if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL) 178 { 179 return(LVDBE_NULLADDRESS); 180 } 181 if (((uintptr_t)pMemoryTable->Region[i].pBaseAddress % pMemoryTable->Region[i].Alignment)!=0){ 182 return(LVDBE_ALIGNMENTERROR); 183 } 184 } 185 } 186 187 188 /* 189 * Save the memory table in the instance structure 190 */ 191 pInstance->Capabilities = *pCapabilities; 192 193 194 /* 195 * Save the memory table in the instance structure 196 */ 197 pInstance->MemoryTable = *pMemoryTable; 198 199 200 /* 201 * Set the default instance parameters 202 */ 203 pInstance->Params.CentreFrequency = LVDBE_CENTRE_55HZ; 204 pInstance->Params.EffectLevel = 0; 205 pInstance->Params.HeadroomdB = 0; 206 pInstance->Params.HPFSelect = LVDBE_HPF_OFF; 207 pInstance->Params.OperatingMode = LVDBE_OFF; 208 pInstance->Params.SampleRate = LVDBE_FS_8000; 209 pInstance->Params.VolumeControl = LVDBE_VOLUME_OFF; 210 pInstance->Params.VolumedB = 0; 211 212 213 /* 214 * Set pointer to data and coef memory 215 */ 216 pInstance->pData = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress; 217 pInstance->pCoef = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress; 218 219 220 /* 221 * Initialise the filters 222 */ 223 LVDBE_SetFilters(pInstance, /* Set the filter taps and coefficients */ 224 &pInstance->Params); 225 226 227 /* 228 * Initialise the AGC 229 */ 230 LVDBE_SetAGC(pInstance, /* Set the AGC gain */ 231 &pInstance->Params); 232 pInstance->pData->AGCInstance.AGC_Gain = pInstance->pData->AGCInstance.AGC_MaxGain; 233 /* Default to the bass boost setting */ 234 235 // initialize the mixer with some fixes values since otherwise LVDBE_SetVolume ends up 236 // reading uninitialized data 237 pMixer_Instance = &pInstance->pData->BypassVolume; 238 LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],0x00007FFF,0x00007FFF); 239 240 /* 241 * Initialise the volume 242 */ 243 LVDBE_SetVolume(pInstance, /* Set the Volume */ 244 &pInstance->Params); 245 246 pInstance->pData->AGCInstance.Volume = pInstance->pData->AGCInstance.Target; 247 /* Initialise as the target */ 248 249 MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]); 250 LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],MixGain,MixGain); 251 252 /* Configure the mixer process path */ 253 pMixer_Instance->MixerStream[0].CallbackParam = 0; 254 pMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL; 255 pMixer_Instance->MixerStream[0].pCallBack = LVM_NULL; 256 pMixer_Instance->MixerStream[0].CallbackSet = 0; 257 258 /* 259 * Initialise the clicks minimisation BypassMixer 260 */ 261 262 pBypassMixer_Instance = &pInstance->pData->BypassMixer; 263 264 /* 265 * Setup the mixer gain for the processed path 266 */ 267 pBypassMixer_Instance->MixerStream[0].CallbackParam = 0; 268 pBypassMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL; 269 pBypassMixer_Instance->MixerStream[0].pCallBack = LVM_NULL; 270 pBypassMixer_Instance->MixerStream[0].CallbackSet=0; 271 LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[0],0,0); 272 LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0], 273 LVDBE_BYPASS_MIXER_TC,pInstance->Params.SampleRate,2); 274 /* 275 * Setup the mixer gain for the unprocessed path 276 */ 277 pBypassMixer_Instance->MixerStream[1].CallbackParam = 0; 278 pBypassMixer_Instance->MixerStream[1].pCallbackHandle = LVM_NULL; 279 pBypassMixer_Instance->MixerStream[1].pCallBack = LVM_NULL; 280 pBypassMixer_Instance->MixerStream[1].CallbackSet=0; 281 LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1],0x00007FFF,0x00007FFF); 282 LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1], 283 LVDBE_BYPASS_MIXER_TC,pInstance->Params.SampleRate,2); 284 285 return(LVDBE_SUCCESS); 286 } 287 288