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@225
|
7 This file copyright 2005-2006 Christian Landone.
|
c@225
|
8 All rights reserved.
|
c@225
|
9 */
|
c@225
|
10
|
c@225
|
11 #include "Decimator.h"
|
c@225
|
12
|
c@225
|
13 //////////////////////////////////////////////////////////////////////
|
c@225
|
14 // Construction/Destruction
|
c@225
|
15 //////////////////////////////////////////////////////////////////////
|
c@225
|
16
|
c@225
|
17 Decimator::Decimator( unsigned int inLength, unsigned int decFactor )
|
c@225
|
18 {
|
c@225
|
19
|
c@225
|
20 m_inputLength = 0;
|
c@225
|
21 m_outputLength = 0;
|
c@225
|
22 m_decFactor = 1;
|
c@225
|
23
|
c@225
|
24 initialise( inLength, decFactor );
|
c@225
|
25 }
|
c@225
|
26
|
c@225
|
27 Decimator::~Decimator()
|
c@225
|
28 {
|
c@225
|
29 deInitialise();
|
c@225
|
30 }
|
c@225
|
31
|
c@225
|
32 void Decimator::initialise( unsigned int inLength, unsigned int decFactor)
|
c@225
|
33 {
|
c@225
|
34 m_inputLength = inLength;
|
c@225
|
35 m_decFactor = decFactor;
|
c@225
|
36 m_outputLength = m_inputLength / m_decFactor;
|
c@225
|
37
|
c@225
|
38 decBuffer = new double[ m_inputLength ];
|
c@225
|
39
|
c@225
|
40 if( m_decFactor == 4 )
|
c@225
|
41 {
|
c@225
|
42 //////////////////////////////////////////////////
|
c@225
|
43 b[ 0 ] = 0.10133306904918619;
|
c@225
|
44 b[ 1 ] = -0.2447523353702363;
|
c@225
|
45 b[ 2 ] = 0.33622528590120965;
|
c@225
|
46 b[ 3 ] = -0.13936581560633518;
|
c@225
|
47 b[ 4 ] = -0.13936581560633382;
|
c@225
|
48 b[ 5 ] = 0.3362252859012087;
|
c@225
|
49 b[ 6 ] = -0.2447523353702358;
|
c@225
|
50 b[ 7 ] = 0.10133306904918594;
|
c@225
|
51
|
c@225
|
52 a[ 0 ] = 1;
|
c@225
|
53 a[ 1 ] = -3.9035590278139427;
|
c@225
|
54 a[ 2 ] = 7.5299379980621133;
|
c@225
|
55 a[ 3 ] = -8.6890803793177511;
|
c@225
|
56 a[ 4 ] = 6.4578667096099176;
|
c@225
|
57 a[ 5 ] = -3.0242979431223631;
|
c@225
|
58 a[ 6 ] = 0.83043385136748382;
|
c@225
|
59 a[ 7 ] = -0.094420800837809335;
|
c@225
|
60 //////////////////////////////////////////////////
|
c@225
|
61 }
|
c@225
|
62 else if( m_decFactor == 2 )
|
c@225
|
63 {
|
c@225
|
64 //////////////////////////////////////////////////
|
c@225
|
65 b[ 0 ] = 0.20898944260075727;
|
c@225
|
66 b[ 1 ] = 0.40011234879814367;
|
c@225
|
67 b[ 2 ] = 0.819741973072733;
|
c@225
|
68 b[ 3 ] = 1.0087419911682323;
|
c@225
|
69 b[ 4 ] = 1.0087419911682325;
|
c@225
|
70 b[ 5 ] = 0.81974197307273156;
|
c@225
|
71 b[ 6 ] = 0.40011234879814295;
|
c@225
|
72 b[ 7 ] = 0.20898944260075661;
|
c@225
|
73
|
c@225
|
74 a[ 0 ] = 1;
|
c@225
|
75 a[ 1 ] = 0.0077331184208358217;
|
c@225
|
76 a[ 2 ] = 1.9853971155964376;
|
c@225
|
77 a[ 3 ] = 0.19296739275341004;
|
c@225
|
78 a[ 4 ] = 1.2330748872852182;
|
c@225
|
79 a[ 5 ] = 0.18705341389316466;
|
c@225
|
80 a[ 6 ] = 0.23659265908013868;
|
c@225
|
81 a[ 7 ] = 0.032352924250533946;
|
c@225
|
82 }
|
c@225
|
83 else
|
c@225
|
84 {
|
c@225
|
85 //////////////////////////////////////////////////
|
c@225
|
86 b[ 0 ] = 1;
|
c@225
|
87 b[ 1 ] = 0;
|
c@225
|
88 b[ 2 ] = 0;
|
c@225
|
89 b[ 3 ] = 0;
|
c@225
|
90 b[ 4 ] = 0;
|
c@225
|
91 b[ 5 ] = 0;
|
c@225
|
92 b[ 6 ] = 0;
|
c@225
|
93 b[ 7 ] = 0;
|
c@225
|
94
|
c@225
|
95 a[ 0 ] = 1;
|
c@225
|
96 a[ 1 ] = 0;
|
c@225
|
97 a[ 2 ] = 0;
|
c@225
|
98 a[ 3 ] = 0;
|
c@225
|
99 a[ 4 ] = 0;
|
c@225
|
100 a[ 5 ] = 0;
|
c@225
|
101 a[ 6 ] = 0;
|
c@225
|
102 a[ 7 ] = 0;
|
c@225
|
103 }
|
c@225
|
104
|
c@225
|
105 resetFilter();
|
c@225
|
106 }
|
c@225
|
107
|
c@225
|
108 void Decimator::deInitialise()
|
c@225
|
109 {
|
c@225
|
110 delete [] decBuffer;
|
c@225
|
111 }
|
c@225
|
112
|
c@225
|
113 void Decimator::resetFilter()
|
c@225
|
114 {
|
c@225
|
115 Input = Output = 0;
|
c@225
|
116
|
c@225
|
117 o1=o2=o3=o4=o5=o6=o7=0;
|
c@225
|
118 }
|
c@225
|
119
|
c@225
|
120 void Decimator::doAntiAlias(double *src, double *dst, unsigned int length)
|
c@225
|
121 {
|
c@225
|
122
|
c@225
|
123 for( unsigned int i = 0; i < length; i++ )
|
c@225
|
124 {
|
c@225
|
125 Input = (double)src[ i ];
|
c@225
|
126
|
c@225
|
127 Output = Input * b[ 0 ] + o1;
|
c@225
|
128
|
c@225
|
129 o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2;
|
c@225
|
130 o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3;
|
c@225
|
131 o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4;
|
c@225
|
132 o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5;
|
c@225
|
133 o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6;
|
c@225
|
134 o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7;
|
c@225
|
135 o7 = Input * b[ 7 ] - Output * a[ 7 ] ;
|
c@225
|
136
|
c@225
|
137 dst[ i ] = Output;
|
c@225
|
138 }
|
c@225
|
139
|
c@225
|
140 }
|
c@225
|
141
|
c@225
|
142 void Decimator::process(double *src, double *dst)
|
c@225
|
143 {
|
c@225
|
144 if( m_decFactor != 1 )
|
c@225
|
145 {
|
c@225
|
146 doAntiAlias( src, decBuffer, m_inputLength );
|
c@225
|
147 }
|
c@225
|
148 unsigned idx = 0;
|
c@225
|
149
|
c@225
|
150 for( unsigned int i = 0; i < m_outputLength; i++ )
|
c@225
|
151 {
|
c@225
|
152 dst[ idx++ ] = decBuffer[ m_decFactor * i ];
|
c@225
|
153 }
|
c@225
|
154 }
|