M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions

View File

@ -0,0 +1,298 @@
/*
* Copyright (C) 2004-2010 NXP Software
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/****************************************************************************************/
/* */
/* Includes */
/* */
/****************************************************************************************/
#include "LVEQNB_Private.h"
/****************************************************************************************/
/* */
/* Defines */
/* */
/****************************************************************************************/
#define PI 3.14159265358979
/****************************************************************************************/
/* */
/* FUNCTION: LVEQNB_DoublePrecCoefs */
/* */
/* DESCRIPTION: */
/* Calculate double precision coefficients for a peaking filter */
/* */
/* PARAMETERS: */
/* Fs Sampling frequency index */
/* pFilterDefinition Pointer to the filter definition */
/* pCoefficients Pointer to the coefficients */
/* */
/* RETURNS: */
/* LVEQNB_SUCCESS Always succeeds */
/* */
/* NOTES: */
/* 1. The equations used are as follows: */
/* */
/* G = 10^(GaindB/20) - 1 */
/* t0 = 2 * Pi * Fc / Fs */
/* D = 1 if GaindB >= 0 */
/* D = 1 / (1 + G) if GaindB < 0 */
/* */
/* b2 = -0.5 * (2Q - D * t0) / (2Q + D * t0) */
/* b1 = (0.5 - b2) * (1 - coserr(t0)) */
/* a0 = (0.5 + b2) / 2 */
/* */
/* Where: */
/* GaindB is the gain in dBs, range -15dB to +15dB */
/* Fc is the centre frequency, DC to Fs/50 */
/* Fs is the sample frequency, 8000 to 48000 in descrete steps */
/* Q is the Q factor, 0.25 to 12 (represented by 25 to 1200) */
/* */
/* 2. The double precision coefficients are only used when fc is less than fs/85, so */
/* the cosine of t0 is always close to 1.0. Instead of calculating the cosine */
/* itself the difference from the value 1.0 is calculated, this can be done with */
/* lower precision maths. */
/* */
/* 3. The value of the B2 coefficient is only calculated as a single precision value, */
/* small errors in this value have a combined effect on the Q and Gain but not the */
/* the frequency of the filter. */
/* */
/****************************************************************************************/
LVEQNB_ReturnStatus_en LVEQNB_DoublePrecCoefs(LVM_UINT16 Fs,
LVEQNB_BandDef_t *pFilterDefinition,
PK_C32_Coefs_t *pCoefficients)
{
extern LVM_INT16 LVEQNB_GainTable[];
extern LVM_INT16 LVEQNB_TwoPiOnFsTable[];
extern LVM_INT16 LVEQNB_DTable[];
extern LVM_INT16 LVEQNB_DPCosCoef[];
/*
* Get the filter definition
*/
LVM_INT16 Gain = pFilterDefinition->Gain;
LVM_UINT16 Frequency = pFilterDefinition->Frequency;
LVM_UINT16 QFactor = pFilterDefinition->QFactor;
/*
* Intermediate variables and temporary values
*/
LVM_INT32 T0;
LVM_INT16 D;
LVM_INT32 A0;
LVM_INT32 B1;
LVM_INT32 B2;
LVM_INT32 Dt0;
LVM_INT32 B2_Den;
LVM_INT32 B2_Num;
LVM_INT32 CosErr;
LVM_INT16 coef;
LVM_INT32 factor;
LVM_INT16 t0;
LVM_INT16 i;
/*
* Calculating the intermediate values
*/
T0 = (LVM_INT32)Frequency * LVEQNB_TwoPiOnFsTable[Fs]; /* T0 = 2 * Pi * Fc / Fs */
if (Gain >= 0)
{
D = LVEQNB_DTable[15]; /* D = 1 if GaindB >= 0 */
}
else
{
D = LVEQNB_DTable[Gain+15]; /* D = 1 / (1 + G) if GaindB < 0 */
}
/*
* Calculate the B2 coefficient
*/
Dt0 = D * (T0 >> 10);
B2_Den = ((LVM_INT32)QFactor << 19) + (Dt0 >> 2);
B2_Num = (Dt0 >> 3) - ((LVM_INT32)QFactor << 18);
B2 = (B2_Num / (B2_Den >> 16)) << 15;
/*
* Calculate the cosine error by a polynomial expansion using the equation:
*
* CosErr += coef(n) * t0^n For n = 0 to 4
*/
T0 = (T0 >> 6) * 0x7f53; /* Scale to 1.0 in 16-bit for range 0 to fs/50 */
t0 = (LVM_INT16)(T0 >> 16);
factor = 0x7fff; /* Initialise to 1.0 for the a0 coefficient */
CosErr = 0; /* Initialise the error to zero */
for (i=1; i<5; i++)
{
coef = LVEQNB_DPCosCoef[i]; /* Get the nth coefficient */
CosErr += (factor * coef) >> 5; /* The nth partial sum */
factor = (factor * t0) >> 15; /* Calculate t0^n */
}
CosErr = CosErr << (LVEQNB_DPCosCoef[0]); /* Correct the scaling */
/*
* Calculate the B1 and A0 coefficients
*/
B1 = (0x40000000 - B2); /* B1 = (0.5 - b2/2) */
A0 = ((B1 >> 16) * (CosErr >> 10)) >> 6; /* Temporary storage for (0.5 - b2/2) * coserr(t0) */
B1 -= A0; /* B1 = (0.5 - b2/2) * (1 - coserr(t0)) */
A0 = (0x40000000 + B2) >> 1; /* A0 = (0.5 + b2) */
/*
* Write coeff into the data structure
*/
pCoefficients->A0 = A0;
pCoefficients->B1 = B1;
pCoefficients->B2 = B2;
pCoefficients->G = LVEQNB_GainTable[Gain+15];
return(LVEQNB_SUCCESS);
}
/****************************************************************************************/
/* */
/* FUNCTION: LVEQNB_SinglePrecCoefs */
/* */
/* DESCRIPTION: */
/* Calculate single precision coefficients for a peaking filter */
/* */
/* PARAMETERS: */
/* Fs Sampling frequency index */
/* pFilterDefinition Pointer to the filter definition */
/* pCoefficients Pointer to the coefficients */
/* */
/* RETURNS: */
/* LVEQNB_SUCCESS Always succeeds */
/* */
/* NOTES: */
/* 1. The equations used are as follows: */
/* */
/* G = 10^(GaindB/20) - 1 */
/* t0 = 2 * Pi * Fc / Fs */
/* D = 1 if GaindB >= 0 */
/* D = 1 / (1 + G) if GaindB < 0 */
/* */
/* b2 = -0.5 * (2Q - D * t0) / (2Q + D * t0) */
/* b1 = (0.5 - b2) * cos(t0) */
/* a0 = (0.5 + b2) / 2 */
/* */
/* Where: */
/* GaindB is the gain in dBs, range -15dB to +15dB */
/* Fc is the centre frequency, DC to Nyquist */
/* Fs is the sample frequency, 8000 to 48000 in descrete steps */
/* Q is the Q factor, 0.25 to 12 */
/* */
/****************************************************************************************/
LVEQNB_ReturnStatus_en LVEQNB_SinglePrecCoefs(LVM_UINT16 Fs,
LVEQNB_BandDef_t *pFilterDefinition,
PK_C16_Coefs_t *pCoefficients)
{
extern LVM_INT16 LVEQNB_GainTable[];
extern LVM_INT16 LVEQNB_TwoPiOnFsTable[];
extern LVM_INT16 LVEQNB_DTable[];
extern LVM_INT16 LVEQNB_CosCoef[];
/*
* Get the filter definition
*/
LVM_INT16 Gain = pFilterDefinition->Gain;
LVM_UINT16 Frequency = pFilterDefinition->Frequency;
LVM_UINT16 QFactor = pFilterDefinition->QFactor;
/*
* Intermediate variables and temporary values
*/
LVM_INT32 T0;
LVM_INT16 D;
LVM_INT32 A0;
LVM_INT32 B1;
LVM_INT32 B2;
LVM_INT32 Dt0;
LVM_INT32 B2_Den;
LVM_INT32 B2_Num;
LVM_INT32 COS_T0;
LVM_INT16 coef;
LVM_INT32 factor;
LVM_INT16 t0;
LVM_INT16 i;
/*
* Calculating the intermediate values
*/
T0 = (LVM_INT32)Frequency * LVEQNB_TwoPiOnFsTable[Fs]; /* T0 = 2 * Pi * Fc / Fs */
if (Gain >= 0)
{
D = LVEQNB_DTable[15]; /* D = 1 if GaindB >= 0 */
}
else
{
D = LVEQNB_DTable[Gain+15]; /* D = 1 / (1 + G) if GaindB < 0 */
}
/*
* Calculate the B2 coefficient
*/
Dt0 = D * (T0 >> 10);
B2_Den = ((LVM_INT32)QFactor << 19) + (Dt0 >> 2);
B2_Num = (Dt0 >> 3) - ((LVM_INT32)QFactor << 18);
B2 = (B2_Num / (B2_Den >> 16)) << 15;
/*
* Calculate the cosine by a polynomial expansion using the equation:
*
* Cos += coef(n) * t0^n For n = 0 to 6
*/
T0 = (T0 >> 10) * 20859; /* Scale to 1.0 in 16-bit for range 0 to fs/2 */
t0 = (LVM_INT16)(T0 >> 16);
factor = 0x7fff; /* Initialise to 1.0 for the a0 coefficient */
COS_T0 = 0; /* Initialise the error to zero */
for (i=1; i<7; i++)
{
coef = LVEQNB_CosCoef[i]; /* Get the nth coefficient */
COS_T0 += (factor * coef) >> 5; /* The nth partial sum */
factor = (factor * t0) >> 15; /* Calculate t0^n */
}
COS_T0 = COS_T0 << (LVEQNB_CosCoef[0]+6); /* Correct the scaling */
B1 = ((0x40000000 - B2) >> 16) * (COS_T0 >> 16); /* B1 = (0.5 - b2/2) * cos(t0) */
A0 = (0x40000000 + B2) >> 1; /* A0 = (0.5 + b2/2) */
/*
* Write coeff into the data structure
*/
pCoefficients->A0 = (LVM_INT16)(A0>>16);
pCoefficients->B1 = (LVM_INT16)(B1>>15);
pCoefficients->B2 = (LVM_INT16)(B2>>16);
pCoefficients->G = LVEQNB_GainTable[Gain+15];
return(LVEQNB_SUCCESS);
}

View File

@ -0,0 +1,106 @@
/*
* Copyright (C) 2004-2010 NXP Software
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __LVEQNB_COEFFS_H__
#define __LVEQNB_COEFFS_H__
/************************************************************************************/
/* */
/* Gain table for (10^(Gain/20) - 1) */
/* */
/************************************************************************************/
#define LVEQNB_GAINSHIFT 11 /* As a power of 2 */
#define LVEQNB_Gain_Neg15_dB -1684 /* Floating point value -0.822172 */
#define LVEQNB_Gain_Neg14_dB -1639 /* Floating point value -0.800474 */
#define LVEQNB_Gain_Neg13_dB -1590 /* Floating point value -0.776128 */
#define LVEQNB_Gain_Neg12_dB -1534 /* Floating point value -0.748811 */
#define LVEQNB_Gain_Neg11_dB -1471 /* Floating point value -0.718162 */
#define LVEQNB_Gain_Neg10_dB -1400 /* Floating point value -0.683772 */
#define LVEQNB_Gain_Neg9_dB -1321 /* Floating point value -0.645187 */
#define LVEQNB_Gain_Neg8_dB -1233 /* Floating point value -0.601893 */
#define LVEQNB_Gain_Neg7_dB -1133 /* Floating point value -0.553316 */
#define LVEQNB_Gain_Neg6_dB -1022 /* Floating point value -0.498813 */
#define LVEQNB_Gain_Neg5_dB -896 /* Floating point value -0.437659 */
#define LVEQNB_Gain_Neg4_dB -756 /* Floating point value -0.369043 */
#define LVEQNB_Gain_Neg3_dB -598 /* Floating point value -0.292054 */
#define LVEQNB_Gain_Neg2_dB -421 /* Floating point value -0.205672 */
#define LVEQNB_Gain_Neg1_dB -223 /* Floating point value -0.108749 */
#define LVEQNB_Gain_0_dB 0 /* Floating point value 0.000000 */
#define LVEQNB_Gain_1_dB 250 /* Floating point value 0.122018 */
#define LVEQNB_Gain_2_dB 530 /* Floating point value 0.258925 */
#define LVEQNB_Gain_3_dB 845 /* Floating point value 0.412538 */
#define LVEQNB_Gain_4_dB 1198 /* Floating point value 0.584893 */
#define LVEQNB_Gain_5_dB 1594 /* Floating point value 0.778279 */
#define LVEQNB_Gain_6_dB 2038 /* Floating point value 0.995262 */
#define LVEQNB_Gain_7_dB 2537 /* Floating point value 1.238721 */
#define LVEQNB_Gain_8_dB 3096 /* Floating point value 1.511886 */
#define LVEQNB_Gain_9_dB 3724 /* Floating point value 1.818383 */
#define LVEQNB_Gain_10_dB 4428 /* Floating point value 2.162278 */
#define LVEQNB_Gain_11_dB 5219 /* Floating point value 2.548134 */
#define LVEQNB_Gain_12_dB 6105 /* Floating point value 2.981072 */
#define LVEQNB_Gain_13_dB 7100 /* Floating point value 3.466836 */
#define LVEQNB_Gain_14_dB 8216 /* Floating point value 4.011872 */
#define LVEQNB_Gain_15_dB 9469 /* Floating point value 4.623413 */
/************************************************************************************/
/* */
/* Frequency table for 2*Pi/Fs */
/* */
/************************************************************************************/
#define LVEQNB_FREQSHIFT 25 /* As a power of 2 */
#define LVEQNB_2PiOn_8000 26354 /* Floating point value 0.000785 */
#define LVEQNB_2PiOn_11025 19123 /* Floating point value 0.000570 */
#define LVEQNB_2PiOn_12000 17569 /* Floating point value 0.000524 */
#define LVEQNB_2PiOn_16000 13177 /* Floating point value 0.000393 */
#define LVEQNB_2PiOn_22050 9561 /* Floating point value 0.000285 */
#define LVEQNB_2PiOn_24000 8785 /* Floating point value 0.000262 */
#define LVEQNB_2PiOn_32000 6588 /* Floating point value 0.000196 */
#define LVEQNB_2PiOn_44100 4781 /* Floating point value 0.000142 */
#define LVEQNB_2PiOn_48000 4392 /* Floating point value 0.000131 */
/************************************************************************************/
/* */
/* 50D table for 50 / ( 1 + Gain ) */
/* */
/************************************************************************************/
#define LVEQNB_100DSHIFT 5 /* As a power of 2 */
#define LVEQNB_100D_Neg15_dB 17995 /* Floating point value 5.623413 */
#define LVEQNB_100D_Neg14_dB 16038 /* Floating point value 5.011872 */
#define LVEQNB_100D_Neg13_dB 14294 /* Floating point value 4.466836 */
#define LVEQNB_100D_Neg12_dB 12739 /* Floating point value 3.981072 */
#define LVEQNB_100D_Neg11_dB 11354 /* Floating point value 3.548134 */
#define LVEQNB_100D_Neg10_dB 10119 /* Floating point value 3.162278 */
#define LVEQNB_100D_Neg9_dB 9019 /* Floating point value 2.818383 */
#define LVEQNB_100D_Neg8_dB 8038 /* Floating point value 2.511886 */
#define LVEQNB_100D_Neg7_dB 7164 /* Floating point value 2.238721 */
#define LVEQNB_100D_Neg6_dB 6385 /* Floating point value 1.995262 */
#define LVEQNB_100D_Neg5_dB 5690 /* Floating point value 1.778279 */
#define LVEQNB_100D_Neg4_dB 5072 /* Floating point value 1.584893 */
#define LVEQNB_100D_Neg3_dB 4520 /* Floating point value 1.412538 */
#define LVEQNB_100D_Neg2_dB 4029 /* Floating point value 1.258925 */
#define LVEQNB_100D_Neg1_dB 3590 /* Floating point value 1.122018 */
#define LVEQNB_100D_0_dB 3200 /* Floating point value 1.000000 */
#endif

View File

@ -0,0 +1,493 @@
/*
* Copyright (C) 2004-2010 NXP Software
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/****************************************************************************************/
/* */
/* Includes */
/* */
/****************************************************************************************/
#include "LVEQNB.h"
#include "LVEQNB_Private.h"
#include "VectorArithmetic.h"
#include "BIQUAD.h"
/****************************************************************************************/
/* */
/* Defines */
/* */
/****************************************************************************************/
#define LOW_FREQ 298 /* 32768/110 for low test frequency */
#define HIGH_FREQ 386 /* 32768/85 for high test frequency */
/****************************************************************************************/
/* */
/* FUNCTION: LVEQNB_GetParameters */
/* */
/* DESCRIPTION: */
/* Request the N-Band equaliser parameters. The current parameter set is returned via */
/* the parameter pointer. */
/* */
/* PARAMETERS: */
/* hInstance Instance handle */
/* pParams Pointer to an empty parameter structure */
/* */
/* RETURNS: */
/* LVEQNB_SUCCESS Succeeds */
/* LVEQNB_NULLADDRESS Instance or pParams is NULL pointer */
/* */
/* NOTES: */
/* 1. This function may be interrupted by the LVEQNB_Process function */
/* */
/****************************************************************************************/
LVEQNB_ReturnStatus_en LVEQNB_GetParameters(LVEQNB_Handle_t hInstance,
LVEQNB_Params_t *pParams)
{
LVEQNB_Instance_t *pInstance =(LVEQNB_Instance_t *)hInstance;
/*
* Check for error conditions
*/
if((hInstance == LVM_NULL) || (pParams == LVM_NULL))
{
return LVEQNB_NULLADDRESS;
}
*pParams = pInstance->Params;
return(LVEQNB_SUCCESS);
}
/************************************************************************************/
/* */
/* FUNCTION: LVEQNB_GetCapabilities */
/* */
/* DESCRIPTION: */
/* Get the N-Band equaliser capabilities. The current capabilities are returned */
/* via the pointer. */
/* */
/* PARAMETERS: */
/* hInstance Instance handle */
/* pCapabilities Pointer to an empty capability structure */
/* */
/* RETURNS: */
/* LVEQNB_Success Succeeds */
/* LVEQNB_NULLADDRESS hInstance or pCapabilities is NULL */
/* */
/* NOTES: */
/* 1. This function may be interrupted by the LVEQNB_Process function */
/* */
/************************************************************************************/
LVEQNB_ReturnStatus_en LVEQNB_GetCapabilities(LVEQNB_Handle_t hInstance,
LVEQNB_Capabilities_t *pCapabilities)
{
LVEQNB_Instance_t *pInstance =(LVEQNB_Instance_t *)hInstance;
if((hInstance == LVM_NULL) || (pCapabilities == LVM_NULL))
{
return LVEQNB_NULLADDRESS;
}
*pCapabilities = pInstance->Capabilities;
return(LVEQNB_SUCCESS);
}
/************************************************************************************/
/* */
/* FUNCTION: LVEQNB_SetFilters */
/* */
/* DESCRIPTION: */
/* Sets the filter type based on the definition. */
/* */
/* PARAMETERS: */
/* pInstance Pointer to the instance */
/* pParams Initialisation parameters */
/* */
/* RETURNS: */
/* void Nothing */
/* */
/* NOTES: */
/* 1. To select the biquad type the follow rules are applied: */
/* Double precision if (fc <= fs/110) */
/* Double precision if (fs/110 < fc < fs/85) & (Q>3) */
/* Single precision otherwise */
/* */
/************************************************************************************/
void LVEQNB_SetFilters(LVEQNB_Instance_t *pInstance,
LVEQNB_Params_t *pParams)
{
extern const LVM_UINT16 LVEQNB_SampleRateTab[]; /* Sample rate table */
LVM_UINT16 i; /* Filter band index */
LVM_UINT32 fs = (LVM_UINT32)LVEQNB_SampleRateTab[(LVM_UINT16)pParams->SampleRate]; /* Sample rate */
LVM_UINT32 fc; /* Filter centre frequency */
LVM_INT16 QFactor; /* Filter Q factor */
pInstance->NBands = pParams->NBands;
for (i=0; i<pParams->NBands; i++)
{
/*
* Get the filter settings
*/
fc = (LVM_UINT32)pParams->pBandDefinition[i].Frequency; /* Get the band centre frequency */
QFactor = (LVM_INT16)pParams->pBandDefinition[i].QFactor; /* Get the band Q factor */
/*
* For each filter set the type of biquad required
*/
pInstance->pBiquadType[i] = LVEQNB_SinglePrecision; /* Default to single precision */
if ((fc << 15) <= (LOW_FREQ * fs))
{
/*
* fc <= fs/110
*/
pInstance->pBiquadType[i] = LVEQNB_DoublePrecision;
}
else if (((fc << 15) <= (HIGH_FREQ * fs)) && (QFactor > 300))
{
/*
* (fs/110 < fc < fs/85) & (Q>3)
*/
pInstance->pBiquadType[i] = LVEQNB_DoublePrecision;
}
/*
* Check for out of range frequencies
*/
if (fc > (fs >> 1))
{
pInstance->pBiquadType[i] = LVEQNB_OutOfRange;
}
/*
* Copy the filter definition to persistant memory
*/
pInstance->pBandDefinitions[i] = pParams->pBandDefinition[i];
}
}
/************************************************************************************/
/* */
/* FUNCTION: LVEQNB_SetCoefficients */
/* */
/* DESCRIPTION: */
/* Sets the filter coefficients. This uses the type to select single or double */
/* precision coefficients. */
/* */
/* PARAMETERS: */
/* pInstance Pointer to the instance */
/* pParams Initialisation parameters */
/* */
/************************************************************************************/
void LVEQNB_SetCoefficients(LVEQNB_Instance_t *pInstance)
{
LVM_UINT16 i; /* Filter band index */
LVEQNB_BiquadType_en BiquadType; /* Filter biquad type */
/*
* Set the coefficients for each band by the init function
*/
for (i=0; i<pInstance->Params.NBands; i++)
{
/*
* Check band type for correct initialisation method and recalculate the coefficients
*/
BiquadType = pInstance->pBiquadType[i];
switch (BiquadType)
{
case LVEQNB_DoublePrecision:
{
PK_C32_Coefs_t Coefficients;
/*
* Calculate the double precision coefficients
*/
LVEQNB_DoublePrecCoefs((LVM_UINT16)pInstance->Params.SampleRate,
&pInstance->pBandDefinitions[i],
&Coefficients);
/*
* Set the coefficients
*/
PK_2I_D32F32CllGss_TRC_WRA_01_Init(&pInstance->pEQNB_FilterState[i],
&pInstance->pEQNB_Taps[i],
&Coefficients);
break;
}
case LVEQNB_SinglePrecision:
{
PK_C16_Coefs_t Coefficients;
/*
* Calculate the single precision coefficients
*/
LVEQNB_SinglePrecCoefs((LVM_UINT16)pInstance->Params.SampleRate,
&pInstance->pBandDefinitions[i],
&Coefficients);
/*
* Set the coefficients
*/
PK_2I_D32F32CssGss_TRC_WRA_01_Init(&pInstance->pEQNB_FilterState[i],
&pInstance->pEQNB_Taps[i],
&Coefficients);
break;
}
default:
break;
}
}
}
/************************************************************************************/
/* */
/* FUNCTION: LVEQNB_ClearFilterHistory */
/* */
/* DESCRIPTION: */
/* Clears the filter data history */
/* */
/* PARAMETERS: */
/* pInstance Pointer to the instance */
/* */
/************************************************************************************/
void LVEQNB_ClearFilterHistory(LVEQNB_Instance_t *pInstance)
{
LVM_INT16 *pTapAddress;
LVM_INT16 NumTaps;
pTapAddress = (LVM_INT16 *)pInstance->pEQNB_Taps;
NumTaps = (LVM_INT16)((pInstance->Capabilities.MaxBands * sizeof(Biquad_2I_Order2_Taps_t))/sizeof(LVM_INT16));
if (NumTaps != 0)
{
LoadConst_16(0, /* Clear the history, value 0 */
pTapAddress, /* Destination */
NumTaps); /* Number of words */
}
}
/****************************************************************************************/
/* */
/* FUNCTION: LVEQNB_Control */
/* */
/* DESCRIPTION: */
/* Sets or changes the LifeVibes module parameters. */
/* */
/* PARAMETERS: */
/* hInstance Instance handle */
/* pParams Pointer to a parameter structure */
/* */
/* RETURNS: */
/* LVEQNB_Success Always succeeds */
/* LVEQNB_NULLADDRESS Instance or pParams is NULL pointer */
/* LVEQNB_NULLADDRESS NULL address for the equaliser filter definitions and the */
/* number of bands is non-zero */
/* */
/* NOTES: */
/* 1. This function may be interrupted by the LVEQNB_Process function */
/* */
/****************************************************************************************/
LVEQNB_ReturnStatus_en LVEQNB_Control(LVEQNB_Handle_t hInstance,
LVEQNB_Params_t *pParams)
{
LVEQNB_Instance_t *pInstance = (LVEQNB_Instance_t *)hInstance;
LVM_INT16 bChange = LVM_FALSE;
LVM_INT16 i = 0;
LVEQNB_Mode_en OperatingModeSave ;
/*
* Check for error conditions
*/
if((hInstance == LVM_NULL) || (pParams == LVM_NULL))
{
return LVEQNB_NULLADDRESS;
}
if((pParams->NBands !=0) && (pParams->pBandDefinition==LVM_NULL))
{
return LVEQNB_NULLADDRESS;
}
OperatingModeSave = pInstance->Params.OperatingMode;
/* Set the alpha factor of the mixer */
if (pParams->SampleRate != pInstance->Params.SampleRate)
{
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
}
if( (pInstance->Params.NBands != pParams->NBands ) ||
(pInstance->Params.OperatingMode != pParams->OperatingMode ) ||
(pInstance->Params.pBandDefinition != pParams->pBandDefinition ) ||
(pInstance->Params.SampleRate != pParams->SampleRate ) ||
(pInstance->Params.SourceFormat != pParams->SourceFormat ))
{
bChange = LVM_TRUE;
}
else
{
for(i = 0; i < pParams->NBands; i++)
{
if((pInstance->pBandDefinitions[i].Frequency != pParams->pBandDefinition[i].Frequency )||
(pInstance->pBandDefinitions[i].Gain != pParams->pBandDefinition[i].Gain )||
(pInstance->pBandDefinitions[i].QFactor != pParams->pBandDefinition[i].QFactor ))
{
bChange = LVM_TRUE;
}
}
}
if(bChange){
/*
* If the sample rate has changed clear the history
*/
if (pInstance->Params.SampleRate != pParams->SampleRate)
{
LVEQNB_ClearFilterHistory(pInstance); /* Clear the history */
}
/*
* Update the instance parameters
*/
pInstance->Params = *pParams;
/*
* Reset the filters except if the algo is switched off
*/
if(pParams->OperatingMode != LVEQNB_BYPASS){
/*
* Reset the filters as all parameters could have changed
*/
LVEQNB_SetFilters(pInstance, /* Instance pointer */
pParams); /* New parameters */
/*
* Update the filters
*/
LVEQNB_SetCoefficients(pInstance); /* Instance pointer */
}
if(pParams->OperatingMode != OperatingModeSave)
{
if(pParams->OperatingMode == LVEQNB_ON)
{
LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0],LVM_MAXINT_16);
LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1],0);
pInstance->BypassMixer.MixerStream[0].CallbackSet = 1;
pInstance->BypassMixer.MixerStream[1].CallbackSet = 1;
}
else
{
/* Stay on the ON operating mode until the transition is done */
pInstance->Params.OperatingMode = LVEQNB_ON;
LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[0],0);
LVC_Mixer_SetTarget(&pInstance->BypassMixer.MixerStream[1],LVM_MAXINT_16);
pInstance->BypassMixer.MixerStream[0].CallbackSet = 1;
pInstance->BypassMixer.MixerStream[1].CallbackSet = 1;
}
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
LVC_Mixer_VarSlope_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],LVEQNB_BYPASS_MIXER_TC,(LVM_Fs_en)pParams->SampleRate,2);
pInstance->bInOperatingModeTransition = LVM_TRUE;
}
}
return(LVEQNB_SUCCESS);
}
/****************************************************************************************/
/* */
/* FUNCTION: LVEQNB_BypassMixerCallBack */
/* */
/* DESCRIPTION: */
/* CallBack function of the mixer */
/* transition */
/* */
/****************************************************************************************/
LVM_INT32 LVEQNB_BypassMixerCallBack (void* hInstance,
void *pGeneralPurpose,
LVM_INT16 CallbackParam)
{
LVEQNB_Instance_t *pInstance =(LVEQNB_Instance_t *)hInstance;
LVM_Callback CallBack = pInstance->Capabilities.CallBack;
(void) pGeneralPurpose;
/*
* Send an ALGOFF event if the ON->OFF switch transition is finished
*/
if((LVC_Mixer_GetTarget(&pInstance->BypassMixer.MixerStream[0]) == 0x00000000) &&
(CallbackParam == 0)){
pInstance->Params.OperatingMode = LVEQNB_BYPASS;
if (CallBack != LVM_NULL){
CallBack(pInstance->Capabilities.pBundleInstance, LVM_NULL, ALGORITHM_EQNB_ID|LVEQNB_EVENT_ALGOFF);
}
}
/*
* Exit transition state
*/
pInstance->bInOperatingModeTransition = LVM_FALSE;
return 1;
}

View File

@ -0,0 +1,321 @@
/*
* Copyright (C) 2004-2010 NXP Software
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/****************************************************************************************/
/* */
/* Includes */
/* */
/****************************************************************************************/
#include "LVEQNB.h"
#include "LVEQNB_Private.h"
#include "InstAlloc.h"
/****************************************************************************************/
/* */
/* FUNCTION: LVEQNB_Memory */
/* */
/* DESCRIPTION: */
/* This function is used for memory allocation and free. It can be called in */
/* two ways: */
/* */
/* hInstance = NULL Returns the memory requirements */
/* hInstance = Instance handle Returns the memory requirements and */
/* allocated base addresses for the instance */
/* */
/* When this function is called for memory allocation (hInstance=NULL) the memory */
/* base address pointers are NULL on return. */
/* */
/* When the function is called for free (hInstance = Instance Handle) the memory */
/* table returns the allocated memory and base addresses used during initialisation. */
/* */
/* PARAMETERS: */
/* hInstance Instance Handle */
/* pMemoryTable Pointer to an empty memory definition table */
/* pCapabilities Pointer to the instance capabilities */
/* */
/* RETURNS: */
/* LVEQNB_SUCCESS Succeeded */
/* LVEQNB_NULLADDRESS When any of pMemoryTable and pCapabilities is NULL address */
/* */
/* NOTES: */
/* 1. This function may be interrupted by the LVEQNB_Process function */
/* */
/****************************************************************************************/
LVEQNB_ReturnStatus_en LVEQNB_Memory(LVEQNB_Handle_t hInstance,
LVEQNB_MemTab_t *pMemoryTable,
LVEQNB_Capabilities_t *pCapabilities)
{
INST_ALLOC AllocMem;
LVEQNB_Instance_t *pInstance = (LVEQNB_Instance_t *)hInstance;
if((pMemoryTable == LVM_NULL)|| (pCapabilities == LVM_NULL))
{
return LVEQNB_NULLADDRESS;
}
/*
* Fill in the memory table
*/
if (hInstance == LVM_NULL)
{
/*
* Instance memory
*/
InstAlloc_Init(&AllocMem,
LVM_NULL);
InstAlloc_AddMember(&AllocMem, /* Low pass filter */
sizeof(LVEQNB_Instance_t));
pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Size = InstAlloc_GetTotal(&AllocMem);
pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Alignment = LVEQNB_INSTANCE_ALIGN;
pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].Type = LVEQNB_PERSISTENT;
pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].pBaseAddress = LVM_NULL;
/*
* Persistant data memory
*/
InstAlloc_Init(&AllocMem,
LVM_NULL);
InstAlloc_AddMember(&AllocMem, /* Low pass filter */
sizeof(Biquad_2I_Order2_Taps_t));
InstAlloc_AddMember(&AllocMem, /* High pass filter */
sizeof(Biquad_2I_Order2_Taps_t));
InstAlloc_AddMember(&AllocMem,
(pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_Taps_t))); /* Equaliser Biquad Taps */
InstAlloc_AddMember(&AllocMem,
(pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t))); /* Filter definitions */
InstAlloc_AddMember(&AllocMem,
(pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en))); /* Biquad types */
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Size = InstAlloc_GetTotal(&AllocMem);
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Alignment = LVEQNB_DATA_ALIGN;
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].Type = LVEQNB_PERSISTENT_DATA;
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress = LVM_NULL;
/*
* Persistant coefficient memory
*/
InstAlloc_Init(&AllocMem,
LVM_NULL);
InstAlloc_AddMember(&AllocMem, /* Low pass filter */
sizeof(Biquad_Instance_t));
InstAlloc_AddMember(&AllocMem, /* High pass filter */
sizeof(Biquad_Instance_t));
InstAlloc_AddMember(&AllocMem,
pCapabilities->MaxBands * sizeof(Biquad_Instance_t)); /* Equaliser Biquad Instance */
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Size = InstAlloc_GetTotal(&AllocMem);
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Alignment = LVEQNB_COEF_ALIGN;
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].Type = LVEQNB_PERSISTENT_COEF;
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress = LVM_NULL;
/*
* Scratch memory
*/
InstAlloc_Init(&AllocMem,
LVM_NULL);
InstAlloc_AddMember(&AllocMem, /* Low pass filter */
LVEQNB_SCRATCHBUFFERS*sizeof(LVM_INT16)*pCapabilities->MaxBlockSize);
pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Size = InstAlloc_GetTotal(&AllocMem);
pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Alignment = LVEQNB_SCRATCH_ALIGN;
pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].Type = LVEQNB_SCRATCH;
pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress = LVM_NULL;
}
else
{
/* Read back memory allocation table */
*pMemoryTable = pInstance->MemoryTable;
}
return(LVEQNB_SUCCESS);
}
/****************************************************************************************/
/* */
/* FUNCTION: LVEQNB_Init */
/* */
/* DESCRIPTION: */
/* Create and initialisation function for the N-Band equaliser module */
/* */
/* This function can be used to create an algorithm instance by calling with */
/* hInstance set to NULL. In this case the algorithm returns the new instance */
/* handle. */
/* */
/* This function can be used to force a full re-initialisation of the algorithm */
/* by calling with hInstance = Instance Handle. In this case the memory table */
/* should be correct for the instance, this can be ensured by calling the function */
/* DBE_Memory before calling this function. */
/* */
/* PARAMETERS: */
/* hInstance Instance handle */
/* pMemoryTable Pointer to the memory definition table */
/* pCapabilities Pointer to the instance capabilities */
/* */
/* RETURNS: */
/* LVEQNB_SUCCESS Initialisation succeeded */
/* LVEQNB_NULLADDRESS When pCapabilities or pMemoryTableis or phInstance are NULL */
/* LVEQNB_NULLADDRESS One or more of the memory regions has a NULL base address */
/* pointer for a memory region with a non-zero size. */
/* */
/* NOTES: */
/* 1. The instance handle is the pointer to the base address of the first memory */
/* region. */
/* 2. This function must not be interrupted by the LVEQNB_Process function */
/* */
/****************************************************************************************/
LVEQNB_ReturnStatus_en LVEQNB_Init(LVEQNB_Handle_t *phInstance,
LVEQNB_MemTab_t *pMemoryTable,
LVEQNB_Capabilities_t *pCapabilities)
{
LVEQNB_Instance_t *pInstance;
LVM_UINT32 MemSize;
INST_ALLOC AllocMem;
LVM_INT32 i;
/*
* Check for NULL pointers
*/
if((phInstance == LVM_NULL) || (pMemoryTable == LVM_NULL) || (pCapabilities == LVM_NULL))
{
return LVEQNB_NULLADDRESS;
}
/*
* Check the memory table for NULL pointers
*/
for (i = 0; i < LVEQNB_NR_MEMORY_REGIONS; i++)
{
if (pMemoryTable->Region[i].Size!=0)
{
if (pMemoryTable->Region[i].pBaseAddress==LVM_NULL)
{
return(LVEQNB_NULLADDRESS);
}
}
}
/*
* Set the instance handle if not already initialised
*/
InstAlloc_Init(&AllocMem, pMemoryTable->Region[LVEQNB_MEMREGION_INSTANCE].pBaseAddress);
if (*phInstance == LVM_NULL)
{
*phInstance = InstAlloc_AddMember(&AllocMem, sizeof(LVEQNB_Instance_t));
}
pInstance =(LVEQNB_Instance_t *)*phInstance;
/*
* Save the memory table in the instance structure
*/
pInstance->Capabilities = *pCapabilities;
/*
* Save the memory table in the instance structure and
* set the structure pointers
*/
pInstance->MemoryTable = *pMemoryTable;
/*
* Allocate coefficient memory
*/
InstAlloc_Init(&AllocMem,
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_COEF].pBaseAddress);
pInstance->pEQNB_FilterState = InstAlloc_AddMember(&AllocMem,
pCapabilities->MaxBands * sizeof(Biquad_Instance_t)); /* Equaliser Biquad Instance */
/*
* Allocate data memory
*/
InstAlloc_Init(&AllocMem,
pMemoryTable->Region[LVEQNB_MEMREGION_PERSISTENT_DATA].pBaseAddress);
MemSize = (pCapabilities->MaxBands * sizeof(Biquad_2I_Order2_Taps_t));
pInstance->pEQNB_Taps = (Biquad_2I_Order2_Taps_t *)InstAlloc_AddMember(&AllocMem,
MemSize);
MemSize = (pCapabilities->MaxBands * sizeof(LVEQNB_BandDef_t));
pInstance->pBandDefinitions = (LVEQNB_BandDef_t *)InstAlloc_AddMember(&AllocMem,
MemSize);
MemSize = (pCapabilities->MaxBands * sizeof(LVEQNB_BiquadType_en));
pInstance->pBiquadType = (LVEQNB_BiquadType_en *)InstAlloc_AddMember(&AllocMem,
MemSize);
/*
* Internally map, structure and allign scratch memory
*/
InstAlloc_Init(&AllocMem,
pMemoryTable->Region[LVEQNB_MEMREGION_SCRATCH].pBaseAddress);
pInstance->pFastTemporary = (LVM_INT16 *)InstAlloc_AddMember(&AllocMem,
sizeof(LVM_INT16));
/*
* Update the instance parameters
*/
pInstance->Params.NBands = 0;
pInstance->Params.OperatingMode = LVEQNB_BYPASS;
pInstance->Params.pBandDefinition = LVM_NULL;
pInstance->Params.SampleRate = LVEQNB_FS_8000;
pInstance->Params.SourceFormat = LVEQNB_STEREO;
/*
* Initialise the filters
*/
LVEQNB_SetFilters(pInstance, /* Set the filter types */
&pInstance->Params);
LVEQNB_SetCoefficients(pInstance); /* Set the filter coefficients */
LVEQNB_ClearFilterHistory(pInstance); /* Clear the filter history */
/*
* Initialise the bypass variables
*/
pInstance->BypassMixer.MixerStream[0].CallbackSet = 0;
pInstance->BypassMixer.MixerStream[0].CallbackParam = 0;
pInstance->BypassMixer.MixerStream[0].pCallbackHandle = (void*)pInstance;
pInstance->BypassMixer.MixerStream[0].pCallBack = LVEQNB_BypassMixerCallBack;
LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[0],0,0);
LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[0],0,LVM_FS_8000,2);
pInstance->BypassMixer.MixerStream[1].CallbackSet = 1;
pInstance->BypassMixer.MixerStream[1].CallbackParam = 0;
pInstance->BypassMixer.MixerStream[1].pCallbackHandle = LVM_NULL;
pInstance->BypassMixer.MixerStream[1].pCallBack = LVM_NULL;
LVC_Mixer_Init(&pInstance->BypassMixer.MixerStream[1],0,LVM_MAXINT_16);
LVC_Mixer_SetTimeConstant(&pInstance->BypassMixer.MixerStream[1],0,LVM_FS_8000,2);
pInstance->bInOperatingModeTransition = LVM_FALSE;
return(LVEQNB_SUCCESS);
}

View File

@ -0,0 +1,133 @@
/*
* Copyright (C) 2004-2010 NXP Software
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __LVEQNB_PRIVATE_H__
#define __LVEQNB_PRIVATE_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/****************************************************************************************/
/* */
/* Includes */
/* */
/****************************************************************************************/
#include "LVEQNB.h" /* Calling or Application layer definitions */
#include "BIQUAD.h"
#include "LVC_Mixer.h"
/****************************************************************************************/
/* */
/* Defines */
/* */
/****************************************************************************************/
/* General */
#define LVEQNB_INVALID 0xFFFF /* Invalid init parameter */
/* Memory */
#define LVEQNB_INSTANCE_ALIGN 4 /* 32-bit alignment for instance structures */
#define LVEQNB_DATA_ALIGN 4 /* 32-bit alignment for structures */
#define LVEQNB_COEF_ALIGN 4 /* 32-bit alignment for long words */
#define LVEQNB_SCRATCHBUFFERS 4 /* Number of buffers required for inplace processing */
#define LVEQNB_SCRATCH_ALIGN 4 /* 32-bit alignment for long data */
#define LVEQNB_BYPASS_MIXER_TC 100 /* Bypass Mixer TC */
/****************************************************************************************/
/* */
/* Types */
/* */
/****************************************************************************************/
/* Filter biquad types */
typedef enum
{
LVEQNB_SinglePrecision = 0,
LVEQNB_DoublePrecision = 1,
LVEQNB_OutOfRange = 2,
LVEQNB_BIQUADTYPE_MAX = LVM_MAXINT_32
} LVEQNB_BiquadType_en;
/****************************************************************************************/
/* */
/* Structures */
/* */
/****************************************************************************************/
/* Instance structure */
typedef struct
{
/* Public parameters */
LVEQNB_MemTab_t MemoryTable; /* Instance memory allocation table */
LVEQNB_Params_t Params; /* Instance parameters */
LVEQNB_Capabilities_t Capabilities; /* Instance capabilities */
/* Aligned memory pointers */
LVM_INT16 *pFastTemporary; /* Fast temporary data base address */
/* Process variables */
Biquad_2I_Order2_Taps_t *pEQNB_Taps; /* Equaliser Taps */
Biquad_Instance_t *pEQNB_FilterState; /* State for each filter band */
/* Filter definitions and call back */
LVM_UINT16 NBands; /* Number of bands */
LVEQNB_BandDef_t *pBandDefinitions; /* Filter band definitions */
LVEQNB_BiquadType_en *pBiquadType; /* Filter biquad types */
/* Bypass variable */
LVMixer3_2St_st BypassMixer; /* Bypass mixer used in transitions */
LVM_INT16 bInOperatingModeTransition; /* Operating mode transition flag */
} LVEQNB_Instance_t;
/****************************************************************************************/
/* */
/* Function prototypes */
/* */
/****************************************************************************************/
void LVEQNB_SetFilters(LVEQNB_Instance_t *pInstance,
LVEQNB_Params_t *pParams);
void LVEQNB_SetCoefficients(LVEQNB_Instance_t *pInstance);
void LVEQNB_ClearFilterHistory(LVEQNB_Instance_t *pInstance);
LVEQNB_ReturnStatus_en LVEQNB_SinglePrecCoefs(LVM_UINT16 Fs,
LVEQNB_BandDef_t *pFilterDefinition,
PK_C16_Coefs_t *pCoefficients);
LVEQNB_ReturnStatus_en LVEQNB_DoublePrecCoefs(LVM_UINT16 Fs,
LVEQNB_BandDef_t *pFilterDefinition,
PK_C32_Coefs_t *pCoefficients);
LVM_INT32 LVEQNB_BypassMixerCallBack (void* hInstance, void *pGeneralPurpose, LVM_INT16 CallbackParam);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __LVEQNB_PRIVATE_H__ */

View File

@ -0,0 +1,200 @@
/*
* Copyright (C) 2004-2010 NXP Software
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/****************************************************************************************/
/* */
/* Includes */
/* */
/****************************************************************************************/
#include "LVEQNB.h"
#include "LVEQNB_Private.h"
#include "VectorArithmetic.h"
#include "BIQUAD.h"
/****************************************************************************************/
/* */
/* Defines */
/* */
/****************************************************************************************/
#define SHIFT 13
/****************************************************************************************/
/* */
/* FUNCTION: LVEQNB_Process */
/* */
/* DESCRIPTION: */
/* Process function for the N-Band Equaliser module. */
/* */
/* PARAMETERS: */
/* hInstance Instance handle */
/* pInData Pointer to the input data */
/* pOutData Pointer to the output data */
/* NumSamples Number of samples in the input buffer */
/* */
/* RETURNS: */
/* LVEQNB_SUCCESS Succeeded */
/* LVEQNB_NULLADDRESS When hInstance, pInData or pOutData are NULL */
/* LVEQNB_ALIGNMENTERROR When pInData or pOutData are not 32-bit aligned */
/* LVEQNB_TOOMANYSAMPLES NumSamples was larger than the maximum block size */
/* */
/* NOTES: */
/* */
/****************************************************************************************/
LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t hInstance,
const LVM_INT16 *pInData,
LVM_INT16 *pOutData,
LVM_UINT16 NumSamples)
{
LVM_UINT16 i;
Biquad_Instance_t *pBiquad;
LVEQNB_Instance_t *pInstance = (LVEQNB_Instance_t *)hInstance;
LVM_INT32 *pScratch;
/* Check for NULL pointers */
if((hInstance == LVM_NULL) || (pInData == LVM_NULL) || (pOutData == LVM_NULL))
{
return LVEQNB_NULLADDRESS;
}
/* Check if the input and output data buffers are 32-bit aligned */
if ((((LVM_INT32)pInData % 4) != 0) || (((LVM_INT32)pOutData % 4) != 0))
{
return LVEQNB_ALIGNMENTERROR;
}
pScratch = (LVM_INT32 *)pInstance->pFastTemporary;
/*
* Check the number of samples is not too large
*/
if (NumSamples > pInstance->Capabilities.MaxBlockSize)
{
return(LVEQNB_TOOMANYSAMPLES);
}
if (pInstance->Params.OperatingMode == LVEQNB_ON)
{
/*
* Convert from 16-bit to 32-bit
*/
Int16LShiftToInt32_16x32((LVM_INT16 *)pInData, /* Source */
pScratch, /* Destination */
(LVM_INT16)(2*NumSamples), /* Left and Right */
SHIFT); /* Scaling shift */
/*
* For each section execte the filter unless the gain is 0dB
*/
if (pInstance->NBands != 0)
{
for (i=0; i<pInstance->NBands; i++)
{
/*
* Check if band is non-zero dB gain
*/
if (pInstance->pBandDefinitions[i].Gain != 0)
{
/*
* Get the address of the biquad instance
*/
pBiquad = &pInstance->pEQNB_FilterState[i];
/*
* Select single or double precision as required
*/
switch (pInstance->pBiquadType[i])
{
case LVEQNB_SinglePrecision:
{
PK_2I_D32F32C14G11_TRC_WRA_01(pBiquad,
(LVM_INT32 *)pScratch,
(LVM_INT32 *)pScratch,
(LVM_INT16)NumSamples);
break;
}
case LVEQNB_DoublePrecision:
{
PK_2I_D32F32C30G11_TRC_WRA_01(pBiquad,
(LVM_INT32 *)pScratch,
(LVM_INT32 *)pScratch,
(LVM_INT16)NumSamples);
break;
}
default:
break;
}
}
}
}
if(pInstance->bInOperatingModeTransition == LVM_TRUE){
/*
* Convert from 32-bit to 16- bit and saturate
*/
Int32RShiftToInt16_Sat_32x16(pScratch, /* Source */
(LVM_INT16 *)pScratch, /* Destination */
(LVM_INT16)(2*NumSamples), /* Left and Right */
SHIFT); /* Scaling shift */
LVC_MixSoft_2St_D16C31_SAT(&pInstance->BypassMixer,
(LVM_INT16 *)pScratch,
(LVM_INT16 *)pInData,
(LVM_INT16 *)pScratch,
(LVM_INT16)(2*NumSamples));
Copy_16((LVM_INT16*)pScratch, /* Source */
pOutData, /* Destination */
(LVM_INT16)(2*NumSamples)); /* Left and Right samples */
}
else{
/*
* Convert from 32-bit to 16- bit and saturate
*/
Int32RShiftToInt16_Sat_32x16(pScratch, /* Source */
pOutData, /* Destination */
(LVM_INT16 )(2*NumSamples), /* Left and Right */
SHIFT); /* Scaling shift */
}
}
else
{
/*
* Mode is OFF so copy the data if necessary
*/
if (pInData != pOutData)
{
Copy_16(pInData, /* Source */
pOutData, /* Destination */
(LVM_INT16)(2*NumSamples)); /* Left and Right samples */
}
}
return(LVEQNB_SUCCESS);
}

View File

@ -0,0 +1,195 @@
/*
* Copyright (C) 2004-2010 NXP Software
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/************************************************************************************/
/* */
/* Includes */
/* */
/************************************************************************************/
#include "LVEQNB.h"
#include "LVEQNB_Coeffs.h"
/************************************************************************************/
/* */
/* Sample rate table */
/* */
/************************************************************************************/
/*
* Sample rate table for converting between the enumerated type and the actual
* frequency
*/
const LVM_UINT16 LVEQNB_SampleRateTab[] = {8000, /* 8kS/s */
11025,
12000,
16000,
22050,
24000,
32000,
44100,
48000}; /* 48kS/s */
/************************************************************************************/
/* */
/* Coefficient calculation tables */
/* */
/************************************************************************************/
/*
* Table for 2 * Pi / Fs
*/
const LVM_INT16 LVEQNB_TwoPiOnFsTable[] = {LVEQNB_2PiOn_8000, /* 8kS/s */
LVEQNB_2PiOn_11025,
LVEQNB_2PiOn_12000,
LVEQNB_2PiOn_16000,
LVEQNB_2PiOn_22050,
LVEQNB_2PiOn_24000,
LVEQNB_2PiOn_32000,
LVEQNB_2PiOn_44100,
LVEQNB_2PiOn_48000}; /* 48kS/s */
/*
* Gain table
*/
const LVM_INT16 LVEQNB_GainTable[] = {LVEQNB_Gain_Neg15_dB, /* -15dB gain */
LVEQNB_Gain_Neg14_dB,
LVEQNB_Gain_Neg13_dB,
LVEQNB_Gain_Neg12_dB,
LVEQNB_Gain_Neg11_dB,
LVEQNB_Gain_Neg10_dB,
LVEQNB_Gain_Neg9_dB,
LVEQNB_Gain_Neg8_dB,
LVEQNB_Gain_Neg7_dB,
LVEQNB_Gain_Neg6_dB,
LVEQNB_Gain_Neg5_dB,
LVEQNB_Gain_Neg4_dB,
LVEQNB_Gain_Neg3_dB,
LVEQNB_Gain_Neg2_dB,
LVEQNB_Gain_Neg1_dB,
LVEQNB_Gain_0_dB, /* 0dB gain */
LVEQNB_Gain_1_dB,
LVEQNB_Gain_2_dB,
LVEQNB_Gain_3_dB,
LVEQNB_Gain_4_dB,
LVEQNB_Gain_5_dB,
LVEQNB_Gain_6_dB,
LVEQNB_Gain_7_dB,
LVEQNB_Gain_8_dB,
LVEQNB_Gain_9_dB,
LVEQNB_Gain_10_dB,
LVEQNB_Gain_11_dB,
LVEQNB_Gain_12_dB,
LVEQNB_Gain_13_dB,
LVEQNB_Gain_14_dB,
LVEQNB_Gain_15_dB}; /* +15dB gain */
/*
* D table for 100 / (Gain + 1)
*/
const LVM_INT16 LVEQNB_DTable[] = {LVEQNB_100D_Neg15_dB, /* -15dB gain */
LVEQNB_100D_Neg14_dB,
LVEQNB_100D_Neg13_dB,
LVEQNB_100D_Neg12_dB,
LVEQNB_100D_Neg11_dB,
LVEQNB_100D_Neg10_dB,
LVEQNB_100D_Neg9_dB,
LVEQNB_100D_Neg8_dB,
LVEQNB_100D_Neg7_dB,
LVEQNB_100D_Neg6_dB,
LVEQNB_100D_Neg5_dB,
LVEQNB_100D_Neg4_dB,
LVEQNB_100D_Neg3_dB,
LVEQNB_100D_Neg2_dB,
LVEQNB_100D_Neg1_dB,
LVEQNB_100D_0_dB}; /* 0dB gain */
/************************************************************************************/
/* */
/* Filter polynomial coefficients */
/* */
/************************************************************************************/
/*
* Coefficients for calculating the cosine with the equation:
*
* Cos(x) = (2^Shifts)*(a0 + a1*x + a2*x^2 + a3*x^3 + a4*x^4 + a5*x^5)
*
* These coefficients expect the input, x, to be in the range 0 to 32768 respresenting
* a range of 0 to Pi. The output is in the range 32767 to -32768 representing the range
* +1.0 to -1.0
*/
const LVM_INT16 LVEQNB_CosCoef[] = {3, /* Shifts */
4096, /* a0 */
-36, /* a1 */
-19725, /* a2 */
-2671, /* a3 */
23730, /* a4 */
-9490}; /* a5 */
/*
* Coefficients for calculating the cosine error with the equation:
*
* CosErr(x) = (2^Shifts)*(a0 + a1*x + a2*x^2 + a3*x^3)
*
* These coefficients expect the input, x, to be in the range 0 to 32768 respresenting
* a range of 0 to Pi/25. The output is in the range 0 to 32767 representing the range
* 0.0 to 0.0078852986
*
* This is used to give a double precision cosine over the range 0 to Pi/25 using the
* the equation:
*
* Cos(x) = 1.0 - CosErr(x)
*/
const LVM_INT16 LVEQNB_DPCosCoef[] = {1, /* Shifts */
0, /* a0 */
-6, /* a1 */
16586, /* a2 */
-44}; /* a3 */
/************************************************************************************/
/* */
/* Bypass mixer time constants (100ms) */
/* */
/************************************************************************************/
#define LVEQNB_MIX_TC_Fs8000 32580 /* Floating point value 0.994262695 */
#define LVEQNB_MIX_TC_Fs11025 32632 /* Floating point value 0.995849609 */
#define LVEQNB_MIX_TC_Fs12000 32643 /* Floating point value 0.996185303 */
#define LVEQNB_MIX_TC_Fs16000 32674 /* Floating point value 0.997131348 */
#define LVEQNB_MIX_TC_Fs22050 32700 /* Floating point value 0.997924805 */
#define LVEQNB_MIX_TC_Fs24000 32705 /* Floating point value 0.998077393 */
#define LVEQNB_MIX_TC_Fs32000 32721 /* Floating point value 0.998565674 */
#define LVEQNB_MIX_TC_Fs44100 32734 /* Floating point value 0.998962402 */
#define LVEQNB_MIX_TC_Fs48000 32737 /* Floating point value 0.999053955 */
const LVM_INT16 LVEQNB_MixerTCTable[] = {
LVEQNB_MIX_TC_Fs8000,
LVEQNB_MIX_TC_Fs11025,
LVEQNB_MIX_TC_Fs12000,
LVEQNB_MIX_TC_Fs16000,
LVEQNB_MIX_TC_Fs22050,
LVEQNB_MIX_TC_Fs24000,
LVEQNB_MIX_TC_Fs32000,
LVEQNB_MIX_TC_Fs44100,
LVEQNB_MIX_TC_Fs48000};