cannam@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ cannam@0: cannam@0: /* cannam@0: QM DSP Library cannam@0: cannam@0: Centre for Digital Music, Queen Mary, University of London. cannam@0: This file copyright 2005-2006 Christian Landone. cannam@0: All rights reserved. cannam@0: */ cannam@0: cannam@0: #include "Decimator.h" cannam@0: cannam@0: ////////////////////////////////////////////////////////////////////// cannam@0: // Construction/Destruction cannam@0: ////////////////////////////////////////////////////////////////////// cannam@0: cannam@0: Decimator::Decimator( unsigned int inLength, unsigned int decFactor ) cannam@0: { cannam@0: cannam@0: m_inputLength = 0; cannam@0: m_outputLength = 0; cannam@0: m_decFactor = 1; cannam@0: cannam@0: initialise( inLength, decFactor ); cannam@0: } cannam@0: cannam@0: Decimator::~Decimator() cannam@0: { cannam@0: deInitialise(); cannam@0: } cannam@0: cannam@0: void Decimator::initialise( unsigned int inLength, unsigned int decFactor) cannam@0: { cannam@0: m_inputLength = inLength; cannam@0: m_decFactor = decFactor; cannam@0: m_outputLength = m_inputLength / m_decFactor; cannam@0: cannam@0: decBuffer = new double[ m_inputLength ]; cannam@0: cannam@0: if( m_decFactor == 4 ) cannam@0: { cannam@0: ////////////////////////////////////////////////// cannam@0: b[ 0 ] = 0.10133306904918619; cannam@0: b[ 1 ] = -0.2447523353702363; cannam@0: b[ 2 ] = 0.33622528590120965; cannam@0: b[ 3 ] = -0.13936581560633518; cannam@0: b[ 4 ] = -0.13936581560633382; cannam@0: b[ 5 ] = 0.3362252859012087; cannam@0: b[ 6 ] = -0.2447523353702358; cannam@0: b[ 7 ] = 0.10133306904918594; cannam@0: cannam@0: a[ 0 ] = 1; cannam@0: a[ 1 ] = -3.9035590278139427; cannam@0: a[ 2 ] = 7.5299379980621133; cannam@0: a[ 3 ] = -8.6890803793177511; cannam@0: a[ 4 ] = 6.4578667096099176; cannam@0: a[ 5 ] = -3.0242979431223631; cannam@0: a[ 6 ] = 0.83043385136748382; cannam@0: a[ 7 ] = -0.094420800837809335; cannam@0: ////////////////////////////////////////////////// cannam@0: } cannam@0: else if( m_decFactor == 2 ) cannam@0: { cannam@0: ////////////////////////////////////////////////// cannam@0: b[ 0 ] = 0.20898944260075727; cannam@0: b[ 1 ] = 0.40011234879814367; cannam@0: b[ 2 ] = 0.819741973072733; cannam@0: b[ 3 ] = 1.0087419911682323; cannam@0: b[ 4 ] = 1.0087419911682325; cannam@0: b[ 5 ] = 0.81974197307273156; cannam@0: b[ 6 ] = 0.40011234879814295; cannam@0: b[ 7 ] = 0.20898944260075661; cannam@0: cannam@0: a[ 0 ] = 1; cannam@0: a[ 1 ] = 0.0077331184208358217; cannam@0: a[ 2 ] = 1.9853971155964376; cannam@0: a[ 3 ] = 0.19296739275341004; cannam@0: a[ 4 ] = 1.2330748872852182; cannam@0: a[ 5 ] = 0.18705341389316466; cannam@0: a[ 6 ] = 0.23659265908013868; cannam@0: a[ 7 ] = 0.032352924250533946; cannam@0: } cannam@0: else cannam@0: { cannam@0: ////////////////////////////////////////////////// cannam@0: b[ 0 ] = 1; cannam@0: b[ 1 ] = 0; cannam@0: b[ 2 ] = 0; cannam@0: b[ 3 ] = 0; cannam@0: b[ 4 ] = 0; cannam@0: b[ 5 ] = 0; cannam@0: b[ 6 ] = 0; cannam@0: b[ 7 ] = 0; cannam@0: cannam@0: a[ 0 ] = 1; cannam@0: a[ 1 ] = 0; cannam@0: a[ 2 ] = 0; cannam@0: a[ 3 ] = 0; cannam@0: a[ 4 ] = 0; cannam@0: a[ 5 ] = 0; cannam@0: a[ 6 ] = 0; cannam@0: a[ 7 ] = 0; cannam@0: } cannam@0: cannam@0: resetFilter(); cannam@0: } cannam@0: cannam@0: void Decimator::deInitialise() cannam@0: { cannam@0: delete [] decBuffer; cannam@0: } cannam@0: cannam@0: void Decimator::resetFilter() cannam@0: { cannam@0: Input = Output = 0; cannam@0: cannam@0: o1=o2=o3=o4=o5=o6=o7=0; cannam@0: } cannam@0: cannam@0: void Decimator::doAntiAlias(double *src, double *dst, unsigned int length) cannam@0: { cannam@0: cannam@0: for( unsigned int i = 0; i < length; i++ ) cannam@0: { cannam@0: Input = (double)src[ i ]; cannam@0: cannam@0: Output = Input * b[ 0 ] + o1; cannam@0: cannam@0: o1 = Input * b[ 1 ] - Output * a[ 1 ] + o2; cannam@0: o2 = Input * b[ 2 ] - Output * a[ 2 ] + o3; cannam@0: o3 = Input * b[ 3 ] - Output * a[ 3 ] + o4; cannam@0: o4 = Input * b[ 4 ] - Output * a[ 4 ] + o5; cannam@0: o5 = Input * b[ 5 ] - Output * a[ 5 ] + o6; cannam@0: o6 = Input * b[ 6 ] - Output * a[ 6 ] + o7; cannam@0: o7 = Input * b[ 7 ] - Output * a[ 7 ] ; cannam@0: cannam@0: dst[ i ] = Output; cannam@0: } cannam@0: cannam@0: } cannam@0: cannam@0: void Decimator::process(double *src, double *dst) cannam@0: { cannam@0: if( m_decFactor != 1 ) cannam@0: { cannam@0: doAntiAlias( src, decBuffer, m_inputLength ); cannam@0: } cannam@0: unsigned idx = 0; cannam@0: cannam@0: for( unsigned int i = 0; i < m_outputLength; i++ ) cannam@0: { cannam@0: dst[ idx++ ] = decBuffer[ m_decFactor * i ]; cannam@0: } cannam@0: }