qm-dsp
1.8
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 QM DSP Library 00005 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file 2005-2006 Christian Landone. 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License as 00011 published by the Free Software Foundation; either version 2 of the 00012 License, or (at your option) any later version. See the file 00013 COPYING included with this distribution for more information. 00014 */ 00015 00016 #include "Decimator.h" 00017 00018 #include <iostream> 00019 00021 // Construction/Destruction 00023 00024 Decimator::Decimator( unsigned int inLength, unsigned int decFactor ) 00025 { 00026 00027 m_inputLength = 0; 00028 m_outputLength = 0; 00029 m_decFactor = 1; 00030 00031 initialise( inLength, decFactor ); 00032 } 00033 00034 Decimator::~Decimator() 00035 { 00036 deInitialise(); 00037 } 00038 00039 void Decimator::initialise( unsigned int inLength, unsigned int decFactor) 00040 { 00041 m_inputLength = inLength; 00042 m_decFactor = decFactor; 00043 m_outputLength = m_inputLength / m_decFactor; 00044 00045 decBuffer = new double[ m_inputLength ]; 00046 00047 // If adding new factors here, add them to 00048 // getHighestSupportedFactor in the header as well 00049 00050 if(m_decFactor == 8) 00051 { 00053 b[0] = 0.060111378492136; 00054 b[1] = -0.257323420830598; 00055 b[2] = 0.420583503165928; 00056 b[3] = -0.222750785197418; 00057 b[4] = -0.222750785197418; 00058 b[5] = 0.420583503165928; 00059 b[6] = -0.257323420830598; 00060 b[7] = 0.060111378492136; 00061 00062 a[0] = 1; 00063 a[1] = -5.667654878577432; 00064 a[2] = 14.062452278088417; 00065 a[3] = -19.737303840697738; 00066 a[4] = 16.889698874608641; 00067 a[5] = -8.796600612325928; 00068 a[6] = 2.577553446979888; 00069 a[7] = -0.326903916815751; 00071 } 00072 else if( m_decFactor == 4 ) 00073 { 00075 b[ 0 ] = 0.10133306904918619; 00076 b[ 1 ] = -0.2447523353702363; 00077 b[ 2 ] = 0.33622528590120965; 00078 b[ 3 ] = -0.13936581560633518; 00079 b[ 4 ] = -0.13936581560633382; 00080 b[ 5 ] = 0.3362252859012087; 00081 b[ 6 ] = -0.2447523353702358; 00082 b[ 7 ] = 0.10133306904918594; 00083 00084 a[ 0 ] = 1; 00085 a[ 1 ] = -3.9035590278139427; 00086 a[ 2 ] = 7.5299379980621133; 00087 a[ 3 ] = -8.6890803793177511; 00088 a[ 4 ] = 6.4578667096099176; 00089 a[ 5 ] = -3.0242979431223631; 00090 a[ 6 ] = 0.83043385136748382; 00091 a[ 7 ] = -0.094420800837809335; 00093 } 00094 else if( m_decFactor == 2 ) 00095 { 00097 b[ 0 ] = 0.20898944260075727; 00098 b[ 1 ] = 0.40011234879814367; 00099 b[ 2 ] = 0.819741973072733; 00100 b[ 3 ] = 1.0087419911682323; 00101 b[ 4 ] = 1.0087419911682325; 00102 b[ 5 ] = 0.81974197307273156; 00103 b[ 6 ] = 0.40011234879814295; 00104 b[ 7 ] = 0.20898944260075661; 00105 00106 a[ 0 ] = 1; 00107 a[ 1 ] = 0.0077331184208358217; 00108 a[ 2 ] = 1.9853971155964376; 00109 a[ 3 ] = 0.19296739275341004; 00110 a[ 4 ] = 1.2330748872852182; 00111 a[ 5 ] = 0.18705341389316466; 00112 a[ 6 ] = 0.23659265908013868; 00113 a[ 7 ] = 0.032352924250533946; 00114 } 00115 else 00116 { 00117 if ( m_decFactor != 1 ) { 00118 std::cerr << "WARNING: Decimator::initialise: unsupported decimation factor " << m_decFactor << ", no antialiasing filter will be used" << std::endl; 00119 } 00120 00122 b[ 0 ] = 1; 00123 b[ 1 ] = 0; 00124 b[ 2 ] = 0; 00125 b[ 3 ] = 0; 00126 b[ 4 ] = 0; 00127 b[ 5 ] = 0; 00128 b[ 6 ] = 0; 00129 b[ 7 ] = 0; 00130 00131 a[ 0 ] = 1; 00132 a[ 1 ] = 0; 00133 a[ 2 ] = 0; 00134 a[ 3 ] = 0; 00135 a[ 4 ] = 0; 00136 a[ 5 ] = 0; 00137 a[ 6 ] = 0; 00138 a[ 7 ] = 0; 00139 } 00140 00141 resetFilter(); 00142 } 00143 00144 void Decimator::deInitialise() 00145 { 00146 delete [] decBuffer; 00147 } 00148 00149 void Decimator::resetFilter() 00150 { 00151 Input = Output = 0; 00152 00153 o1=o2=o3=o4=o5=o6=o7=0; 00154 } 00155 00156 void Decimator::doAntiAlias(const double *src, double *dst, unsigned int length) 00157 { 00158 00159 for( unsigned int i = 0; i < length; i++ ) 00160 { 00161 Input = (double)src[ i ]; 00162 00163 Output = Input * b[ 0 ] + o1; 00164 00165 o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2; 00166 o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3; 00167 o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4; 00168 o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5; 00169 o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6; 00170 o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7; 00171 o7 = Input * b[ 7 ] - Output * a[ 7 ] ; 00172 00173 dst[ i ] = Output; 00174 } 00175 00176 } 00177 00178 void Decimator::doAntiAlias(const float *src, double *dst, unsigned int length) 00179 { 00180 00181 for( unsigned int i = 0; i < length; i++ ) 00182 { 00183 Input = (double)src[ i ]; 00184 00185 Output = Input * b[ 0 ] + o1; 00186 00187 o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2; 00188 o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3; 00189 o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4; 00190 o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5; 00191 o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6; 00192 o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7; 00193 o7 = Input * b[ 7 ] - Output * a[ 7 ] ; 00194 00195 dst[ i ] = Output; 00196 } 00197 00198 } 00199 00200 void Decimator::process(const double *src, double *dst) 00201 { 00202 if (m_decFactor == 1) { 00203 for( unsigned int i = 0; i < m_outputLength; i++ ) { 00204 dst[i] = src[i]; 00205 } 00206 return; 00207 } 00208 00209 doAntiAlias( src, decBuffer, m_inputLength ); 00210 00211 unsigned idx = 0; 00212 00213 for( unsigned int i = 0; i < m_outputLength; i++ ) 00214 { 00215 dst[ idx++ ] = decBuffer[ m_decFactor * i ]; 00216 } 00217 } 00218 00219 void Decimator::process(const float *src, float *dst) 00220 { 00221 if (m_decFactor == 1) { 00222 for( unsigned int i = 0; i < m_outputLength; i++ ) { 00223 dst[i] = src[i]; 00224 } 00225 return; 00226 } 00227 00228 doAntiAlias( src, decBuffer, m_inputLength ); 00229 00230 unsigned idx = 0; 00231 00232 for( unsigned int i = 0; i < m_outputLength; i++ ) 00233 { 00234 dst[ idx++ ] = decBuffer[ m_decFactor * i ]; 00235 } 00236 }