| c@225 | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */ | 
| c@225 | 2 | 
| c@225 | 3 /* | 
| c@225 | 4     QM DSP Library | 
| c@225 | 5 | 
| c@225 | 6     Centre for Digital Music, Queen Mary, University of London. | 
| c@309 | 7     This file 2005-2006 Christian Landone. | 
| c@309 | 8 | 
| c@309 | 9     This program is free software; you can redistribute it and/or | 
| c@309 | 10     modify it under the terms of the GNU General Public License as | 
| c@309 | 11     published by the Free Software Foundation; either version 2 of the | 
| c@309 | 12     License, or (at your option) any later version.  See the file | 
| c@309 | 13     COPYING included with this distribution for more information. | 
| c@225 | 14 */ | 
| c@225 | 15 | 
| c@225 | 16 #include "FiltFilt.h" | 
| c@225 | 17 | 
| c@225 | 18 ////////////////////////////////////////////////////////////////////// | 
| c@225 | 19 // Construction/Destruction | 
| c@225 | 20 ////////////////////////////////////////////////////////////////////// | 
| c@225 | 21 | 
| c@417 | 22 FiltFilt::FiltFilt(Filter::Parameters parameters) : | 
| c@417 | 23     m_filter(parameters) | 
| c@225 | 24 { | 
| c@417 | 25     m_ord = m_filter.getOrder(); | 
| c@225 | 26 } | 
| c@225 | 27 | 
| c@225 | 28 FiltFilt::~FiltFilt() | 
| c@225 | 29 { | 
| c@225 | 30 } | 
| c@225 | 31 | 
| cannam@503 | 32 void FiltFilt::process(double *src, double *dst, int length) | 
| cannam@483 | 33 { | 
| cannam@503 | 34     int i; | 
| c@225 | 35 | 
| c@283 | 36     if (length == 0) return; | 
| c@283 | 37 | 
| cannam@503 | 38     int nFilt = m_ord + 1; | 
| cannam@503 | 39     int nFact = 3 * (nFilt - 1); | 
| cannam@503 | 40     int nExt = length + 2 * nFact; | 
| c@225 | 41 | 
| c@417 | 42     double *filtScratchIn = new double[ nExt ]; | 
| c@417 | 43     double *filtScratchOut = new double[ nExt ]; | 
| cannam@483 | 44 | 
| cannam@503 | 45     for (i = 0; i < nExt; i++) { | 
| cannam@483 | 46         filtScratchIn[ i ] = 0.0; | 
| cannam@483 | 47         filtScratchOut[ i ] = 0.0; | 
| c@225 | 48     } | 
| c@225 | 49 | 
| c@225 | 50     // Edge transients reflection | 
| c@225 | 51     double sample0 = 2 * src[ 0 ]; | 
| c@225 | 52     double sampleN = 2 * src[ length - 1 ]; | 
| c@225 | 53 | 
| cannam@503 | 54     int index = 0; | 
| cannam@503 | 55     for (i = nFact; i > 0; i--) { | 
| cannam@483 | 56         filtScratchIn[ index++ ] = sample0 - src[ i ]; | 
| c@225 | 57     } | 
| c@225 | 58     index = 0; | 
| cannam@503 | 59     for (i = 0; i < nFact; i++) { | 
| cannam@503 | 60         filtScratchIn[ (nExt - nFact) + index++ ] = | 
| cannam@503 | 61             sampleN - src[ (length - 2) - i ]; | 
| c@225 | 62     } | 
| c@225 | 63 | 
| c@225 | 64     index = 0; | 
| cannam@503 | 65     for (i = 0; i < length; i++) { | 
| cannam@483 | 66         filtScratchIn[ i + nFact ] = src[ i ]; | 
| c@225 | 67     } | 
| cannam@483 | 68 | 
| c@225 | 69     //////////////////////////////// | 
| cannam@503 | 70     // Do 0Ph filtering | 
| cannam@503 | 71     m_filter.process(filtScratchIn, filtScratchOut, nExt); | 
| cannam@483 | 72 | 
| c@225 | 73     // reverse the series for FILTFILT | 
| cannam@503 | 74     for (i = 0; i < nExt; i++) { | 
| cannam@483 | 75         filtScratchIn[ i ] = filtScratchOut[ nExt - i - 1]; | 
| c@225 | 76     } | 
| c@225 | 77 | 
| c@225 | 78     // do FILTER again | 
| cannam@503 | 79     m_filter.process(filtScratchIn, filtScratchOut, nExt); | 
| cannam@483 | 80 | 
| c@225 | 81     // reverse the series back | 
| cannam@503 | 82     for (i = 0; i < nExt; i++) { | 
| cannam@483 | 83         filtScratchIn[ i ] = filtScratchOut[ nExt - i - 1 ]; | 
| c@225 | 84     } | 
| cannam@503 | 85     for (i = 0; i < nExt; i++) { | 
| cannam@483 | 86         filtScratchOut[ i ] = filtScratchIn[ i ]; | 
| c@225 | 87     } | 
| c@225 | 88 | 
| c@225 | 89     index = 0; | 
| cannam@503 | 90     for (i = 0; i < length; i++) { | 
| cannam@483 | 91         dst[ index++ ] = filtScratchOut[ i + nFact ]; | 
| cannam@483 | 92     } | 
| c@225 | 93 | 
| c@417 | 94     delete [] filtScratchIn; | 
| c@417 | 95     delete [] filtScratchOut; | 
| c@225 | 96 } | 
| c@225 | 97 | 
| c@225 | 98 void FiltFilt::reset() | 
| c@225 | 99 { | 
| c@225 | 100 | 
| c@225 | 101 } |