qm-dsp  1.8
Decimator.cpp
Go to the documentation of this file.
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 }