12c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*
22c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Copyright (C) 2004-2010 NXP Software
32c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Copyright (C) 2010 The Android Open Source Project
42c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *
52c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
62c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * you may not use this file except in compliance with the License.
72c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * You may obtain a copy of the License at
82c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *
92c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *
112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * Unless required by applicable law or agreed to in writing, software
122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * See the License for the specific language governing permissions and
152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent * limitations under the License.
162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent */
172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  Includes                                                                            */
222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVEQNB.h"
262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "LVEQNB_Private.h"
272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include "InstAlloc.h"
28377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT#include <string.h> /* For memset */
292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                LVEQNB_Memory                                               */
332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                         */
352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  This function is used for memory allocation and free. It can be called in           */
362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  two ways:                                                                           */
372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*      hInstance = NULL                Returns the memory requirements                 */
392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*      hInstance = Instance handle     Returns the memory requirements and             */
402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                      allocated base addresses for the instance       */
412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  When this function is called for memory allocation (hInstance=NULL) the memory      */
432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  base address pointers are NULL on return.                                           */
442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  When the function is called for free (hInstance = Instance Handle) the memory       */
462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  table returns the allocated memory and base addresses used during initialisation.   */
472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                          */
492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  hInstance               Instance Handle                                             */
502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pMemoryTable            Pointer to an empty memory definition table                 */
512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pCapabilities           Pointer to the instance capabilities                        */
522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                             */
542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVEQNB_SUCCESS          Succeeded                                                   */
552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVEQNB_NULLADDRESS      When any of pMemoryTable and pCapabilities is NULL address  */
562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                               */
582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  1.  This function may be interrupted by the LVEQNB_Process function                 */
592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
622c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVEQNB_ReturnStatus_en LVEQNB_Memory(LVEQNB_Handle_t            hInstance,
632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                     LVEQNB_MemTab_t            *pMemoryTable,
642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                     LVEQNB_Capabilities_t      *pCapabilities)
652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    INST_ALLOC          AllocMem;
682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVEQNB_Instance_t   *pInstance = (LVEQNB_Instance_t *)hInstance;
692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if((pMemoryTable == LVM_NULL)|| (pCapabilities == LVM_NULL))
722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return LVEQNB_NULLADDRESS;
742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Fill in the memory table
792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (hInstance == LVM_NULL)
812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Instance memory
842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_Init(&AllocMem,
862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                       LVM_NULL);
872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            sizeof(LVEQNB_Instance_t));
892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Size         = InstAlloc_GetTotal(&AllocMem);
902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Alignment    = LVEQNB_INSTANCE_ALIGN;
912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Type         = LVEQNB_PERSISTENT;
922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].pBaseAddress = LVM_NULL;
932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Persistant data memory
972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_Init(&AllocMem,
992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                       LVM_NULL);
1002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
1012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            sizeof(Biquad_2I_Order2_Taps_t));
1022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_AddMember(&AllocMem,                              /* High pass filter */
1032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            sizeof(Biquad_2I_Order2_Taps_t));
1042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_AddMember(&AllocMem,
1052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_Taps_t))); /* Equaliser Biquad Taps */
1062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_AddMember(&AllocMem,
1072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            (pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t)));        /* Filter definitions */
1082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_AddMember(&AllocMem,
1092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            (pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en)));    /* Biquad types */
1102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Size         = InstAlloc_GetTotal(&AllocMem);
1112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Alignment    = LVEQNB_DATA_ALIGN;
1122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Type         = LVEQNB_PERSISTENT_DATA;
1132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;
1142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
1162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Persistant coefficient memory
1172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
1182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_Init(&AllocMem,
1192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                       LVM_NULL);
1202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
1212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            sizeof(Biquad_Instance_t));
1222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_AddMember(&AllocMem,                              /* High pass filter */
1232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            sizeof(Biquad_Instance_t));
1242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_AddMember(&AllocMem,
1252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            pCapabilities->MaxBands * sizeof(Biquad_Instance_t)); /* Equaliser Biquad Instance */
1262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Size         = InstAlloc_GetTotal(&AllocMem);
1272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Alignment    = LVEQNB_COEF_ALIGN;
1282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Type         = LVEQNB_PERSISTENT_COEF;
1292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;
1302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /*
1322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         * Scratch memory
1332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         */
1342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_Init(&AllocMem,
1352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                       LVM_NULL);
1362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        InstAlloc_AddMember(&AllocMem,                              /* Low pass filter */
1372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                            LVEQNB_SCRATCHBUFFERS*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize);
1382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Size              = InstAlloc_GetTotal(&AllocMem);
1392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Alignment         = LVEQNB_SCRATCH_ALIGN;
1402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Type              = LVEQNB_SCRATCH;
1412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress      = LVM_NULL;
1422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    else
1442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /* Read back memory allocation table */
1462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        *pMemoryTable = pInstance->MemoryTable;
1472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return(LVEQNB_SUCCESS);
1502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
1512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
1542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
1552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:                LVEQNB_Init                                                 */
1562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
1572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                         */
1582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  Create and initialisation function for the N-Band equaliser module                  */
1592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
1602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  This function can be used to create an algorithm instance by calling with           */
1612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  hInstance set to NULL. In this case the algorithm returns the new instance          */
1622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  handle.                                                                             */
1632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
1642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  This function can be used to force a full re-initialisation of the algorithm        */
1652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  by calling with hInstance = Instance Handle. In this case the memory table          */
1662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  should be correct for the instance, this can be ensured by calling the function     */
1672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  DBE_Memory before calling this function.                                            */
1682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
1692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                          */
1702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  hInstance               Instance handle                                             */
1712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pMemoryTable            Pointer to the memory definition table                      */
1722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pCapabilities           Pointer to the instance capabilities                        */
1732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
1742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                             */
1752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVEQNB_SUCCESS          Initialisation succeeded                                    */
1762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVEQNB_NULLADDRESS        When pCapabilities or pMemoryTableis or phInstance are NULL */
1772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVEQNB_NULLADDRESS        One or more of the memory regions has a NULL base address   */
1782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                          pointer for a memory region with a non-zero size.           */
1792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
1802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* NOTES:                                                                               */
1812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  1.  The instance handle is the pointer to the base address of the first memory      */
1822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*      region.                                                                         */
1832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  2.  This function must not be interrupted by the LVEQNB_Process function            */
1842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                      */
1852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/****************************************************************************************/
1862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1872c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVEQNB_ReturnStatus_en LVEQNB_Init(LVEQNB_Handle_t          *phInstance,
1882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                   LVEQNB_MemTab_t          *pMemoryTable,
1892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                   LVEQNB_Capabilities_t    *pCapabilities)
1902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
1912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVEQNB_Instance_t   *pInstance;
1932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_UINT32          MemSize;
1942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    INST_ALLOC          AllocMem;
1952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT32           i;
1962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
1982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check for NULL pointers
1992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if((phInstance == LVM_NULL) || (pMemoryTable == LVM_NULL) || (pCapabilities == LVM_NULL))
2012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
2022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return LVEQNB_NULLADDRESS;
2032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Check the memory table for NULL pointers
2072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    for (i = 0; i < LVEQNB_NR_MEMORY_REGIONS; i++)
2092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
2102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if (pMemoryTable->Region[i].Size!=0)
2112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
2122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL)
2132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            {
2142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                return(LVEQNB_NULLADDRESS);
2152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            }
2162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
2172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Set the instance handle if not already initialised
2212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    InstAlloc_Init(&AllocMem,  pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].pBaseAddress);
2242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (*phInstance == LVM_NULL)
2262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
2272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        *phInstance = InstAlloc_AddMember(&AllocMem, sizeof(LVEQNB_Instance_t));
2282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance =(LVEQNB_Instance_t  *)*phInstance;
2302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Save the memory table in the instance structure
2352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->Capabilities = *pCapabilities;
2372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Save the memory table in the instance structure and
2412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * set the structure pointers
2422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->MemoryTable       = *pMemoryTable;
2442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Allocate coefficient memory
2472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    InstAlloc_Init(&AllocMem,
2492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                   pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress);
2502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->pEQNB_FilterState = InstAlloc_AddMember(&AllocMem,
2522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                                       pCapabilities->MaxBands * sizeof(Biquad_Instance_t)); /* Equaliser Biquad Instance */
2532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Allocate data memory
2582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    InstAlloc_Init(&AllocMem,
2602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                   pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress);
2612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    MemSize = (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_Taps_t));
2632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->pEQNB_Taps = (Biquad_2I_Order2_Taps_t *)InstAlloc_AddMember(&AllocMem,
2642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                                                           MemSize);
2652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    MemSize = (pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t));
2662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->pBandDefinitions  = (LVEQNB_BandDef_t *)InstAlloc_AddMember(&AllocMem,
2672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                                                           MemSize);
26897bb6e89845cb6d85f4d34a4efcc1de2ce585336Marco Nelissen    // clear all the bands, setting their gain to 0, otherwise when applying new params,
26997bb6e89845cb6d85f4d34a4efcc1de2ce585336Marco Nelissen    // it will compare against uninitialized values
27097bb6e89845cb6d85f4d34a4efcc1de2ce585336Marco Nelissen    memset(pInstance->pBandDefinitions, 0, MemSize);
2712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    MemSize = (pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en));
2722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->pBiquadType = (LVEQNB_BiquadType_en *)InstAlloc_AddMember(&AllocMem,
2732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                                                         MemSize);
2742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Internally map, structure and allign scratch memory
2782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    InstAlloc_Init(&AllocMem,
2802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                   pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress);
2812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->pFastTemporary = (LVM_INT16 *)InstAlloc_AddMember(&AllocMem,
2832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                                                 sizeof(LVM_INT16));
2842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Update the instance parameters
2872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->Params.NBands          = 0;
2892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->Params.OperatingMode   = LVEQNB_BYPASS;
2902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->Params.pBandDefinition = LVM_NULL;
2912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->Params.SampleRate      = LVEQNB_FS_8000;
2922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->Params.SourceFormat    = LVEQNB_STEREO;
2932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
2952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Initialise the filters
2962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
2972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVEQNB_SetFilters(pInstance,                        /* Set the filter types */
2982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                      &pInstance->Params);
2992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVEQNB_SetCoefficients(pInstance);                  /* Set the filter coefficients */
3012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVEQNB_ClearFilterHistory(pInstance);               /* Clear the filter history */
3032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /*
3052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     * Initialise the bypass variables
3062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent     */
3072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->BypassMixer.MixerStream[0].CallbackSet        = 0;
3082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->BypassMixer.MixerStream[0].CallbackParam      = 0;
3092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->BypassMixer.MixerStream[0].pCallbackHandle    = (void*)pInstance;
3102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->BypassMixer.MixerStream[0].pCallBack          = LVEQNB_BypassMixerCallBack;
3112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[0],0,0);
3122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],0,LVM_FS_8000,2);
3132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->BypassMixer.MixerStream[1].CallbackSet        = 1;
3152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->BypassMixer.MixerStream[1].CallbackParam      = 0;
3162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->BypassMixer.MixerStream[1].pCallbackHandle    = LVM_NULL;
3172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->BypassMixer.MixerStream[1].pCallBack          = LVM_NULL;
3182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[1],0,LVM_MAXINT_16);
3192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],0,LVM_FS_8000,2);
3202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pInstance->bInOperatingModeTransition      = LVM_FALSE;
3222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return(LVEQNB_SUCCESS);
3242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
3252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
326