~alex.barker/mixxx/mixxx-libs

« back to all changes in this revision

Viewing changes to mixxx/lib/soundtouch-1.6.0/AAFilter.cpp

  • Committer: Alex Barker
  • Date: 2011-07-24 21:06:29 UTC
  • Revision ID: alex@1stleg.com-20110724210629-zyr2khq2o0nv8iru
Updated libsoundtouch and fidlib to latest versions

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
////////////////////////////////////////////////////////////////////////////////
 
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
}