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 "FiltFilt.h" 00017 00019 // Construction/Destruction 00021 00022 FiltFilt::FiltFilt( FilterConfig Config ) 00023 { 00024 m_filtScratchIn = NULL; 00025 m_filtScratchOut = NULL; 00026 m_ord = 0; 00027 00028 initialise( Config ); 00029 } 00030 00031 FiltFilt::~FiltFilt() 00032 { 00033 deInitialise(); 00034 } 00035 00036 void FiltFilt::initialise( FilterConfig Config ) 00037 { 00038 m_ord = Config.ord; 00039 m_filterConfig.ord = Config.ord; 00040 m_filterConfig.ACoeffs = Config.ACoeffs; 00041 m_filterConfig.BCoeffs = Config.BCoeffs; 00042 00043 m_filter = new Filter( m_filterConfig ); 00044 } 00045 00046 void FiltFilt::deInitialise() 00047 { 00048 delete m_filter; 00049 } 00050 00051 00052 void FiltFilt::process(double *src, double *dst, unsigned int length) 00053 { 00054 unsigned int i; 00055 00056 if (length == 0) return; 00057 00058 unsigned int nFilt = m_ord + 1; 00059 unsigned int nFact = 3 * ( nFilt - 1); 00060 unsigned int nExt = length + 2 * nFact; 00061 00062 m_filtScratchIn = new double[ nExt ]; 00063 m_filtScratchOut = new double[ nExt ]; 00064 00065 00066 for( i = 0; i< nExt; i++ ) 00067 { 00068 m_filtScratchIn[ i ] = 0.0; 00069 m_filtScratchOut[ i ] = 0.0; 00070 } 00071 00072 // Edge transients reflection 00073 double sample0 = 2 * src[ 0 ]; 00074 double sampleN = 2 * src[ length - 1 ]; 00075 00076 unsigned int index = 0; 00077 for( i = nFact; i > 0; i-- ) 00078 { 00079 m_filtScratchIn[ index++ ] = sample0 - src[ i ]; 00080 } 00081 index = 0; 00082 for( i = 0; i < nFact; i++ ) 00083 { 00084 m_filtScratchIn[ (nExt - nFact) + index++ ] = sampleN - src[ (length - 2) - i ]; 00085 } 00086 00087 index = 0; 00088 for( i = 0; i < length; i++ ) 00089 { 00090 m_filtScratchIn[ i + nFact ] = src[ i ]; 00091 } 00092 00094 // Do 0Ph filtering 00095 m_filter->process( m_filtScratchIn, m_filtScratchOut, nExt); 00096 00097 // reverse the series for FILTFILT 00098 for ( i = 0; i < nExt; i++) 00099 { 00100 m_filtScratchIn[ i ] = m_filtScratchOut[ nExt - i - 1]; 00101 } 00102 00103 // do FILTER again 00104 m_filter->process( m_filtScratchIn, m_filtScratchOut, nExt); 00105 00106 // reverse the series back 00107 for ( i = 0; i < nExt; i++) 00108 { 00109 m_filtScratchIn[ i ] = m_filtScratchOut[ nExt - i - 1 ]; 00110 } 00111 for ( i = 0;i < nExt; i++) 00112 { 00113 m_filtScratchOut[ i ] = m_filtScratchIn[ i ]; 00114 } 00115 00116 index = 0; 00117 for( i = 0; i < length; i++ ) 00118 { 00119 dst[ index++ ] = m_filtScratchOut[ i + nFact ]; 00120 } 00121 00122 delete [] m_filtScratchIn; 00123 delete [] m_filtScratchOut; 00124 00125 } 00126 00127 void FiltFilt::reset() 00128 { 00129 00130 }