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 "FiltFilt.h" c@225: c@417: FiltFilt::FiltFilt(Filter::Parameters parameters) : c@417: m_filter(parameters) c@225: { c@417: m_ord = m_filter.getOrder(); c@225: } c@225: c@225: FiltFilt::~FiltFilt() c@225: { c@225: } c@225: cannam@506: void FiltFilt::process(const double *const QM_R__ src, cannam@506: double *const QM_R__ dst, cannam@506: const int length) cannam@483: { cannam@503: int i; c@225: c@283: if (length == 0) return; c@283: cannam@503: int nFilt = m_ord + 1; cannam@503: int nFact = 3 * (nFilt - 1); cannam@503: int nExt = length + 2 * nFact; c@225: c@417: double *filtScratchIn = new double[ nExt ]; c@417: double *filtScratchOut = new double[ nExt ]; cannam@483: cannam@503: for (i = 0; i < nExt; i++) { cannam@483: filtScratchIn[ i ] = 0.0; cannam@483: filtScratchOut[ i ] = 0.0; c@225: } c@225: c@225: // Edge transients reflection c@225: double sample0 = 2 * src[ 0 ]; c@225: double sampleN = 2 * src[ length - 1 ]; c@225: cannam@503: int index = 0; cannam@503: for (i = nFact; i > 0; i--) { cannam@506: if (i < length) { cannam@506: filtScratchIn[index] = sample0 - src[ i ]; cannam@506: } cannam@506: ++index; c@225: } c@225: index = 0; cannam@503: for (i = 0; i < nFact; i++) { cannam@507: if (i + 1 < length) { cannam@506: filtScratchIn[(nExt - nFact) + index] = cannam@506: sampleN - src[ (length - 2) - i ]; cannam@506: } cannam@506: ++index; c@225: } c@225: cannam@503: for (i = 0; i < length; i++) { cannam@483: filtScratchIn[ i + nFact ] = src[ i ]; c@225: } cannam@506: c@225: //////////////////////////////// cannam@503: // Do 0Ph filtering cannam@503: m_filter.process(filtScratchIn, filtScratchOut, nExt); cannam@483: c@225: // reverse the series for FILTFILT cannam@503: for (i = 0; i < nExt; i++) { cannam@483: filtScratchIn[ i ] = filtScratchOut[ nExt - i - 1]; c@225: } c@225: cannam@506: // clear filter state cannam@506: m_filter.reset(); cannam@506: c@225: // do FILTER again cannam@503: m_filter.process(filtScratchIn, filtScratchOut, nExt); cannam@506: cannam@508: // reverse the series to output cannam@508: for (i = 0; i < length; i++) { cannam@508: dst[ i ] = filtScratchOut[ nExt - nFact - i - 1 ]; c@225: } c@225: c@417: delete [] filtScratchIn; c@417: delete [] filtScratchOut; c@225: } c@225: