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/************************************************************************************/ 462c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVPSA_RETURN LVPSA_Process ( pLVPSA_Handle_t hInstance, 472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 *pLVPSA_InputSamples, 482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_UINT16 InputBlockSize, 492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVPSA_Time AudioTime ) 502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{ 522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVPSA_InstancePr_t *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance; 532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 *pScratch; 542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT16 ii; 552c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT32 AudioTimeInc; 562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent extern LVM_UINT32 LVPSA_SampleRateInvTab[]; 572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_UINT8 *pWrite_Save; /* Position of the write pointer at the beginning of the process */ 582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /****************************************************************************** 602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent CHECK PARAMETERS 612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *******************************************************************************/ 622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(hInstance == LVM_NULL || pLVPSA_InputSamples == LVM_NULL) 632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return(LVPSA_ERROR_NULLADDRESS); 652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(InputBlockSize == 0 || InputBlockSize > pLVPSA_Inst->MaxInputBlockSize) 672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return(LVPSA_ERROR_INVALIDPARAM); 692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pScratch = (LVM_INT16*)pLVPSA_Inst->MemoryTable.Region[LVPSA_MEMREGION_SCRATCH].pBaseAddress; 722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pWrite_Save = pLVPSA_Inst->pSpectralDataBufferWritePointer; 732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /****************************************************************************** 752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent APPLY NEW SETTINGS IF NEEDED 762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *******************************************************************************/ 772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if (pLVPSA_Inst->bControlPending == LVM_TRUE) 782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pLVPSA_Inst->bControlPending = 0; 802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVPSA_ApplyNewSettings( pLVPSA_Inst); 812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /****************************************************************************** 842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent PROCESS SAMPLES 852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *******************************************************************************/ 862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Put samples in range [-0.5;0.5[ for BP filters (see Biquads documentation) */ 872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Copy_16( pLVPSA_InputSamples,pScratch,(LVM_INT16)InputBlockSize); 882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent Shift_Sat_v16xv16(-1,pScratch,pScratch,(LVM_INT16)InputBlockSize); 892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent for (ii = 0; ii < pLVPSA_Inst->nRelevantFilters; ii++) 912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent switch(pLVPSA_Inst->pBPFiltersPrecision[ii]) 932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent case LVPSA_SimplePrecisionFilter: 952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent BP_1I_D16F16C14_TRC_WRA_01 ( &pLVPSA_Inst->pBP_Instances[ii], 962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pScratch, 972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pScratch + InputBlockSize, 982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)InputBlockSize); 992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent break; 1002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent case LVPSA_DoublePrecisionFilter: 1022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent BP_1I_D16F32C30_TRC_WRA_01 ( &pLVPSA_Inst->pBP_Instances[ii], 1032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pScratch, 1042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pScratch + InputBlockSize, 1052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)InputBlockSize); 1062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent break; 1072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent default: 1082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent break; 1092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVPSA_QPD_Process ( pLVPSA_Inst, 1132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pScratch + InputBlockSize, 1142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT16)InputBlockSize, 1152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent ii); 1162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /****************************************************************************** 1192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent UPDATE SpectralDataBufferAudioTime 1202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent *******************************************************************************/ 1212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(pLVPSA_Inst->pSpectralDataBufferWritePointer != pWrite_Save) 1232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 1242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent MUL32x32INTO32((AudioTime + (LVM_INT32)((LVM_INT32)pLVPSA_Inst->LocalSamplesCount*1000)), 1252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (LVM_INT32)LVPSA_SampleRateInvTab[pLVPSA_Inst->CurrentParams.Fs], 1262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent AudioTimeInc, 1272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVPSA_FsInvertShift) 1282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pLVPSA_Inst->SpectralDataBufferAudioTime = AudioTime + AudioTimeInc; 1292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return(LVPSA_OK); 1322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent} 1332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/ 1362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* FUNCTION: LVPSA_GetSpectrum */ 1382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* DESCRIPTION: */ 1402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* Gets the levels values at a certain point in time */ 1412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* PARAMETERS: */ 1442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* hInstance Pointer to the instance */ 1452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* GetSpectrumAudioTime Retrieve the values at this time */ 1462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* pCurrentValues Pointer to a buffer that will contain levels' values */ 1472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* pMaxValues Pointer to a buffer that will contain max levels' values */ 1482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* RETURNS: */ 1512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* LVPSA_OK Succeeds */ 1522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* otherwise Error due to bad parameters */ 1532c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/* */ 1542c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent/************************************************************************************/ 1552c8e5cab3faa6d360e222b7a6c40a80083d021acEric LaurentLVPSA_RETURN LVPSA_GetSpectrum ( pLVPSA_Handle_t hInstance, 1562c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVPSA_Time GetSpectrumAudioTime, 1572c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_UINT8 *pCurrentValues, 1582c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_UINT8 *pPeakValues ) 1592c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1602c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent{ 1612c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1622c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVPSA_InstancePr_t *pLVPSA_Inst = (LVPSA_InstancePr_t*)hInstance; 1632c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT32 StatusDelta, ii; 1642c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_UINT8 *pRead; 1652c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1662c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(hInstance == LVM_NULL || pCurrentValues == LVM_NULL || pPeakValues == LVM_NULL) 1672c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 1682c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return(LVPSA_ERROR_NULLADDRESS); 1692c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1702c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1712c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1722c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* First find the place where to look in the status buffer */ 1732c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(GetSpectrumAudioTime <= pLVPSA_Inst->SpectralDataBufferAudioTime) 1742c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 1752c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent MUL32x32INTO32((pLVPSA_Inst->SpectralDataBufferAudioTime - GetSpectrumAudioTime),LVPSA_InternalRefreshTimeInv,StatusDelta,LVPSA_InternalRefreshTimeShift); 1762c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if((StatusDelta * LVPSA_InternalRefreshTime) != (pLVPSA_Inst->SpectralDataBufferAudioTime - GetSpectrumAudioTime)) 1772c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 1782c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent StatusDelta += 1; 1792c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1802c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1812c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent else 1822c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 1832c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* This part handles the wrap around */ 1842c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent MUL32x32INTO32(((pLVPSA_Inst->SpectralDataBufferAudioTime - (LVM_INT32)LVM_MININT_32) + ((LVM_INT32)LVM_MAXINT_32 - GetSpectrumAudioTime)),LVPSA_InternalRefreshTimeInv,StatusDelta,LVPSA_InternalRefreshTimeShift) 1852c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(((LVM_INT32)(StatusDelta * LVPSA_InternalRefreshTime)) != ((LVM_INT32)((pLVPSA_Inst->SpectralDataBufferAudioTime - (LVM_INT32)LVM_MININT_32) + ((LVM_INT32)LVM_MAXINT_32 - GetSpectrumAudioTime)))) 1862c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 1872c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent StatusDelta += 1; 1882c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1892c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 1902c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Check whether the desired level is not too "old" (see 2.10 in LVPSA_DesignNotes.doc)*/ 1912c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if( 1922c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent ((GetSpectrumAudioTime < pLVPSA_Inst->SpectralDataBufferAudioTime)&& 1932c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent ((GetSpectrumAudioTime<0)&&(pLVPSA_Inst->SpectralDataBufferAudioTime>0))&& 1942c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (((LVM_INT32)(-GetSpectrumAudioTime + pLVPSA_Inst->SpectralDataBufferAudioTime))>LVM_MAXINT_32))|| 1952c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 1962c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent ((GetSpectrumAudioTime > pLVPSA_Inst->SpectralDataBufferAudioTime)&& 1972c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (((GetSpectrumAudioTime>=0)&&(pLVPSA_Inst->SpectralDataBufferAudioTime>=0))|| 1982c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent ((GetSpectrumAudioTime<=0)&&(pLVPSA_Inst->SpectralDataBufferAudioTime<=0))|| 1992c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (((GetSpectrumAudioTime>=0)&&(pLVPSA_Inst->SpectralDataBufferAudioTime<=0))&& 2002c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (((LVM_INT32)(GetSpectrumAudioTime - pLVPSA_Inst->SpectralDataBufferAudioTime))<LVM_MAXINT_32))))|| 2012c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2022c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (StatusDelta > (LVM_INT32)pLVPSA_Inst->SpectralDataBufferLength) || 2032c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent (!StatusDelta)) 2042c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2052c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent for(ii = 0; ii < pLVPSA_Inst->nBands; ii++) 2062c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2072c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pCurrentValues[ii] = 0; 2082c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pPeakValues[ii] = 0; 2092c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2102c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return(LVPSA_OK); 2112c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2122c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Set the reading pointer */ 2132c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if((LVM_INT32)(StatusDelta * pLVPSA_Inst->nBands) > (pLVPSA_Inst->pSpectralDataBufferWritePointer - pLVPSA_Inst->pSpectralDataBufferStart)) 2142c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2152c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pRead = pLVPSA_Inst->pSpectralDataBufferWritePointer + (pLVPSA_Inst->SpectralDataBufferLength - (LVM_UINT32)StatusDelta) * pLVPSA_Inst->nBands; 2162c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2172c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent else 2182c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2192c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pRead = pLVPSA_Inst->pSpectralDataBufferWritePointer - StatusDelta * pLVPSA_Inst->nBands; 2202c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2212c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2222c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2232c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Read the status buffer and fill the output buffers */ 2242c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent for(ii = 0; ii < pLVPSA_Inst->nBands; ii++) 2252c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2262c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pCurrentValues[ii] = pRead[ii]; 2272c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(pLVPSA_Inst->pPreviousPeaks[ii] <= pRead[ii]) 2282c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2292c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pLVPSA_Inst->pPreviousPeaks[ii] = pRead[ii]; 2302c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2312c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent else if(pLVPSA_Inst->pPreviousPeaks[ii] != 0) 2322c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2332c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent LVM_INT32 temp; 2342c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /*Re-compute max values for decay */ 2352c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent temp = (LVM_INT32)(LVPSA_MAXUNSIGNEDCHAR - pLVPSA_Inst->pPreviousPeaks[ii]); 2362c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent temp = ((temp * LVPSA_MAXLEVELDECAYFACTOR)>>LVPSA_MAXLEVELDECAYSHIFT); 2372c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* If the gain has no effect, "help" the value to increase */ 2382c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent if(temp == (LVPSA_MAXUNSIGNEDCHAR - pLVPSA_Inst->pPreviousPeaks[ii])) 2392c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent { 2402c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent temp += 1; 2412c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2422c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Saturate */ 2432c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent temp = (temp > LVPSA_MAXUNSIGNEDCHAR) ? LVPSA_MAXUNSIGNEDCHAR : temp; 2442c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent /* Store new max level */ 2452c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pLVPSA_Inst->pPreviousPeaks[ii] = (LVM_UINT8)(LVPSA_MAXUNSIGNEDCHAR - temp); 2462c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2472c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2482c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent pPeakValues[ii] = pLVPSA_Inst->pPreviousPeaks[ii]; 2492c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent } 2502c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent 2512c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent return(LVPSA_OK); 2522c8e5cab3faa6d360e222b7a6c40a80083d021acEric Laurent} 253