annotate dsp/signalconditioning/DFProcess.cpp @ 193:ca658c7215a9

Faster filter implementation with explicit FIR support
author Chris Cannam
date Wed, 07 Oct 2015 10:36:09 +0100
parents e4a57215ddee
children ccd2019190bf
rev   line source
cannam@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@0 2
cannam@0 3 /*
cannam@0 4 QM DSP Library
cannam@0 5
cannam@0 6 Centre for Digital Music, Queen Mary, University of London.
Chris@84 7 This file 2005-2006 Christian Landone.
Chris@84 8
mathieu@96 9 Modifications:
mathieu@96 10
mathieu@96 11 - delta threshold
mathieu@96 12 Description: add delta threshold used as offset in the smoothed
mathieu@96 13 detection function
mathieu@96 14 Author: Mathieu Barthet
mathieu@96 15 Date: June 2010
mathieu@96 16
Chris@84 17 This program is free software; you can redistribute it and/or
Chris@84 18 modify it under the terms of the GNU General Public License as
Chris@84 19 published by the Free Software Foundation; either version 2 of the
Chris@84 20 License, or (at your option) any later version. See the file
Chris@84 21 COPYING included with this distribution for more information.
cannam@0 22 */
cannam@0 23
cannam@0 24 #include "DFProcess.h"
cannam@16 25 #include "maths/MathUtilities.h"
cannam@0 26
cannam@47 27 #include <cstring>
cannam@47 28
cannam@0 29 //////////////////////////////////////////////////////////////////////
cannam@0 30 // Construction/Destruction
cannam@0 31 //////////////////////////////////////////////////////////////////////
cannam@0 32
cannam@0 33 DFProcess::DFProcess( DFProcConfig Config )
cannam@0 34 {
cannam@0 35 filtSrc = NULL;
cannam@0 36 filtDst = NULL;
cannam@0 37 m_filtScratchIn = NULL;
cannam@0 38 m_filtScratchOut = NULL;
cannam@0 39
cannam@0 40 m_FFOrd = 0;
cannam@0 41
cannam@0 42 initialise( Config );
cannam@0 43 }
cannam@0 44
cannam@0 45 DFProcess::~DFProcess()
cannam@0 46 {
cannam@0 47 deInitialise();
cannam@0 48 }
cannam@0 49
cannam@0 50 void DFProcess::initialise( DFProcConfig Config )
cannam@0 51 {
cannam@0 52 m_length = Config.length;
cannam@0 53 m_winPre = Config.winPre;
cannam@0 54 m_winPost = Config.winPost;
cannam@0 55 m_alphaNormParam = Config.AlphaNormParam;
cannam@0 56
cannam@0 57 m_isMedianPositive = Config.isMedianPositive;
cannam@0 58
cannam@0 59 filtSrc = new double[ m_length ];
cannam@0 60 filtDst = new double[ m_length ];
cannam@0 61
Chris@193 62 Filter::Parameters params;
Chris@193 63 params.a = std::vector<double>(Config.LPACoeffs, Config.LPACoeffs + Config.LPOrd + 1);
Chris@193 64 params.b = std::vector<double>(Config.LPBCoeffs, Config.LPBCoeffs + Config.LPOrd + 1);
Chris@193 65
Chris@193 66 m_FiltFilt = new FiltFilt(params);
mathieu@96 67
mathieu@96 68 //add delta threshold
Chris@185 69 m_delta = Config.delta;
cannam@0 70 }
cannam@0 71
cannam@0 72 void DFProcess::deInitialise()
cannam@0 73 {
cannam@0 74 delete [] filtSrc;
cannam@0 75
cannam@0 76 delete [] filtDst;
cannam@0 77
cannam@0 78 delete [] m_filtScratchIn;
cannam@0 79
cannam@0 80 delete [] m_filtScratchOut;
cannam@0 81
cannam@0 82 delete m_FiltFilt;
cannam@0 83 }
cannam@0 84
cannam@0 85 void DFProcess::process(double *src, double* dst)
cannam@0 86 {
cannam@58 87 if (m_length == 0) return;
cannam@58 88
cannam@0 89 removeDCNormalize( src, filtSrc );
cannam@0 90
cannam@0 91 m_FiltFilt->process( filtSrc, filtDst, m_length );
cannam@0 92
cannam@0 93 medianFilter( filtDst, dst );
cannam@0 94 }
cannam@0 95
cannam@0 96
cannam@0 97 void DFProcess::medianFilter(double *src, double *dst)
cannam@0 98 {
cannam@74 99 int i,k,j,l;
cannam@74 100 int index = 0;
cannam@0 101
cannam@0 102 double val = 0;
cannam@0 103
cannam@0 104 double* y = new double[ m_winPost + m_winPre + 1];
cannam@0 105 memset( y, 0, sizeof( double ) * ( m_winPost + m_winPre + 1) );
cannam@0 106
cannam@0 107 double* scratch = new double[ m_length ];
cannam@0 108
cannam@80 109 for( i = 0; i < m_winPre; i++)
cannam@0 110 {
cannam@74 111 if (index >= m_length) break;
cannam@74 112
cannam@0 113 k = i + m_winPost + 1;
cannam@0 114
cannam@0 115 for( j = 0; j < k; j++)
cannam@0 116 {
cannam@0 117 y[ j ] = src[ j ];
cannam@0 118 }
cannam@0 119 scratch[ index ] = MathUtilities::median( y, k );
cannam@0 120 index++;
cannam@0 121 }
cannam@0 122
cannam@74 123 for( i = 0; i + m_winPost + m_winPre < m_length; i ++)
cannam@0 124 {
cannam@74 125 if (index >= m_length) break;
cannam@74 126
cannam@0 127
cannam@0 128 l = 0;
cannam@0 129 for( j = i; j < ( i + m_winPost + m_winPre + 1); j++)
cannam@0 130 {
cannam@0 131 y[ l ] = src[ j ];
cannam@0 132 l++;
cannam@0 133 }
cannam@0 134
cannam@0 135 scratch[ index++ ] = MathUtilities::median( y, (m_winPost + m_winPre + 1 ));
cannam@0 136 }
cannam@0 137
cannam@74 138 for( i = std::max( m_length - m_winPost, 1); i < m_length; i++)
cannam@0 139 {
cannam@74 140 if (index >= m_length) break;
cannam@74 141
cannam@74 142 k = std::max( i - m_winPre, 1);
cannam@0 143
cannam@0 144 l = 0;
cannam@0 145 for( j = k; j < m_length; j++)
cannam@0 146 {
cannam@0 147 y[ l ] = src[ j ];
cannam@0 148
cannam@0 149 l++;
cannam@0 150 }
cannam@0 151
cannam@0 152 scratch[ index++ ] = MathUtilities::median( y, l);
cannam@0 153 }
cannam@0 154
cannam@0 155
cannam@0 156 for( i = 0; i < m_length; i++ )
cannam@0 157 {
mathieu@96 158 //add a delta threshold used as an offset when computing the smoothed detection function
mathieu@96 159 //(helps to discard noise when detecting peaks)
Chris@185 160 val = src[ i ] - scratch[ i ] - m_delta;
cannam@0 161
cannam@0 162 if( m_isMedianPositive )
cannam@0 163 {
cannam@0 164 if( val > 0 )
cannam@0 165 {
cannam@0 166 dst[ i ] = val;
cannam@0 167 }
cannam@0 168 else
cannam@0 169 {
cannam@0 170 dst[ i ] = 0;
cannam@0 171 }
cannam@0 172 }
cannam@0 173 else
cannam@0 174 {
cannam@0 175 dst[ i ] = val;
cannam@0 176 }
cannam@0 177 }
cannam@0 178
cannam@0 179 delete [] y;
cannam@0 180 delete [] scratch;
cannam@0 181 }
cannam@0 182
cannam@0 183
cannam@0 184 void DFProcess::removeDCNormalize( double *src, double*dst )
cannam@0 185 {
cannam@0 186 double DFmax = 0;
cannam@0 187 double DFMin = 0;
cannam@0 188 double DFAlphaNorm = 0;
cannam@0 189
cannam@0 190 MathUtilities::getFrameMinMax( src, m_length, &DFMin, &DFmax );
cannam@0 191
cannam@0 192 MathUtilities::getAlphaNorm( src, m_length, m_alphaNormParam, &DFAlphaNorm );
cannam@0 193
Chris@189 194 for (int i = 0; i < m_length; i++)
cannam@0 195 {
cannam@0 196 dst[ i ] = ( src[ i ] - DFMin ) / DFAlphaNorm;
cannam@0 197 }
cannam@0 198 }