|
MythTV
0.25-pre
|
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 }
1.7.6.1