/* * Copyright (C) 2004-2010 NXP Software * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /****************************************************************************************/ /* */ /* Includes */ /* */ /****************************************************************************************/ #include "LVDBE.h" #include "LVDBE_Private.h" /****************************************************************************************/ /* */ /* FUNCTION: LVDBE_Memory */ /* */ /* DESCRIPTION: */ /* This function is used for memory allocation and free. It can be called in */ /* two ways: */ /* */ /* hInstance = NULL Returns the memory requirements */ /* hInstance = Instance handle Returns the memory requirements and */ /* allocated base addresses for the instance */ /* */ /* When this function is called for memory allocation (hInstance=NULL) the memory */ /* base address pointers are NULL on return. */ /* */ /* When the function is called for free (hInstance = Instance Handle) the memory */ /* table returns the allocated memory and base addresses used during initialisation. */ /* */ /* PARAMETERS: */ /* hInstance Instance Handle */ /* pMemoryTable Pointer to an empty memory definition table */ /* pCapabilities Pointer to the instance capabilities */ /* */ /* RETURNS: */ /* LVDBE_SUCCESS Succeeded */ /* */ /* NOTES: */ /* 1. This function may be interrupted by the LVDBE_Process function */ /* */ /****************************************************************************************/ LVDBE_ReturnStatus_en LVDBE_Memory(LVDBE_Handle_t hInstance, LVDBE_MemTab_t *pMemoryTable, LVDBE_Capabilities_t *pCapabilities) { LVM_UINT32 ScratchSize; LVDBE_Instance_t *pInstance = (LVDBE_Instance_t *)hInstance; /* * Fill in the memory table */ if (hInstance == LVM_NULL) { /* * Instance memory */ pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Size = sizeof(LVDBE_Instance_t); pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Alignment = LVDBE_INSTANCE_ALIGN; pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].Type = LVDBE_PERSISTENT; pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress = LVM_NULL; /* * Data memory */ pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Size = sizeof(LVDBE_Data_t); pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Alignment = LVDBE_PERSISTENT_DATA_ALIGN; pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].Type = LVDBE_PERSISTENT_DATA; pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL; /* * Coef memory */ pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Size = sizeof(LVDBE_Coef_t); pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Alignment = LVDBE_PERSISTENT_COEF_ALIGN; pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].Type = LVDBE_PERSISTENT_COEF; pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL; /* * Scratch memory */ ScratchSize = (LVM_UINT32)(LVDBE_SCRATCHBUFFERS_INPLACE*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize); pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Size = ScratchSize; pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Alignment = LVDBE_SCRATCH_ALIGN; pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].Type = LVDBE_SCRATCH; pMemoryTable->Region[LVDBE_MEMREGION_SCRATCH].pBaseAddress = LVM_NULL; } else { /* Read back memory allocation table */ *pMemoryTable = pInstance->MemoryTable; } return(LVDBE_SUCCESS); } /****************************************************************************************/ /* */ /* FUNCTION: LVDBE_Init */ /* */ /* DESCRIPTION: */ /* Create and initialisation function for the Dynamic Bass Enhancement module */ /* */ /* This function can be used to create an algorithm instance by calling with */ /* hInstance set to NULL. In this case the algorithm returns the new instance */ /* handle. */ /* */ /* This function can be used to force a full re-initialisation of the algorithm */ /* by calling with hInstance = Instance Handle. In this case the memory table */ /* should be correct for the instance, this can be ensured by calling the function */ /* DBE_Memory before calling this function. */ /* */ /* PARAMETERS: */ /* hInstance Instance handle */ /* pMemoryTable Pointer to the memory definition table */ /* pCapabilities Pointer to the instance capabilities */ /* */ /* RETURNS: */ /* LVDBE_SUCCESS Initialisation succeeded */ /* LVDBE_ALIGNMENTERROR Instance or scratch memory on incorrect alignment */ /* LVDBE_NULLADDRESS Instance or scratch memory has a NULL pointer */ /* */ /* NOTES: */ /* 1. The instance handle is the pointer to the base address of the first memory */ /* region. */ /* 2. This function must not be interrupted by the LVDBE_Process function */ /* */ /****************************************************************************************/ LVDBE_ReturnStatus_en LVDBE_Init(LVDBE_Handle_t *phInstance, LVDBE_MemTab_t *pMemoryTable, LVDBE_Capabilities_t *pCapabilities) { LVDBE_Instance_t *pInstance; LVMixer3_1St_st *pMixer_Instance; LVMixer3_2St_st *pBypassMixer_Instance; LVM_INT16 i; LVM_INT32 MixGain; /* * Set the instance handle if not already initialised */ if (*phInstance == LVM_NULL) { *phInstance = (LVDBE_Handle_t)pMemoryTable->Region[LVDBE_MEMREGION_INSTANCE].pBaseAddress; } pInstance =(LVDBE_Instance_t *)*phInstance; /* * Check the memory table for NULL pointers and incorrectly aligned data */ for (i=0; iRegion[i].Size!=0) { if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL) { return(LVDBE_NULLADDRESS); } if (((LVM_UINT32)pMemoryTable->Region[i].pBaseAddress % pMemoryTable->Region[i].Alignment)!=0){ return(LVDBE_ALIGNMENTERROR); } } } /* * Save the memory table in the instance structure */ pInstance->Capabilities = *pCapabilities; /* * Save the memory table in the instance structure */ pInstance->MemoryTable = *pMemoryTable; /* * Set the default instance parameters */ pInstance->Params.CentreFrequency = LVDBE_CENTRE_55HZ; pInstance->Params.EffectLevel = 0; pInstance->Params.HeadroomdB = 0; pInstance->Params.HPFSelect = LVDBE_HPF_OFF; pInstance->Params.OperatingMode = LVDBE_OFF; pInstance->Params.SampleRate = LVDBE_FS_8000; pInstance->Params.VolumeControl = LVDBE_VOLUME_OFF; pInstance->Params.VolumedB = 0; /* * Set pointer to data and coef memory */ pInstance->pData = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_DATA].pBaseAddress; pInstance->pCoef = pMemoryTable->Region[LVDBE_MEMREGION_PERSISTENT_COEF].pBaseAddress; /* * Initialise the filters */ LVDBE_SetFilters(pInstance, /* Set the filter taps and coefficients */ &pInstance->Params); /* * Initialise the AGC */ LVDBE_SetAGC(pInstance, /* Set the AGC gain */ &pInstance->Params); pInstance->pData->AGCInstance.AGC_Gain = pInstance->pData->AGCInstance.AGC_MaxGain; /* Default to the bass boost setting */ // initialize the mixer with some fixes values since otherwise LVDBE_SetVolume ends up // reading uninitialized data pMixer_Instance = &pInstance->pData->BypassVolume; LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],0x00007FFF,0x00007FFF); /* * Initialise the volume */ LVDBE_SetVolume(pInstance, /* Set the Volume */ &pInstance->Params); pInstance->pData->AGCInstance.Volume = pInstance->pData->AGCInstance.Target; /* Initialise as the target */ MixGain = LVC_Mixer_GetTarget(&pMixer_Instance->MixerStream[0]); LVC_Mixer_Init(&pMixer_Instance->MixerStream[0],MixGain,MixGain); /* Configure the mixer process path */ pMixer_Instance->MixerStream[0].CallbackParam = 0; pMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL; pMixer_Instance->MixerStream[0].pCallBack = LVM_NULL; pMixer_Instance->MixerStream[0].CallbackSet = 0; /* * Initialise the clicks minimisation BypassMixer */ pBypassMixer_Instance = &pInstance->pData->BypassMixer; /* * Setup the mixer gain for the processed path */ pBypassMixer_Instance->MixerStream[0].CallbackParam = 0; pBypassMixer_Instance->MixerStream[0].pCallbackHandle = LVM_NULL; pBypassMixer_Instance->MixerStream[0].pCallBack = LVM_NULL; pBypassMixer_Instance->MixerStream[0].CallbackSet=0; LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[0],0,0); LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[0], LVDBE_BYPASS_MIXER_TC,pInstance->Params.SampleRate,2); /* * Setup the mixer gain for the unprocessed path */ pBypassMixer_Instance->MixerStream[1].CallbackParam = 0; pBypassMixer_Instance->MixerStream[1].pCallbackHandle = LVM_NULL; pBypassMixer_Instance->MixerStream[1].pCallBack = LVM_NULL; pBypassMixer_Instance->MixerStream[1].CallbackSet=0; LVC_Mixer_Init(&pBypassMixer_Instance->MixerStream[1],0x00007FFF,0x00007FFF); LVC_Mixer_SetTimeConstant(&pBypassMixer_Instance->MixerStream[1], LVDBE_BYPASS_MIXER_TC,pInstance->Params.SampleRate,2); return(LVDBE_SUCCESS); }