MythTV  0.25-pre
AAFilter.cpp
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 //
00015 // Last changed  : $Date$
00016 // File revision : $Revision$
00017 //
00018 // $Id$
00019 //
00021 //
00022 // License :
00023 //
00024 //  SoundTouch audio processing library
00025 //  Copyright (c) Olli Parviainen
00026 //
00027 //  This library is free software; you can redistribute it and/or
00028 //  modify it under the terms of the GNU Lesser General Public
00029 //  License as published by the Free Software Foundation; either
00030 //  version 2.1 of the License, or (at your option) any later version.
00031 //
00032 //  This library is distributed in the hope that it will be useful,
00033 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00034 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00035 //  Lesser General Public License for more details.
00036 //
00037 //  You should have received a copy of the GNU Lesser General Public
00038 //  License along with this library; if not, write to the Free Software
00039 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00040 //
00042 
00043 #include <memory.h>
00044 #include <assert.h>
00045 #include <math.h>
00046 #include <stdlib.h>
00047 #include "AAFilter.h"
00048 #include "FIRFilter.h"
00049 
00050 using namespace soundtouch;
00051 
00052 #define PI        3.141592655357989
00053 #define TWOPI    (2 * PI)
00054 
00055 /*****************************************************************************
00056  *
00057  * Implementation of the class 'AAFilter'
00058  *
00059  *****************************************************************************/
00060 
00061 AAFilter::AAFilter(const uint length)
00062 {
00063     pFIR = FIRFilter::newInstance();
00064     cutoffFreq = 0.5;
00065     setLength(length);
00066 }
00067 
00068 
00069 
00070 AAFilter::~AAFilter()
00071 {
00072     delete pFIR;
00073 }
00074 
00075 
00076 
00077 // Sets new anti-alias filter cut-off edge frequency, scaled to
00078 // sampling frequency (nyquist frequency = 0.5).
00079 // The filter will cut frequencies higher than the given frequency.
00080 void AAFilter::setCutoffFreq(const double newCutoffFreq)
00081 {
00082     cutoffFreq = newCutoffFreq;
00083     calculateCoeffs();
00084 }
00085 
00086 
00087 
00088 // Sets number of FIR filter taps
00089 void AAFilter::setLength(const uint newLength)
00090 {
00091     length = newLength;
00092     calculateCoeffs();
00093 }
00094 
00095 
00096 
00097 // Calculates coefficients for a low-pass FIR filter using Hamming window
00098 void AAFilter::calculateCoeffs()
00099 {
00100     uint i;
00101     double cntTemp, temp, tempCoeff,h, w;
00102     double fc2, wc;
00103     double scaleCoeff, sum;
00104     double *work;
00105     SAMPLETYPE *coeffs;
00106 
00107     assert(length > 0);
00108     assert(length % 4 == 0);
00109     assert(cutoffFreq >= 0);
00110     assert(cutoffFreq <= 0.5);
00111 
00112     work = new double[length];
00113     coeffs = new SAMPLETYPE[length];
00114 
00115     fc2 = 2.0 * cutoffFreq; 
00116     wc = PI * fc2;
00117     tempCoeff = TWOPI / (double)length;
00118 
00119     sum = 0;
00120     for (i = 0; i < length; i ++) 
00121     {
00122         cntTemp = (double)i - (double)(length / 2);
00123 
00124         temp = cntTemp * wc;
00125         if (temp != 0) 
00126         {
00127             h = fc2 * sin(temp) / temp;                     // sinc function
00128         } 
00129         else 
00130         {
00131             h = 1.0;
00132         }
00133         w = 0.54 + 0.46 * cos(tempCoeff * cntTemp);       // hamming window
00134 
00135         temp = w * h;
00136         work[i] = temp;
00137 
00138         // calc net sum of coefficients 
00139         sum += temp;
00140     }
00141 
00142     // ensure the sum of coefficients is larger than zero
00143     assert(sum > 0);
00144 
00145     // ensure we've really designed a lowpass filter...
00146     assert(work[length/2] > 0);
00147     assert(work[length/2 + 1] > -1e-6);
00148     assert(work[length/2 - 1] > -1e-6);
00149 
00150     // Calculate a scaling coefficient in such a way that the result can be
00151     // divided by 16384
00152     scaleCoeff = 16384.0f / sum;
00153 
00154     for (i = 0; i < length; i ++) 
00155     {
00156         // scale & round to nearest integer
00157         temp = work[i] * scaleCoeff;
00158         temp += (temp >= 0) ? 0.5 : -0.5;
00159         // ensure no overfloods
00160         assert(temp >= -32768 && temp <= 32767);
00161         coeffs[i] = (SAMPLETYPE)temp;
00162     }
00163 
00164     // Set coefficients. Use divide factor 14 => divide result by 2^14 = 16384
00165     pFIR->setCoefficients(coeffs, length, 14);
00166 
00167     delete[] work;
00168     delete[] coeffs;
00169 }
00170 
00171 
00172 // Applies the filter to the given sequence of samples. 
00173 // Note : The amount of outputted samples is by value of 'filter length' 
00174 // smaller than the amount of input samples.
00175 uint AAFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
00176 {
00177     return pFIR->evaluate(dest, src, numSamples, numChannels);
00178 }
00179 
00180 
00181 uint AAFilter::getLength() const
00182 {
00183     return pFIR->getLength();
00184 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends