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 "FiltFilt.h" cannam@0: cannam@0: ////////////////////////////////////////////////////////////////////// cannam@0: // Construction/Destruction cannam@0: ////////////////////////////////////////////////////////////////////// cannam@0: cannam@0: FiltFilt::FiltFilt( FiltFiltConfig Config ) cannam@0: { cannam@0: m_filtScratchIn = NULL; cannam@0: m_filtScratchOut = NULL; cannam@0: m_ord = 0; cannam@0: cannam@0: initialise( Config ); cannam@0: } cannam@0: cannam@0: FiltFilt::~FiltFilt() cannam@0: { cannam@0: deInitialise(); cannam@0: } cannam@0: cannam@0: void FiltFilt::initialise( FiltFiltConfig Config ) cannam@0: { cannam@0: m_ord = Config.ord; cannam@0: m_filterConfig.ord = Config.ord; cannam@0: m_filterConfig.ACoeffs = Config.ACoeffs; cannam@0: m_filterConfig.BCoeffs = Config.BCoeffs; cannam@0: cannam@0: m_filter = new Filter( m_filterConfig ); cannam@0: } cannam@0: cannam@0: void FiltFilt::deInitialise() cannam@0: { cannam@0: delete m_filter; cannam@0: } cannam@0: cannam@0: cannam@0: void FiltFilt::process(double *src, double *dst, unsigned int length) cannam@0: { cannam@0: unsigned int i; cannam@0: cannam@58: if (length == 0) return; cannam@58: cannam@0: unsigned int nFilt = m_ord + 1; cannam@0: unsigned int nFact = 3 * ( nFilt - 1); cannam@0: unsigned int nExt = length + 2 * nFact; cannam@0: cannam@0: m_filtScratchIn = new double[ nExt ]; cannam@0: m_filtScratchOut = new double[ nExt ]; cannam@0: cannam@0: cannam@0: for( i = 0; i< nExt; i++ ) cannam@0: { cannam@0: m_filtScratchIn[ i ] = 0.0; cannam@0: m_filtScratchOut[ i ] = 0.0; cannam@0: } cannam@0: cannam@0: // Edge transients reflection cannam@0: double sample0 = 2 * src[ 0 ]; cannam@0: double sampleN = 2 * src[ length - 1 ]; cannam@0: cannam@0: unsigned int index = 0; cannam@0: for( i = nFact; i > 0; i-- ) cannam@0: { cannam@0: m_filtScratchIn[ index++ ] = sample0 - src[ i ]; cannam@0: } cannam@0: index = 0; cannam@0: for( i = 0; i < nFact; i++ ) cannam@0: { cannam@0: m_filtScratchIn[ (nExt - nFact) + index++ ] = sampleN - src[ (length - 2) - i ]; cannam@0: } cannam@0: cannam@0: index = 0; cannam@0: for( i = 0; i < length; i++ ) cannam@0: { cannam@0: m_filtScratchIn[ i + nFact ] = src[ i ]; cannam@0: } cannam@0: cannam@0: //////////////////////////////// cannam@0: // Do 0Ph filtering cannam@0: m_filter->process( m_filtScratchIn, m_filtScratchOut, nExt); cannam@0: cannam@0: // reverse the series for FILTFILT cannam@0: for ( i = 0; i < nExt; i++) cannam@0: { cannam@0: m_filtScratchIn[ i ] = m_filtScratchOut[ nExt - i - 1]; cannam@0: } cannam@0: cannam@0: // do FILTER again cannam@0: m_filter->process( m_filtScratchIn, m_filtScratchOut, nExt); cannam@0: cannam@0: // reverse the series back cannam@0: for ( i = 0; i < nExt; i++) cannam@0: { cannam@0: m_filtScratchIn[ i ] = m_filtScratchOut[ nExt - i - 1 ]; cannam@0: } cannam@0: for ( i = 0;i < nExt; i++) cannam@0: { cannam@0: m_filtScratchOut[ i ] = m_filtScratchIn[ i ]; cannam@0: } cannam@0: cannam@0: index = 0; cannam@0: for( i = 0; i < length; i++ ) cannam@0: { cannam@0: dst[ index++ ] = m_filtScratchOut[ i + nFact ]; cannam@0: } cannam@0: cannam@0: delete [] m_filtScratchIn; cannam@0: delete [] m_filtScratchOut; cannam@0: cannam@0: } cannam@0: cannam@0: void FiltFilt::reset() cannam@0: { cannam@0: cannam@0: }