LVM_FO_LPF.c revision 2c8e5cab3faa6d360e222b7a6c40a80083d021ac
1/* 2 * Copyright (C) 2004-2010 NXP Software 3 * Copyright (C) 2010 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18/************************************************************************/ 19/* */ 20/* Project:: */ 21/* $Author: nxp27078 $*/ 22/* $Revision: 762 $*/ 23/* $Date: 2010-06-11 14:50:33 +0200 (vr, 11 jun 2010) $*/ 24/* */ 25/************************************************************************/ 26 27#include "LVM_Types.h" 28#include "LVM_Macros.h" 29#include "ScalarArithmetic.h" 30#include "BIQUAD.h" 31#include "Filter.h" 32 33 34/*-------------------------------------------------------------------------*/ 35/* FUNCTION: */ 36/* void LVM_FO_LPF( LVM_INT32 w , */ 37/* FO_C32_Coefs_t *pCoeffs); */ 38/* */ 39/* */ 40/* DESCRIPTION: */ 41/* This function calculates the coefficient of first order low pass */ 42/* filter. It uses the equations: */ 43/* */ 44/* B1 = (tan(w/2) - 1 ) / (tan(w/2) + 1 ) */ 45/* A0 = (1 + B1) / 2 */ 46/* A1 = A0 */ 47/* */ 48/* The value of B1 is then calculated directly from the value w by a */ 49/* polynomial expansion using a 9th order polynomial. It uses the */ 50/* following table of 32-bit integer polynomial coefficients: */ 51/* */ 52/* Coefficient Value */ 53/* A0 -8388571 */ 54/* A1 33547744 */ 55/* A2 -66816791 */ 56/* A3 173375308 */ 57/* A4 -388437573 */ 58/* A5 752975383 */ 59/* A6 -1103016663 */ 60/* A7 1121848567 */ 61/* A8 -688078159 */ 62/* A9 194669577 */ 63/* A10 8 */ 64/* */ 65/* Y = (A0 + A1*X + A2*X2 + A3*X3 + �.. + AN*xN) << AN+1 */ 66/* */ 67/* */ 68/* PARAMETERS: */ 69/* */ 70/* w Sample rate in radians, where: */ 71/* w = 2 * Pi * Fc / Fs */ 72/* Fc is the corner frequency in Hz */ 73/* Fs is the sample rate in Hz */ 74/* w is in Q2.29 format and data range is [0 Pi] */ 75/* pCoeffs Points to the filter coefficients calculated here */ 76/* in Q1.30 format */ 77/* RETURNS: */ 78/* */ 79/*-------------------------------------------------------------------------*/ 80 81LVM_INT32 LVM_FO_LPF( LVM_INT32 w, 82 FO_C32_Coefs_t *pCoeffs) 83{ 84 LVM_INT32 Y,Coefficients[13]={ -8388571, 85 33547744, 86 -66816791, 87 173375308, 88 -388437573, 89 752975383, 90 -1103016663, 91 1121848567, 92 -688078159, 93 194669577, 94 8}; 95 Y=LVM_Polynomial( (LVM_UINT16)9, 96 Coefficients, 97 w); 98 pCoeffs->B1=-Y; // Store -B1 in filter structure instead of B1! 99 // A0=(1+B1)/2= B1/2 + 0.5 100 Y=Y>>1; // A0=Y=B1/2 101 Y=Y+0x40000000; // A0=Y=(B1/2 + 0.5) 102 MUL32x16INTO32(Y, FILTER_LOSS ,pCoeffs->A0 ,15) // Apply loss to avoid overflow 103 pCoeffs->A1=pCoeffs->A0; 104 return 1; 105} 106 107