annotate dsp/signalconditioning/FiltFilt.cpp @ 506:285f18c0992a

Tests and fixes for FiltFilt: Fix overrun; reset filter between forwards and backwards processes
author Chris Cannam <cannam@all-day-breakfast.com>
date Wed, 05 Jun 2019 15:50:38 +0100
parents b1f72e469ec8
children d7b9691817a3
rev   line source
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@417 18 FiltFilt::FiltFilt(Filter::Parameters parameters) :
c@417 19 m_filter(parameters)
c@225 20 {
c@417 21 m_ord = m_filter.getOrder();
c@225 22 }
c@225 23
c@225 24 FiltFilt::~FiltFilt()
c@225 25 {
c@225 26 }
c@225 27
cannam@506 28 void FiltFilt::process(const double *const QM_R__ src,
cannam@506 29 double *const QM_R__ dst,
cannam@506 30 const int length)
cannam@483 31 {
cannam@503 32 int i;
c@225 33
c@283 34 if (length == 0) return;
c@283 35
cannam@503 36 int nFilt = m_ord + 1;
cannam@503 37 int nFact = 3 * (nFilt - 1);
cannam@503 38 int nExt = length + 2 * nFact;
c@225 39
c@417 40 double *filtScratchIn = new double[ nExt ];
c@417 41 double *filtScratchOut = new double[ nExt ];
cannam@483 42
cannam@503 43 for (i = 0; i < nExt; i++) {
cannam@483 44 filtScratchIn[ i ] = 0.0;
cannam@483 45 filtScratchOut[ i ] = 0.0;
c@225 46 }
c@225 47
c@225 48 // Edge transients reflection
c@225 49 double sample0 = 2 * src[ 0 ];
c@225 50 double sampleN = 2 * src[ length - 1 ];
c@225 51
cannam@503 52 int index = 0;
cannam@503 53 for (i = nFact; i > 0; i--) {
cannam@506 54 if (i < length) {
cannam@506 55 filtScratchIn[index] = sample0 - src[ i ];
cannam@506 56 }
cannam@506 57 ++index;
c@225 58 }
c@225 59 index = 0;
cannam@503 60 for (i = 0; i < nFact; i++) {
cannam@506 61 if (i < length) {
cannam@506 62 filtScratchIn[(nExt - nFact) + index] =
cannam@506 63 sampleN - src[ (length - 2) - i ];
cannam@506 64 }
cannam@506 65 ++index;
c@225 66 }
c@225 67
c@225 68 index = 0;
cannam@503 69 for (i = 0; i < length; i++) {
cannam@483 70 filtScratchIn[ i + nFact ] = src[ i ];
c@225 71 }
cannam@506 72
c@225 73 ////////////////////////////////
cannam@503 74 // Do 0Ph filtering
cannam@503 75 m_filter.process(filtScratchIn, filtScratchOut, nExt);
cannam@483 76
c@225 77 // reverse the series for FILTFILT
cannam@503 78 for (i = 0; i < nExt; i++) {
cannam@483 79 filtScratchIn[ i ] = filtScratchOut[ nExt - i - 1];
c@225 80 }
c@225 81
cannam@506 82 // clear filter state
cannam@506 83 m_filter.reset();
cannam@506 84
c@225 85 // do FILTER again
cannam@503 86 m_filter.process(filtScratchIn, filtScratchOut, nExt);
cannam@506 87
c@225 88 // reverse the series back
cannam@503 89 for (i = 0; i < nExt; i++) {
cannam@483 90 filtScratchIn[ i ] = filtScratchOut[ nExt - i - 1 ];
c@225 91 }
cannam@503 92 for (i = 0; i < nExt; i++) {
cannam@483 93 filtScratchOut[ i ] = filtScratchIn[ i ];
c@225 94 }
c@225 95
c@225 96 index = 0;
cannam@503 97 for (i = 0; i < length; i++) {
cannam@483 98 dst[ index++ ] = filtScratchOut[ i + nFact ];
cannam@483 99 }
c@225 100
c@417 101 delete [] filtScratchIn;
c@417 102 delete [] filtScratchOut;
c@225 103 }
c@225 104