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 #ifdef BUILD_FLOAT 84 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size = sizeof(LVDBE_Data_FLOAT_t); 85 #else 86 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size = sizeof(LVDBE_Data_t); 87 #endif 88 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Alignment = LVDBE_PERSISTENT_DATA_ALIGN; 89 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Type = LVDBE_PERSISTENT_DATA; 90 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL; 91 92 /* 93 * Coef memory 94 */ 95 #ifdef BUILD_FLOAT 96 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size = sizeof(LVDBE_Coef_FLOAT_t); 97 #else 98 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size = sizeof(LVDBE_Coef_t); 99 #endif 100 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Alignment = LVDBE_PERSISTENT_COEF_ALIGN; 101 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Type = LVDBE_PERSISTENT_COEF; 102 pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL; 103 104 /* 105 * Scratch memory 106 */ 107 #ifdef BUILD_FLOAT 108 ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_FLOAT) * \ 109 pCapabilities->MaxBlockSize); 110 #else /*BUILD_FLOAT*/ 111 ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize); 112 #endif 113 pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Size = ScratchSize; 114 pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Alignment = LVDBE_SCRATCH_ALIGN; 115 pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Type = LVDBE_SCRATCH; 116 pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress = LVM_NULL; 117 } 118 else 119 { 120 /* Read back memory allocation table */ 121 *pMemoryTable = pInstance->MemoryTable; 122 } 123 124 return(LVDBE_SUCCESS); 125 } 126 127 128 /****************************************************************************************/ 129 /* */ 130 /* FUNCTION: LVDBE_Init */ 131 /* */ 132 /* DESCRIPTION: */ 133 /* Create and initialisation function for the Dynamic Bass Enhancement module */ 134 /* */ 135 /* This function can be used to create an algorithm instance by calling with */ 136 /* hInstance set to NULL. In this case the algorithm returns the new instance */ 137 /* handle. */ 138 /* */ 139 /* This function can be used to force a full re-initialisation of the algorithm */ 140 /* by calling with hInstance = Instance Handle. In this case the memory table */ 141 /* should be correct for the instance, this can be ensured by calling the function */ 142 /* DBE_Memory before calling this function. */ 143 /* */ 144 /* PARAMETERS: */ 145 /* hInstance Instance handle */ 146 /* pMemoryTable Pointer to the memory definition table */ 147 /* pCapabilities Pointer to the instance capabilities */ 148 /* */ 149 /* RETURNS: */ 150 /* LVDBE_SUCCESS Initialisation succeeded */ 151 /* LVDBE_ALIGNMENTERROR Instance or scratch memory on incorrect alignment */ 152 /* LVDBE_NULLADDRESS Instance or scratch memory has a NULL pointer */ 153 /* */ 154 /* NOTES: */ 155 /* 1. The instance handle is the pointer to the base address of the first memory */ 156 /* region. */ 157 /* 2. This function must not be interrupted by the LVDBE_Process function */ 158 /* */ 159 /****************************************************************************************/ 160 161 LVDBE_ReturnStatus_en LVDBE_Init(LVDBE_Handle_t *phInstance, 162 LVDBE_MemTab_t *pMemoryTable, 163 LVDBE_Capabilities_t *pCapabilities) 164 { 165 166 LVDBE_Instance_t *pInstance; 167 #ifdef BUILD_FLOAT 168 LVMixer3_1St_FLOAT_st *pMixer_Instance; 169 LVMixer3_2St_FLOAT_st *pBypassMixer_Instance; 170 LVM_FLOAT MixGain; 171 #else 172 LVMixer3_1St_st *pMixer_Instance; 173 LVMixer3_2St_st *pBypassMixer_Instance; 174 LVM_INT32 MixGain; 175 #endif 176 LVM_INT16 i; 177 178 179 /* 180 * Set the instance handle if not already initialised 181 */ 182 if (*phInstance == LVM_NULL) 183 { 184 *phInstance = (LVDBE_Handle_t)pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress; 185 } 186 pInstance =(LVDBE_Instance_t *)*phInstance; 187 188 189 /* 190 * Check the memory table for NULL pointers and incorrectly aligned data 191 */ 192 for (i=0; i<LVDBE_NR_MEMORY_REGIONS; i++) 193 { 194 if (pMemoryTable->Region[i].Size!=0) 195 { 196 if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL) 197 { 198 return(LVDBE_NULLADDRESS); 199 } 200 if (((uintptr_t)pMemoryTable->Region[i].pBaseAddress % pMemoryTable->Region[i].Alignment)!=0){ 201 return(LVDBE_ALIGNMENTERROR); 202 } 203 } 204 } 205 206 207 /* 208 * Save the memory table in the instance structure 209 */ 210 pInstance->Capabilities = *pCapabilities; 211 212 213 /* 214 * Save the memory table in the instance structure 215 */ 216 pInstance->MemoryTable = *pMemoryTable; 217 218 219 /* 220 * Set the default instance parameters 221 */ 222 pInstance->Params.CentreFrequency = LVDBE_CENTRE_55HZ; 223 pInstance->Params.EffectLevel = 0; 224 pInstance->Params.HeadroomdB = 0; 225 pInstance->Params.HPFSelect = LVDBE_HPF_OFF; 226 pInstance->Params.OperatingMode = LVDBE_OFF; 227 pInstance->Params.SampleRate = LVDBE_FS_8000; 228 pInstance->Params.VolumeControl = LVDBE_VOLUME_OFF; 229 pInstance->Params.VolumedB = 0; 230 231 232 /* 233 * Set pointer to data and coef memory 234 */ 235 pInstance->pData = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress; 236 pInstance->pCoef = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress; 237 238 239 /* 240 * Initialise the filters 241 */ 242 LVDBE_SetFilters(pInstance, /* Set the filter taps and coefficients */ 243 &pInstance->Params); 244 245 246 /* 247 * Initialise the AGC 248 */ 249 LVDBE_SetAGC(pInstance, /* Set the AGC gain */ 250 &pInstance->Params); 251 pInstance->pData->AGCInstance.AGC_Gain = pInstance->pData->AGCInstance.AGC_MaxGain; 252 /* Default to the bass boost setting */ 253 254 // initialize the mixer with some fixes values since otherwise LVDBE_SetVolume ends up 255 // reading uninitialized data 256 pMixer_Instance = &pInstance->pData->BypassVolume; 257 #ifndef BUILD_FLOAT 258 LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],0x00007FFF,0x00007FFF); 259 #else 260 LVC_Mixer_Init(&pMixer_Instance->MixerStream[0], 1.0, 1.0); 261 #endif 262 263 /* 264 * Initialise the volume 265 */ 266 LVDBE_SetVolume(pInstance, /* Set the Volume */ 267 &pInstance->Params); 268 269 pInstance->pData->AGCInstance.Volume = pInstance->pData->AGCInstance.Target; 270 /* Initialise as the target */ 271 #ifndef BUILD_FLOAT 272 MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]); 273 LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],MixGain,MixGain); 274 #else 275 MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]); 276 LVC_Mixer_Init(&pMixer_Instance->MixerStream[0], MixGain, MixGain); 277 #endif 278 279 /* Configure the mixer process path */ 280 pMixer_Instance->MixerStream[0].CallbackParam = 0; 281 pMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL; 282 pMixer_Instance->MixerStream[0].pCallBack = LVM_NULL; 283 pMixer_Instance->MixerStream[0].CallbackSet = 0; 284 285 /* 286 * Initialise the clicks minimisation BypassMixer 287 */ 288 289 pBypassMixer_Instance = &pInstance->pData->BypassMixer; 290 291 /* 292 * Setup the mixer gain for the processed path 293 */ 294 pBypassMixer_Instance->MixerStream[0].CallbackParam = 0; 295 pBypassMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL; 296 pBypassMixer_Instance->MixerStream[0].pCallBack = LVM_NULL; 297 pBypassMixer_Instance->MixerStream[0].CallbackSet=0; 298 299 LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[0],0,0); 300 LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0], 301 LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate,2); 302 303 /* 304 * Setup the mixer gain for the unprocessed path 305 */ 306 pBypassMixer_Instance->MixerStream[1].CallbackParam = 0; 307 pBypassMixer_Instance->MixerStream[1].pCallbackHandle = LVM_NULL; 308 pBypassMixer_Instance->MixerStream[1].pCallBack = LVM_NULL; 309 pBypassMixer_Instance->MixerStream[1].CallbackSet=0; 310 #ifndef BUILD_FLOAT 311 LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1],0x00007FFF,0x00007FFF); 312 LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1], 313 LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate,2); 314 #else 315 LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1], 1.0, 1.0); 316 LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1], 317 LVDBE_BYPASS_MIXER_TC,(LVM_Fs_en)pInstance->Params.SampleRate, 2); 318 #endif 319 320 return(LVDBE_SUCCESS); 321 } 322