Audaspace:
[blender-staging.git] / intern / audaspace / FX / AUD_ButterworthFactory.cpp
1 /*
2  * $Id$
3  *
4  * ***** BEGIN LGPL LICENSE BLOCK *****
5  *
6  * Copyright 2009 Jörg Hermann Müller
7  *
8  * This file is part of AudaSpace.
9  *
10  * AudaSpace is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * AudaSpace is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with AudaSpace.  If not, see <http://www.gnu.org/licenses/>.
22  *
23  * ***** END LGPL LICENSE BLOCK *****
24  */
25
26 #include "AUD_ButterworthFactory.h"
27 #include "AUD_IIRFilterReader.h"
28
29 #include <cmath>
30
31 #ifndef M_PI
32 #define M_PI 3.14159265358979323846
33 #endif
34
35 #define BWPB41 0.76536686473
36 #define BWPB42 1.84775906502
37
38 AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
39                                                                                            float frequency) :
40                 AUD_EffectFactory(factory),
41                 m_frequency(frequency)
42 {
43 }
44
45 AUD_IReader* AUD_ButterworthFactory::createReader() const
46 {
47         AUD_IReader* reader = getReader();
48
49         // calculate coefficients
50         float omega = 2 * tan(m_frequency * M_PI / reader->getSpecs().rate);
51         float o2 = omega * omega;
52         float o4 = o2 * o2;
53         float x1 = o2 + 2 * BWPB41 * omega + 4;
54         float x2 = o2 + 2 * BWPB42 * omega + 4;
55         float y1 = o2 - 2 * BWPB41 * omega + 4;
56         float y2 = o2 - 2 * BWPB42 * omega + 4;
57         float o228 = 2 * o2 - 8;
58         float norm = x1 * x2;
59         std::vector<float> a, b;
60         a.push_back(1);
61         a.push_back((x1 + x2) * o228 / norm);
62         a.push_back((x1 * y2 + x2 * y1 + o228 * o228) / norm);
63         a.push_back((y1 + y2) * o228 / norm);
64         a.push_back(y1 * y2 / norm);
65         b.push_back(o4 / norm);
66         b.push_back(4 * o4 / norm);
67         b.push_back(6 * o4 / norm);
68         b.push_back(b[1]);
69         b.push_back(b[0]);
70
71         return new AUD_IIRFilterReader(reader, b, a);
72 }