c@225: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ c@225: c@225: /* c@225: QM DSP Library c@225: c@225: Centre for Digital Music, Queen Mary, University of London. c@309: This file 2005-2006 Christian Landone. c@309: c@309: This program is free software; you can redistribute it and/or c@309: modify it under the terms of the GNU General Public License as c@309: published by the Free Software Foundation; either version 2 of the c@309: License, or (at your option) any later version. See the file c@309: COPYING included with this distribution for more information. c@225: */ c@225: c@225: #include "Decimator.h" c@225: c@247: #include c@247: c@225: ////////////////////////////////////////////////////////////////////// c@225: // Construction/Destruction c@225: ////////////////////////////////////////////////////////////////////// c@225: cannam@499: Decimator::Decimator( int inLength, int decFactor ) c@225: { c@225: m_inputLength = 0; c@225: m_outputLength = 0; c@225: m_decFactor = 1; c@225: c@225: initialise( inLength, decFactor ); c@225: } c@225: c@225: Decimator::~Decimator() c@225: { c@225: deInitialise(); c@225: } c@225: cannam@499: void Decimator::initialise( int inLength, int decFactor) c@225: { c@225: m_inputLength = inLength; c@225: m_decFactor = decFactor; c@225: m_outputLength = m_inputLength / m_decFactor; c@225: c@225: decBuffer = new double[ m_inputLength ]; c@225: c@247: // If adding new factors here, add them to c@247: // getHighestSupportedFactor in the header as well c@247: cannam@483: if(m_decFactor == 8) { cannam@483: c@247: ////////////////////////////////////////////////// c@247: b[0] = 0.060111378492136; c@247: b[1] = -0.257323420830598; c@247: b[2] = 0.420583503165928; c@247: b[3] = -0.222750785197418; c@247: b[4] = -0.222750785197418; c@247: b[5] = 0.420583503165928; c@247: b[6] = -0.257323420830598; c@247: b[7] = 0.060111378492136; c@247: c@247: a[0] = 1; c@247: a[1] = -5.667654878577432; c@247: a[2] = 14.062452278088417; c@247: a[3] = -19.737303840697738; c@247: a[4] = 16.889698874608641; c@247: a[5] = -8.796600612325928; c@247: a[6] = 2.577553446979888; c@247: a[7] = -0.326903916815751; c@247: ////////////////////////////////////////////////// c@225: cannam@483: } else if( m_decFactor == 4 ) { cannam@483: cannam@483: ////////////////////////////////////////////////// cannam@483: b[ 0 ] = 0.10133306904918619; cannam@483: b[ 1 ] = -0.2447523353702363; cannam@483: b[ 2 ] = 0.33622528590120965; cannam@483: b[ 3 ] = -0.13936581560633518; cannam@483: b[ 4 ] = -0.13936581560633382; cannam@483: b[ 5 ] = 0.3362252859012087; cannam@483: b[ 6 ] = -0.2447523353702358; cannam@483: b[ 7 ] = 0.10133306904918594; c@225: cannam@483: a[ 0 ] = 1; cannam@483: a[ 1 ] = -3.9035590278139427; cannam@483: a[ 2 ] = 7.5299379980621133; cannam@483: a[ 3 ] = -8.6890803793177511; cannam@483: a[ 4 ] = 6.4578667096099176; cannam@483: a[ 5 ] = -3.0242979431223631; cannam@483: a[ 6 ] = 0.83043385136748382; cannam@483: a[ 7 ] = -0.094420800837809335; cannam@483: ////////////////////////////////////////////////// cannam@483: cannam@483: } else if( m_decFactor == 2 ) { cannam@483: cannam@483: ////////////////////////////////////////////////// cannam@483: b[ 0 ] = 0.20898944260075727; cannam@483: b[ 1 ] = 0.40011234879814367; cannam@483: b[ 2 ] = 0.819741973072733; cannam@483: b[ 3 ] = 1.0087419911682323; cannam@483: b[ 4 ] = 1.0087419911682325; cannam@483: b[ 5 ] = 0.81974197307273156; cannam@483: b[ 6 ] = 0.40011234879814295; cannam@483: b[ 7 ] = 0.20898944260075661; cannam@483: cannam@483: a[ 0 ] = 1; cannam@483: a[ 1 ] = 0.0077331184208358217; cannam@483: a[ 2 ] = 1.9853971155964376; cannam@483: a[ 3 ] = 0.19296739275341004; cannam@483: a[ 4 ] = 1.2330748872852182; cannam@483: a[ 5 ] = 0.18705341389316466; cannam@483: a[ 6 ] = 0.23659265908013868; cannam@483: a[ 7 ] = 0.032352924250533946; cannam@483: cannam@483: } else { cannam@483: c@247: if ( m_decFactor != 1 ) { c@247: std::cerr << "WARNING: Decimator::initialise: unsupported decimation factor " << m_decFactor << ", no antialiasing filter will be used" << std::endl; c@247: } c@247: cannam@483: ////////////////////////////////////////////////// cannam@483: b[ 0 ] = 1; cannam@483: b[ 1 ] = 0; cannam@483: b[ 2 ] = 0; cannam@483: b[ 3 ] = 0; cannam@483: b[ 4 ] = 0; cannam@483: b[ 5 ] = 0; cannam@483: b[ 6 ] = 0; cannam@483: b[ 7 ] = 0; c@225: cannam@483: a[ 0 ] = 1; cannam@483: a[ 1 ] = 0; cannam@483: a[ 2 ] = 0; cannam@483: a[ 3 ] = 0; cannam@483: a[ 4 ] = 0; cannam@483: a[ 5 ] = 0; cannam@483: a[ 6 ] = 0; cannam@483: a[ 7 ] = 0; c@225: } c@225: c@225: resetFilter(); c@225: } c@225: c@225: void Decimator::deInitialise() c@225: { c@225: delete [] decBuffer; c@225: } c@225: c@225: void Decimator::resetFilter() c@225: { c@225: Input = Output = 0; c@225: c@225: o1=o2=o3=o4=o5=o6=o7=0; c@225: } c@225: cannam@499: void Decimator::doAntiAlias(const double *src, double *dst, int length) c@225: { cannam@499: for (int i = 0; i < length; i++ ) { cannam@483: cannam@483: Input = (double)src[ i ]; c@225: cannam@483: Output = Input * b[ 0 ] + o1; c@225: cannam@483: o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2; cannam@483: o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3; cannam@483: o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4; cannam@483: o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5; cannam@483: o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6; cannam@483: o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7; cannam@483: o7 = Input * b[ 7 ] - Output * a[ 7 ] ; c@225: cannam@483: dst[ i ] = Output; c@225: } c@225: } c@225: cannam@499: void Decimator::doAntiAlias(const float *src, double *dst, int length) c@280: { cannam@499: for (int i = 0; i < length; i++ ) { cannam@483: cannam@483: Input = (double)src[ i ]; c@280: cannam@483: Output = Input * b[ 0 ] + o1; c@280: cannam@483: o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2; cannam@483: o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3; cannam@483: o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4; cannam@483: o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5; cannam@483: o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6; cannam@483: o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7; cannam@483: o7 = Input * b[ 7 ] - Output * a[ 7 ] ; c@280: cannam@483: dst[ i ] = Output; c@280: } c@280: } c@280: c@247: void Decimator::process(const double *src, double *dst) c@225: { c@388: if (m_decFactor == 1) { cannam@499: for (int i = 0; i < m_outputLength; i++ ) { c@388: dst[i] = src[i]; c@388: } c@388: return; c@225: } c@388: c@388: doAntiAlias( src, decBuffer, m_inputLength ); c@388: cannam@501: int idx = 0; c@225: cannam@499: for (int i = 0; i < m_outputLength; i++ ) { cannam@483: dst[ idx++ ] = decBuffer[ m_decFactor * i ]; c@225: } c@225: } c@280: c@280: void Decimator::process(const float *src, float *dst) c@280: { c@388: if (m_decFactor == 1) { cannam@499: for (int i = 0; i < m_outputLength; i++ ) { c@388: dst[i] = src[i]; c@388: } c@388: return; c@280: } c@388: c@388: doAntiAlias( src, decBuffer, m_inputLength ); c@388: cannam@499: int idx = 0; c@280: cannam@499: for (int i = 0; i < m_outputLength; i++ ) { cannam@483: dst[ idx++ ] = decBuffer[ m_decFactor * i ]; c@280: } c@280: }