/[pcsx2_0.9.7]/trunk/3rdparty/SoundTouch/AAFilter.cpp
ViewVC logotype

Annotation of /trunk/3rdparty/SoundTouch/AAFilter.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (hide annotations) (download)
Mon Sep 6 11:40:06 2010 UTC (9 years, 10 months ago) by william
File size: 5209 byte(s)
exported r3113 from ./upstream/trunk
1 william 10 ////////////////////////////////////////////////////////////////////////////////
2     ///
3     /// FIR low-pass (anti-alias) filter with filter coefficient design routine and
4     /// MMX optimization.
5     ///
6     /// Anti-alias filter is used to prevent folding of high frequencies when
7     /// transposing the sample rate with interpolation.
8     ///
9     /// Author : Copyright (c) Olli Parviainen
10     /// Author e-mail : oparviai 'at' iki.fi
11     /// SoundTouch WWW: http://www.surina.net/soundtouch
12     ///
13     ////////////////////////////////////////////////////////////////////////////////
14     //
15     // Last changed : $Date: 2009-01-11 13:34:24 +0200 (Sun, 11 Jan 2009) $
16     // File revision : $Revision: 4 $
17     //
18     // $Id: AAFilter.cpp 45 2009-01-11 11:34:24Z oparviai $
19     //
20     ////////////////////////////////////////////////////////////////////////////////
21     //
22     // License :
23     //
24     // SoundTouch audio processing library
25     // Copyright (c) Olli Parviainen
26     //
27     // This library is free software; you can redistribute it and/or
28     // modify it under the terms of the GNU Lesser General Public
29     // License as published by the Free Software Foundation; either
30     // version 2.1 of the License, or (at your option) any later version.
31     //
32     // This library is distributed in the hope that it will be useful,
33     // but WITHOUT ANY WARRANTY; without even the implied warranty of
34     // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35     // Lesser General Public License for more details.
36     //
37     // You should have received a copy of the GNU Lesser General Public
38     // License along with this library; if not, write to the Free Software
39     // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40     //
41     ////////////////////////////////////////////////////////////////////////////////
42    
43     #include <memory.h>
44     #include <assert.h>
45     #include <math.h>
46     #include <stdlib.h>
47     #include "AAFilter.h"
48     #include "FIRFilter.h"
49    
50     using namespace soundtouch;
51    
52     #define PI 3.141592655357989
53     #define TWOPI (2 * PI)
54    
55     /*****************************************************************************
56     *
57     * Implementation of the class 'AAFilter'
58     *
59     *****************************************************************************/
60    
61     AAFilter::AAFilter(uint len)
62     {
63     pFIR = FIRFilter::newInstance();
64     cutoffFreq = 0.5;
65     setLength(len);
66     }
67    
68    
69    
70     AAFilter::~AAFilter()
71     {
72     delete pFIR;
73     }
74    
75    
76    
77     // Sets new anti-alias filter cut-off edge frequency, scaled to
78     // sampling frequency (nyquist frequency = 0.5).
79     // The filter will cut frequencies higher than the given frequency.
80     void AAFilter::setCutoffFreq(double newCutoffFreq)
81     {
82     cutoffFreq = newCutoffFreq;
83     calculateCoeffs();
84     }
85    
86    
87    
88     // Sets number of FIR filter taps
89     void AAFilter::setLength(uint newLength)
90     {
91     length = newLength;
92     calculateCoeffs();
93     }
94    
95    
96    
97     // Calculates coefficients for a low-pass FIR filter using Hamming window
98     void AAFilter::calculateCoeffs()
99     {
100     uint i;
101     double cntTemp, temp, tempCoeff,h, w;
102     double fc2, wc;
103     double scaleCoeff, sum;
104     double *work;
105     SAMPLETYPE *coeffs;
106    
107     assert(length >= 2);
108     assert(length % 4 == 0);
109     assert(cutoffFreq >= 0);
110     assert(cutoffFreq <= 0.5);
111    
112     work = new double[length];
113     coeffs = new SAMPLETYPE[length];
114    
115     fc2 = 2.0 * cutoffFreq;
116     wc = PI * fc2;
117     tempCoeff = TWOPI / (double)length;
118    
119     sum = 0;
120     for (i = 0; i < length; i ++)
121     {
122     cntTemp = (double)i - (double)(length / 2);
123    
124     temp = cntTemp * wc;
125     if (temp != 0)
126     {
127     h = fc2 * sin(temp) / temp; // sinc function
128     }
129     else
130     {
131     h = 1.0;
132     }
133     w = 0.54 + 0.46 * cos(tempCoeff * cntTemp); // hamming window
134    
135     temp = w * h;
136     work[i] = temp;
137    
138     // calc net sum of coefficients
139     sum += temp;
140     }
141    
142     // ensure the sum of coefficients is larger than zero
143     assert(sum > 0);
144    
145     // ensure we've really designed a lowpass filter...
146     assert(work[length/2] > 0);
147     assert(work[length/2 + 1] > -1e-6);
148     assert(work[length/2 - 1] > -1e-6);
149    
150     // Calculate a scaling coefficient in such a way that the result can be
151     // divided by 16384
152     scaleCoeff = 16384.0f / sum;
153    
154     for (i = 0; i < length; i ++)
155     {
156     // scale & round to nearest integer
157     temp = work[i] * scaleCoeff;
158     temp += (temp >= 0) ? 0.5 : -0.5;
159     // ensure no overfloods
160     assert(temp >= -32768 && temp <= 32767);
161     coeffs[i] = (SAMPLETYPE)temp;
162     }
163    
164     // Set coefficients. Use divide factor 14 => divide result by 2^14 = 16384
165     pFIR->setCoefficients(coeffs, length, 14);
166    
167     delete[] work;
168     delete[] coeffs;
169     }
170    
171    
172     // Applies the filter to the given sequence of samples.
173     // Note : The amount of outputted samples is by value of 'filter length'
174     // smaller than the amount of input samples.
175     uint AAFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
176     {
177     return pFIR->evaluate(dest, src, numSamples, numChannels);
178     }
179    
180    
181     uint AAFilter::getLength() const
182     {
183     return pFIR->getLength();
184     }

  ViewVC Help
Powered by ViewVC 1.1.22