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#include    "LVPSA.h"
19#include    "LVPSA_Private.h"
20#include    "InstAlloc.h"
21
22/****************************************************************************************/
23/*                                                                                      */
24/* FUNCTION:                LVEQNB_Memory                                               */
25/*                                                                                      */
26/* DESCRIPTION:                                                                         */
27/*  This function is used for memory allocation and free. It can be called in           */
28/*  two ways:                                                                           */
29/*                                                                                      */
30/*      hInstance = NULL         Returns the memory requirements                        */
31/*      hInstance = Instance handle     Returns the memory requirements and             */
32/*                                      allocated base addresses for the instance       */
33/*                                                                                      */
34/*  When this function is called for memory allocation (hInstance=NULL) the memory      */
35/*  base address pointers are NULL on return.                                           */
36/*                                                                                      */
37/*  When the function is called for free (hInstance = Instance Handle) the memory       */
38/*  table returns the allocated memory and base addresses used during initialisation.   */
39/*                                                                                      */
40/* PARAMETERS:                                                                          */
41/*  hInstance               Instance Handle                                             */
42/*  pMemoryTable            Pointer to an empty memory definition table                 */
43/*  InitParams              Pointer to the instance init parameters                     */
44/*                                                                                      */
45/* RETURNS:                                                                             */
46/*  LVPSA_OK            Succeeds                                                        */
47/*  otherwise           Error due to bad parameters                                     */
48/*                                                                                      */
49/****************************************************************************************/
50LVPSA_RETURN LVPSA_Memory            ( pLVPSA_Handle_t             hInstance,
51                                       LVPSA_MemTab_t             *pMemoryTable,
52                                       LVPSA_InitParams_t         *pInitParams    )
53{
54    LVM_UINT32          ii;
55    LVM_UINT32          BufferLength;
56    INST_ALLOC          Instance;
57    INST_ALLOC          Scratch;
58    INST_ALLOC          Data;
59    INST_ALLOC          Coef;
60    LVPSA_InstancePr_t *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance;
61
62
63    InstAlloc_Init( &Instance   , LVM_NULL);
64    InstAlloc_Init( &Scratch    , LVM_NULL);
65    InstAlloc_Init( &Data       , LVM_NULL);
66    InstAlloc_Init( &Coef       , LVM_NULL);
67
68
69    if((pMemoryTable == LVM_NULL) || (pInitParams == LVM_NULL))
70    {
71        return(LVPSA_ERROR_NULLADDRESS);
72    }
73
74
75    /*
76     * Fill in the memory table
77     */
78    if (hInstance == LVM_NULL)
79    {
80
81        /* Check init parameter */
82        if( (pInitParams->SpectralDataBufferDuration > LVPSA_MAXBUFFERDURATION)   ||
83            (pInitParams->SpectralDataBufferDuration == 0)                        ||
84            (pInitParams->MaxInputBlockSize > LVPSA_MAXINPUTBLOCKSIZE)      ||
85            (pInitParams->MaxInputBlockSize == 0)                           ||
86            (pInitParams->nBands < LVPSA_NBANDSMIN)                         ||
87            (pInitParams->nBands > LVPSA_NBANDSMAX)                         ||
88            (pInitParams->pFiltersParams == 0))
89        {
90            return(LVPSA_ERROR_INVALIDPARAM);
91        }
92        for(ii = 0; ii < pInitParams->nBands; ii++)
93        {
94            if((pInitParams->pFiltersParams[ii].CenterFrequency > LVPSA_MAXCENTERFREQ) ||
95               (pInitParams->pFiltersParams[ii].PostGain        > LVPSA_MAXPOSTGAIN)   ||
96               (pInitParams->pFiltersParams[ii].PostGain        < LVPSA_MINPOSTGAIN)   ||
97               (pInitParams->pFiltersParams[ii].QFactor < LVPSA_MINQFACTOR)            ||
98               (pInitParams->pFiltersParams[ii].QFactor > LVPSA_MAXQFACTOR))
99               {
100                    return(LVPSA_ERROR_INVALIDPARAM);
101               }
102        }
103
104        /*
105         * Instance memory
106         */
107
108        InstAlloc_AddMember( &Instance, sizeof(LVPSA_InstancePr_t) );
109        InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_UINT16) );
110        InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVPSA_FilterParam_t) );
111
112        {
113            /* for avoiding QAC warnings as MUL32x32INTO32 works on LVM_INT32 only*/
114            LVM_INT32 SDBD=(LVM_INT32)pInitParams->SpectralDataBufferDuration;
115            LVM_INT32 IRTI=(LVM_INT32)LVPSA_InternalRefreshTimeInv;
116            LVM_INT32 BL;
117
118            MUL32x32INTO32(SDBD,IRTI,BL,LVPSA_InternalRefreshTimeShift)
119            BufferLength=(LVM_UINT32)BL;
120        }
121
122
123        if((BufferLength * LVPSA_InternalRefreshTime) != pInitParams->SpectralDataBufferDuration)
124        {
125            BufferLength++;
126        }
127        InstAlloc_AddMember( &Instance, pInitParams->nBands * BufferLength * sizeof(LVM_UINT8) );
128        InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVM_UINT8) );
129        InstAlloc_AddMember( &Instance, pInitParams->nBands * sizeof(LVPSA_BPFilterPrecision_en) );
130        pMemoryTable->Region[LVPSA_MEMREGION_INSTANCE].Size         = InstAlloc_GetTotal(&Instance);
131        pMemoryTable->Region[LVPSA_MEMREGION_INSTANCE].Type         = LVPSA_PERSISTENT;
132        pMemoryTable->Region[LVPSA_MEMREGION_INSTANCE].pBaseAddress = LVM_NULL;
133
134        /*
135         * Scratch memory
136         */
137        InstAlloc_AddMember( &Scratch, 2 * pInitParams->MaxInputBlockSize * sizeof(LVM_INT16) );
138        pMemoryTable->Region[LVPSA_MEMREGION_SCRATCH].Size         = InstAlloc_GetTotal(&Scratch);
139        pMemoryTable->Region[LVPSA_MEMREGION_SCRATCH].Type         = LVPSA_SCRATCH;
140        pMemoryTable->Region[LVPSA_MEMREGION_SCRATCH].pBaseAddress = LVM_NULL;
141
142        /*
143         * Persistent coefficients memory
144         */
145        InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(Biquad_Instance_t) );
146        InstAlloc_AddMember( &Coef, pInitParams->nBands * sizeof(QPD_State_t) );
147        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_COEF].Size         = InstAlloc_GetTotal(&Coef);
148        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_COEF].Type         = LVPSA_PERSISTENT_COEF;
149        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;
150
151        /*
152         * Persistent data memory
153         */
154        InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(Biquad_1I_Order2_Taps_t) );
155        InstAlloc_AddMember( &Data, pInitParams->nBands * sizeof(QPD_Taps_t) );
156        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_DATA].Size         = InstAlloc_GetTotal(&Data);
157        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_DATA].Type         = LVPSA_PERSISTENT_DATA;
158        pMemoryTable->Region[LVPSA_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;
159
160    }
161    else
162    {
163        /* Read back memory allocation table */
164        *pMemoryTable = pLVPSA_Inst->MemoryTable;
165    }
166
167    return(LVPSA_OK);
168}
169
170