c@225
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
c@225
|
2
|
c@225
|
3 /*
|
c@225
|
4 QM DSP Library
|
c@225
|
5
|
c@225
|
6 Centre for Digital Music, Queen Mary, University of London.
|
c@309
|
7 This file 2005-2006 Christian Landone.
|
c@309
|
8
|
c@309
|
9 This program is free software; you can redistribute it and/or
|
c@309
|
10 modify it under the terms of the GNU General Public License as
|
c@309
|
11 published by the Free Software Foundation; either version 2 of the
|
c@309
|
12 License, or (at your option) any later version. See the file
|
c@309
|
13 COPYING included with this distribution for more information.
|
c@225
|
14 */
|
c@225
|
15
|
c@225
|
16 #include "Decimator.h"
|
c@225
|
17
|
c@247
|
18 #include <iostream>
|
c@247
|
19
|
c@225
|
20 //////////////////////////////////////////////////////////////////////
|
c@225
|
21 // Construction/Destruction
|
c@225
|
22 //////////////////////////////////////////////////////////////////////
|
c@225
|
23
|
cannam@499
|
24 Decimator::Decimator( int inLength, int decFactor )
|
c@225
|
25 {
|
c@225
|
26 m_inputLength = 0;
|
c@225
|
27 m_outputLength = 0;
|
c@225
|
28 m_decFactor = 1;
|
c@225
|
29
|
c@225
|
30 initialise( inLength, decFactor );
|
c@225
|
31 }
|
c@225
|
32
|
c@225
|
33 Decimator::~Decimator()
|
c@225
|
34 {
|
c@225
|
35 deInitialise();
|
c@225
|
36 }
|
c@225
|
37
|
cannam@499
|
38 void Decimator::initialise( int inLength, int decFactor)
|
c@225
|
39 {
|
c@225
|
40 m_inputLength = inLength;
|
c@225
|
41 m_decFactor = decFactor;
|
c@225
|
42 m_outputLength = m_inputLength / m_decFactor;
|
c@225
|
43
|
c@225
|
44 decBuffer = new double[ m_inputLength ];
|
c@225
|
45
|
c@247
|
46 // If adding new factors here, add them to
|
c@247
|
47 // getHighestSupportedFactor in the header as well
|
c@247
|
48
|
cannam@483
|
49 if(m_decFactor == 8) {
|
cannam@483
|
50
|
c@247
|
51 //////////////////////////////////////////////////
|
c@247
|
52 b[0] = 0.060111378492136;
|
c@247
|
53 b[1] = -0.257323420830598;
|
c@247
|
54 b[2] = 0.420583503165928;
|
c@247
|
55 b[3] = -0.222750785197418;
|
c@247
|
56 b[4] = -0.222750785197418;
|
c@247
|
57 b[5] = 0.420583503165928;
|
c@247
|
58 b[6] = -0.257323420830598;
|
c@247
|
59 b[7] = 0.060111378492136;
|
c@247
|
60
|
c@247
|
61 a[0] = 1;
|
c@247
|
62 a[1] = -5.667654878577432;
|
c@247
|
63 a[2] = 14.062452278088417;
|
c@247
|
64 a[3] = -19.737303840697738;
|
c@247
|
65 a[4] = 16.889698874608641;
|
c@247
|
66 a[5] = -8.796600612325928;
|
c@247
|
67 a[6] = 2.577553446979888;
|
c@247
|
68 a[7] = -0.326903916815751;
|
c@247
|
69 //////////////////////////////////////////////////
|
c@225
|
70
|
cannam@483
|
71 } else if( m_decFactor == 4 ) {
|
cannam@483
|
72
|
cannam@483
|
73 //////////////////////////////////////////////////
|
cannam@483
|
74 b[ 0 ] = 0.10133306904918619;
|
cannam@483
|
75 b[ 1 ] = -0.2447523353702363;
|
cannam@483
|
76 b[ 2 ] = 0.33622528590120965;
|
cannam@483
|
77 b[ 3 ] = -0.13936581560633518;
|
cannam@483
|
78 b[ 4 ] = -0.13936581560633382;
|
cannam@483
|
79 b[ 5 ] = 0.3362252859012087;
|
cannam@483
|
80 b[ 6 ] = -0.2447523353702358;
|
cannam@483
|
81 b[ 7 ] = 0.10133306904918594;
|
c@225
|
82
|
cannam@483
|
83 a[ 0 ] = 1;
|
cannam@483
|
84 a[ 1 ] = -3.9035590278139427;
|
cannam@483
|
85 a[ 2 ] = 7.5299379980621133;
|
cannam@483
|
86 a[ 3 ] = -8.6890803793177511;
|
cannam@483
|
87 a[ 4 ] = 6.4578667096099176;
|
cannam@483
|
88 a[ 5 ] = -3.0242979431223631;
|
cannam@483
|
89 a[ 6 ] = 0.83043385136748382;
|
cannam@483
|
90 a[ 7 ] = -0.094420800837809335;
|
cannam@483
|
91 //////////////////////////////////////////////////
|
cannam@483
|
92
|
cannam@483
|
93 } else if( m_decFactor == 2 ) {
|
cannam@483
|
94
|
cannam@483
|
95 //////////////////////////////////////////////////
|
cannam@483
|
96 b[ 0 ] = 0.20898944260075727;
|
cannam@483
|
97 b[ 1 ] = 0.40011234879814367;
|
cannam@483
|
98 b[ 2 ] = 0.819741973072733;
|
cannam@483
|
99 b[ 3 ] = 1.0087419911682323;
|
cannam@483
|
100 b[ 4 ] = 1.0087419911682325;
|
cannam@483
|
101 b[ 5 ] = 0.81974197307273156;
|
cannam@483
|
102 b[ 6 ] = 0.40011234879814295;
|
cannam@483
|
103 b[ 7 ] = 0.20898944260075661;
|
cannam@483
|
104
|
cannam@483
|
105 a[ 0 ] = 1;
|
cannam@483
|
106 a[ 1 ] = 0.0077331184208358217;
|
cannam@483
|
107 a[ 2 ] = 1.9853971155964376;
|
cannam@483
|
108 a[ 3 ] = 0.19296739275341004;
|
cannam@483
|
109 a[ 4 ] = 1.2330748872852182;
|
cannam@483
|
110 a[ 5 ] = 0.18705341389316466;
|
cannam@483
|
111 a[ 6 ] = 0.23659265908013868;
|
cannam@483
|
112 a[ 7 ] = 0.032352924250533946;
|
cannam@483
|
113
|
cannam@483
|
114 } else {
|
cannam@483
|
115
|
c@247
|
116 if ( m_decFactor != 1 ) {
|
c@247
|
117 std::cerr << "WARNING: Decimator::initialise: unsupported decimation factor " << m_decFactor << ", no antialiasing filter will be used" << std::endl;
|
c@247
|
118 }
|
c@247
|
119
|
cannam@483
|
120 //////////////////////////////////////////////////
|
cannam@483
|
121 b[ 0 ] = 1;
|
cannam@483
|
122 b[ 1 ] = 0;
|
cannam@483
|
123 b[ 2 ] = 0;
|
cannam@483
|
124 b[ 3 ] = 0;
|
cannam@483
|
125 b[ 4 ] = 0;
|
cannam@483
|
126 b[ 5 ] = 0;
|
cannam@483
|
127 b[ 6 ] = 0;
|
cannam@483
|
128 b[ 7 ] = 0;
|
c@225
|
129
|
cannam@483
|
130 a[ 0 ] = 1;
|
cannam@483
|
131 a[ 1 ] = 0;
|
cannam@483
|
132 a[ 2 ] = 0;
|
cannam@483
|
133 a[ 3 ] = 0;
|
cannam@483
|
134 a[ 4 ] = 0;
|
cannam@483
|
135 a[ 5 ] = 0;
|
cannam@483
|
136 a[ 6 ] = 0;
|
cannam@483
|
137 a[ 7 ] = 0;
|
c@225
|
138 }
|
c@225
|
139
|
c@225
|
140 resetFilter();
|
c@225
|
141 }
|
c@225
|
142
|
c@225
|
143 void Decimator::deInitialise()
|
c@225
|
144 {
|
c@225
|
145 delete [] decBuffer;
|
c@225
|
146 }
|
c@225
|
147
|
c@225
|
148 void Decimator::resetFilter()
|
c@225
|
149 {
|
c@225
|
150 Input = Output = 0;
|
c@225
|
151
|
c@225
|
152 o1=o2=o3=o4=o5=o6=o7=0;
|
c@225
|
153 }
|
c@225
|
154
|
cannam@499
|
155 void Decimator::doAntiAlias(const double *src, double *dst, int length)
|
c@225
|
156 {
|
cannam@499
|
157 for (int i = 0; i < length; i++ ) {
|
cannam@483
|
158
|
cannam@483
|
159 Input = (double)src[ i ];
|
c@225
|
160
|
cannam@483
|
161 Output = Input * b[ 0 ] + o1;
|
c@225
|
162
|
cannam@483
|
163 o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2;
|
cannam@483
|
164 o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3;
|
cannam@483
|
165 o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4;
|
cannam@483
|
166 o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5;
|
cannam@483
|
167 o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6;
|
cannam@483
|
168 o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7;
|
cannam@483
|
169 o7 = Input * b[ 7 ] - Output * a[ 7 ] ;
|
c@225
|
170
|
cannam@483
|
171 dst[ i ] = Output;
|
c@225
|
172 }
|
c@225
|
173 }
|
c@225
|
174
|
cannam@499
|
175 void Decimator::doAntiAlias(const float *src, double *dst, int length)
|
c@280
|
176 {
|
cannam@499
|
177 for (int i = 0; i < length; i++ ) {
|
cannam@483
|
178
|
cannam@483
|
179 Input = (double)src[ i ];
|
c@280
|
180
|
cannam@483
|
181 Output = Input * b[ 0 ] + o1;
|
c@280
|
182
|
cannam@483
|
183 o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2;
|
cannam@483
|
184 o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3;
|
cannam@483
|
185 o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4;
|
cannam@483
|
186 o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5;
|
cannam@483
|
187 o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6;
|
cannam@483
|
188 o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7;
|
cannam@483
|
189 o7 = Input * b[ 7 ] - Output * a[ 7 ] ;
|
c@280
|
190
|
cannam@483
|
191 dst[ i ] = Output;
|
c@280
|
192 }
|
c@280
|
193 }
|
c@280
|
194
|
c@247
|
195 void Decimator::process(const double *src, double *dst)
|
c@225
|
196 {
|
c@388
|
197 if (m_decFactor == 1) {
|
cannam@499
|
198 for (int i = 0; i < m_outputLength; i++ ) {
|
c@388
|
199 dst[i] = src[i];
|
c@388
|
200 }
|
c@388
|
201 return;
|
c@225
|
202 }
|
c@388
|
203
|
c@388
|
204 doAntiAlias( src, decBuffer, m_inputLength );
|
c@388
|
205
|
cannam@501
|
206 int idx = 0;
|
c@225
|
207
|
cannam@499
|
208 for (int i = 0; i < m_outputLength; i++ ) {
|
cannam@483
|
209 dst[ idx++ ] = decBuffer[ m_decFactor * i ];
|
c@225
|
210 }
|
c@225
|
211 }
|
c@280
|
212
|
c@280
|
213 void Decimator::process(const float *src, float *dst)
|
c@280
|
214 {
|
c@388
|
215 if (m_decFactor == 1) {
|
cannam@499
|
216 for (int i = 0; i < m_outputLength; i++ ) {
|
c@388
|
217 dst[i] = src[i];
|
c@388
|
218 }
|
c@388
|
219 return;
|
c@280
|
220 }
|
c@388
|
221
|
c@388
|
222 doAntiAlias( src, decBuffer, m_inputLength );
|
c@388
|
223
|
cannam@499
|
224 int idx = 0;
|
c@280
|
225
|
cannam@499
|
226 for (int i = 0; i < m_outputLength; i++ ) {
|
cannam@483
|
227 dst[ idx++ ] = decBuffer[ m_decFactor * i ];
|
c@280
|
228 }
|
c@280
|
229 }
|