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#include    "LVPSA.h"
192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include    "LVPSA_Private.h"
202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include    "LVM_Macros.h"
212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#include    "VectorArithmetic.h"
222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent#define LVM_MININT_32   0x80000000
242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:            LVPSA_Process                                               */
292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                     */
312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  The process applies band pass filters to the signal. Each output                */
322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  feeds a quasi peak filter for level detection.                                  */
332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                      */
352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  hInstance           Pointer to the instance                                     */
362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pLVPSA_InputSamples Pointer to the input samples buffer                         */
372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  InputBlockSize      Number of mono samples to process                           */
382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  AudioTime           Playback time of the input samples                          */
392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                         */
422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVPSA_OK            Succeeds                                                    */
432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  otherwise           Error due to bad parameters                                 */
442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
46d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri#ifdef BUILD_FLOAT
47d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh KaturiLVPSA_RETURN LVPSA_Process           ( pLVPSA_Handle_t      hInstance,
48d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                       LVM_FLOAT           *pLVPSA_InputSamples,
49d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                       LVM_UINT16           InputBlockSize,
50d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                       LVPSA_Time           AudioTime            )
51d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
52d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri{
53d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    LVPSA_InstancePr_t     *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance;
54d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    LVM_FLOAT               *pScratch;
55d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    LVM_INT16               ii;
56d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    LVM_INT32               AudioTimeInc;
57d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    extern LVM_UINT32       LVPSA_SampleRateInvTab[];
58d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    LVM_UINT8               *pWrite_Save;         /* Position of the write pointer
59d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                                     at the beginning of the process  */
60d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
61d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    /******************************************************************************
62d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri       CHECK PARAMETERS
63d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    *******************************************************************************/
64d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    if(hInstance == LVM_NULL || pLVPSA_InputSamples == LVM_NULL)
65d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    {
66d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri        return(LVPSA_ERROR_NULLADDRESS);
67d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    }
68d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    if(InputBlockSize == 0 || InputBlockSize > pLVPSA_Inst->MaxInputBlockSize)
69d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    {
70d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri        return(LVPSA_ERROR_INVALIDPARAM);
71d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    }
72d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
73d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    pScratch = (LVM_FLOAT*)pLVPSA_Inst->MemoryTable.Region[LVPSA_MEMREGION_SCRATCH].pBaseAddress;
74d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    pWrite_Save = pLVPSA_Inst->pSpectralDataBufferWritePointer;
75d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
76d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    /******************************************************************************
77d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri       APPLY NEW SETTINGS IF NEEDED
78d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    *******************************************************************************/
79d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    if (pLVPSA_Inst->bControlPending == LVM_TRUE)
80d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    {
81d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri        pLVPSA_Inst->bControlPending = 0;
82d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri        LVPSA_ApplyNewSettings( pLVPSA_Inst);
83d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    }
84d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
85d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    /******************************************************************************
86d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri       PROCESS SAMPLES
87d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    *******************************************************************************/
88d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    /* Put samples in range [-0.5;0.5[ for BP filters (see Biquads documentation) */
89d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    Copy_Float(pLVPSA_InputSamples, pScratch, (LVM_INT16)InputBlockSize);
90d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    Shift_Sat_Float(-1, pScratch, pScratch, (LVM_INT16)InputBlockSize);
91d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
92d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    for (ii = 0; ii < pLVPSA_Inst->nRelevantFilters; ii++)
93d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    {
94d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri        switch(pLVPSA_Inst->pBPFiltersPrecision[ii])
95d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri        {
96d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri            case LVPSA_SimplePrecisionFilter:
97d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                BP_1I_D16F16C14_TRC_WRA_01  ( &pLVPSA_Inst->pBP_Instances[ii],
98d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                              pScratch,
99d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                              pScratch + InputBlockSize,
100d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                              (LVM_INT16)InputBlockSize);
101d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                break;
102d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
103d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri            case LVPSA_DoublePrecisionFilter:
104d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                BP_1I_D16F32C30_TRC_WRA_01  ( &pLVPSA_Inst->pBP_Instances[ii],
105d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                              pScratch,
106d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                              pScratch + InputBlockSize,
107d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                              (LVM_INT16)InputBlockSize);
108d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                break;
109d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri            default:
110d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                break;
111d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri        }
112d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
113d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
114d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri        LVPSA_QPD_Process_Float   ( pLVPSA_Inst,
115d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                    pScratch + InputBlockSize,
116d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                    (LVM_INT16)InputBlockSize,
117d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                                    ii);
118d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    }
119d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
120d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    /******************************************************************************
121d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri       UPDATE SpectralDataBufferAudioTime
122d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    *******************************************************************************/
123d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
124d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    if(pLVPSA_Inst->pSpectralDataBufferWritePointer != pWrite_Save)
125d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    {
126d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri        MUL32x32INTO32((AudioTime + (LVM_INT32)((LVM_INT32)pLVPSA_Inst->LocalSamplesCount*1000)),
127d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                        (LVM_INT32)LVPSA_SampleRateInvTab[pLVPSA_Inst->CurrentParams.Fs],
128d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                        AudioTimeInc,
129d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri                        LVPSA_FsInvertShift)
130d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri        pLVPSA_Inst->SpectralDataBufferAudioTime = AudioTime + AudioTimeInc;
131d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    }
132d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri
133d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri    return(LVPSA_OK);
134d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri}
135d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri#else
1362c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVPSA_RETURN LVPSA_Process           ( pLVPSA_Handle_t      hInstance,
1372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                       LVM_INT16           *pLVPSA_InputSamples,
1382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                       LVM_UINT16           InputBlockSize,
1392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                       LVPSA_Time           AudioTime            )
1402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
1422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVPSA_InstancePr_t     *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance;
1432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16               *pScratch;
1442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT16               ii;
1452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT32               AudioTimeInc;
1462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    extern LVM_UINT32       LVPSA_SampleRateInvTab[];
1472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_UINT8               *pWrite_Save;         /* Position of the write pointer at the beginning of the process  */
1482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /******************************************************************************
1502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent       CHECK PARAMETERS
1512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    *******************************************************************************/
1522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if(hInstance == LVM_NULL || pLVPSA_InputSamples == LVM_NULL)
1532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return(LVPSA_ERROR_NULLADDRESS);
1552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if(InputBlockSize == 0 || InputBlockSize > pLVPSA_Inst->MaxInputBlockSize)
1572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return(LVPSA_ERROR_INVALIDPARAM);
1592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pScratch = (LVM_INT16*)pLVPSA_Inst->MemoryTable.Region[LVPSA_MEMREGION_SCRATCH].pBaseAddress;
1622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    pWrite_Save = pLVPSA_Inst->pSpectralDataBufferWritePointer;
1632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /******************************************************************************
1652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent       APPLY NEW SETTINGS IF NEEDED
1662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    *******************************************************************************/
1672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if (pLVPSA_Inst->bControlPending == LVM_TRUE)
1682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pLVPSA_Inst->bControlPending = 0;
1702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        LVPSA_ApplyNewSettings( pLVPSA_Inst);
1712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
1722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /******************************************************************************
1742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent       PROCESS SAMPLES
1752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    *******************************************************************************/
1762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Put samples in range [-0.5;0.5[ for BP filters (see Biquads documentation) */
1772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    Copy_16( pLVPSA_InputSamples,pScratch,(LVM_INT16)InputBlockSize);
1782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    Shift_Sat_v16xv16(-1,pScratch,pScratch,(LVM_INT16)InputBlockSize);
1792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    for (ii = 0; ii < pLVPSA_Inst->nRelevantFilters; ii++)
1812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
1822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        switch(pLVPSA_Inst->pBPFiltersPrecision[ii])
1832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
1842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            case LVPSA_SimplePrecisionFilter:
1852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                BP_1I_D16F16C14_TRC_WRA_01  ( &pLVPSA_Inst->pBP_Instances[ii],
1862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                              pScratch,
1872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                              pScratch + InputBlockSize,
1882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                              (LVM_INT16)InputBlockSize);
1892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                break;
1902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
1912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            case LVPSA_DoublePrecisionFilter:
1922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                BP_1I_D16F32C30_TRC_WRA_01  ( &pLVPSA_Inst->pBP_Instances[ii],
1932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                              pScratch,
1942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                              pScratch + InputBlockSize,
1952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                              (LVM_INT16)InputBlockSize);
1962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                break;
1972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            default:
1982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                break;
1992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
2002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        LVPSA_QPD_Process   ( pLVPSA_Inst,
2032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                              pScratch + InputBlockSize,
2042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                              (LVM_INT16)InputBlockSize,
2052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                              ii);
2062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /******************************************************************************
2092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent       UPDATE SpectralDataBufferAudioTime
2102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    *******************************************************************************/
2112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if(pLVPSA_Inst->pSpectralDataBufferWritePointer != pWrite_Save)
2132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
2142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        MUL32x32INTO32((AudioTime + (LVM_INT32)((LVM_INT32)pLVPSA_Inst->LocalSamplesCount*1000)),
2152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                        (LVM_INT32)LVPSA_SampleRateInvTab[pLVPSA_Inst->CurrentParams.Fs],
2162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                        AudioTimeInc,
2172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                        LVPSA_FsInvertShift)
2182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pLVPSA_Inst->SpectralDataBufferAudioTime = AudioTime + AudioTimeInc;
2192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return(LVPSA_OK);
2222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
223d7d013446a64c6de9f0f2dfe098a721b140e0b48Ramesh Katuri#endif
2242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
2262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
2272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION:            LVPSA_GetSpectrum                                           */
2282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
2292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION:                                                                     */
2302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  Gets the levels values at a certain point in time                               */
2312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
2322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
2332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS:                                                                      */
2342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  hInstance            Pointer to the instance                                    */
2352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  GetSpectrumAudioTime Retrieve the values at this time                           */
2362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pCurrentValues       Pointer to a buffer that will contain levels' values       */
2372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  pMaxValues           Pointer to a buffer that will contain max levels' values   */
2382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
2392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
2402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS:                                                                         */
2412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  LVPSA_OK            Succeeds                                                    */
2422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*  otherwise           Error due to bad parameters                                 */
2432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/*                                                                                  */
2442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/
2452c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVPSA_RETURN LVPSA_GetSpectrum       ( pLVPSA_Handle_t      hInstance,
2462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                       LVPSA_Time           GetSpectrumAudioTime,
2472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                       LVM_UINT8           *pCurrentValues,
2482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                                       LVM_UINT8           *pPeakValues           )
2492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{
2512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVPSA_InstancePr_t      *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance;
2532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_INT32               StatusDelta, ii;
2542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    LVM_UINT8               *pRead;
2552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if(hInstance == LVM_NULL || pCurrentValues == LVM_NULL || pPeakValues == LVM_NULL)
2572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
2582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return(LVPSA_ERROR_NULLADDRESS);
2592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* First find the place where to look in the status buffer */
2632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if(GetSpectrumAudioTime <= pLVPSA_Inst->SpectralDataBufferAudioTime)
2642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
2652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        MUL32x32INTO32((pLVPSA_Inst->SpectralDataBufferAudioTime - GetSpectrumAudioTime),LVPSA_InternalRefreshTimeInv,StatusDelta,LVPSA_InternalRefreshTimeShift);
2662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if((StatusDelta * LVPSA_InternalRefreshTime) != (pLVPSA_Inst->SpectralDataBufferAudioTime - GetSpectrumAudioTime))
2672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
2682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            StatusDelta += 1;
2692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
2702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    else
2722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
2732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        /* This part handles the wrap around */
2742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        MUL32x32INTO32(((pLVPSA_Inst->SpectralDataBufferAudioTime - (LVM_INT32)LVM_MININT_32) + ((LVM_INT32)LVM_MAXINT_32 - GetSpectrumAudioTime)),LVPSA_InternalRefreshTimeInv,StatusDelta,LVPSA_InternalRefreshTimeShift)
2752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if(((LVM_INT32)(StatusDelta * LVPSA_InternalRefreshTime)) != ((LVM_INT32)((pLVPSA_Inst->SpectralDataBufferAudioTime - (LVM_INT32)LVM_MININT_32) + ((LVM_INT32)LVM_MAXINT_32 - GetSpectrumAudioTime))))
2762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
2772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            StatusDelta += 1;
2782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
2792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
2802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Check whether the desired level is not too "old" (see 2.10 in LVPSA_DesignNotes.doc)*/
2812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if(
2822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        ((GetSpectrumAudioTime < pLVPSA_Inst->SpectralDataBufferAudioTime)&&
2832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         ((GetSpectrumAudioTime<0)&&(pLVPSA_Inst->SpectralDataBufferAudioTime>0))&&
2842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         (((LVM_INT32)(-GetSpectrumAudioTime + pLVPSA_Inst->SpectralDataBufferAudioTime))>LVM_MAXINT_32))||
2852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         ((GetSpectrumAudioTime > pLVPSA_Inst->SpectralDataBufferAudioTime)&&
2872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         (((GetSpectrumAudioTime>=0)&&(pLVPSA_Inst->SpectralDataBufferAudioTime>=0))||
2882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent          ((GetSpectrumAudioTime<=0)&&(pLVPSA_Inst->SpectralDataBufferAudioTime<=0))||
2892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         (((GetSpectrumAudioTime>=0)&&(pLVPSA_Inst->SpectralDataBufferAudioTime<=0))&&
2902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent         (((LVM_INT32)(GetSpectrumAudioTime - pLVPSA_Inst->SpectralDataBufferAudioTime))<LVM_MAXINT_32))))||
2912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
2922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        (StatusDelta > (LVM_INT32)pLVPSA_Inst->SpectralDataBufferLength) ||
2932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        (!StatusDelta))
2942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
2952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        for(ii = 0; ii < pLVPSA_Inst->nBands; ii++)
2962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
2972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pCurrentValues[ii]  = 0;
2982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pPeakValues[ii]      = 0;
2992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
3002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        return(LVPSA_OK);
3012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
3022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Set the reading pointer */
3032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    if((LVM_INT32)(StatusDelta * pLVPSA_Inst->nBands) > (pLVPSA_Inst->pSpectralDataBufferWritePointer - pLVPSA_Inst->pSpectralDataBufferStart))
3042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
3052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pRead = pLVPSA_Inst->pSpectralDataBufferWritePointer + (pLVPSA_Inst->SpectralDataBufferLength - (LVM_UINT32)StatusDelta) * pLVPSA_Inst->nBands;
3062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
3072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    else
3082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
3092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pRead = pLVPSA_Inst->pSpectralDataBufferWritePointer  - StatusDelta * pLVPSA_Inst->nBands;
3102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
3112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    /* Read the status buffer and fill the output buffers */
3142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    for(ii = 0; ii < pLVPSA_Inst->nBands; ii++)
3152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    {
3162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pCurrentValues[ii] = pRead[ii];
3172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        if(pLVPSA_Inst->pPreviousPeaks[ii] <= pRead[ii])
3182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
3192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pLVPSA_Inst->pPreviousPeaks[ii] = pRead[ii];
3202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
3212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        else if(pLVPSA_Inst->pPreviousPeaks[ii] != 0)
3222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        {
3232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            LVM_INT32 temp;
3242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /*Re-compute max values for decay */
3252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            temp = (LVM_INT32)(LVPSA_MAXUNSIGNEDCHAR - pLVPSA_Inst->pPreviousPeaks[ii]);
3262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            temp = ((temp * LVPSA_MAXLEVELDECAYFACTOR)>>LVPSA_MAXLEVELDECAYSHIFT);
3272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /* If the gain has no effect, "help" the value to increase */
3282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            if(temp == (LVPSA_MAXUNSIGNEDCHAR - pLVPSA_Inst->pPreviousPeaks[ii]))
3292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            {
3302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent                temp += 1;
3312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            }
3322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /* Saturate */
3332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            temp = (temp > LVPSA_MAXUNSIGNEDCHAR) ? LVPSA_MAXUNSIGNEDCHAR : temp;
3342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            /* Store new max level */
3352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent            pLVPSA_Inst->pPreviousPeaks[ii] =  (LVM_UINT8)(LVPSA_MAXUNSIGNEDCHAR - temp);
3362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        }
3372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent        pPeakValues[ii] = pLVPSA_Inst->pPreviousPeaks[ii];
3392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    }
3402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent
3412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent    return(LVPSA_OK);
3422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent}
343