annotate dsp/signalconditioning/DFProcess.cpp @ 321:f1e6be2de9a5

A threshold (delta) is added in the peak picking parameters structure (PPickParams). It is used as an offset when computing the smoothed detection function. A constructor for the structure PPickParams is also added to set the parameters to 0 when a structure instance is created. Hence programmes using the peak picking parameter structure and which do not set the delta parameter (e.g. QM Vamp note onset detector) won't be affected by the modifications. Functions modified: - dsp/onsets/PeakPicking.cpp - dsp/onsets/PeakPicking.h - dsp/signalconditioning/DFProcess.cpp - dsp/signalconditioning/DFProcess.h
author mathieub <mathieu.barthet@eecs.qmul.ac.uk>
date Mon, 20 Jun 2011 19:01:48 +0100
parents d5014ab8b0e5
children 2ae4ceb76ac3
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
mathieu@321 9 Modifications:
mathieu@321 10
mathieu@321 11 - delta threshold
mathieu@321 12 Description: add delta threshold used as offset in the smoothed
mathieu@321 13 detection function
mathieu@321 14 Author: Mathieu Barthet
mathieu@321 15 Date: June 2010
mathieu@321 16
c@309 17 This program is free software; you can redistribute it and/or
c@309 18 modify it under the terms of the GNU General Public License as
c@309 19 published by the Free Software Foundation; either version 2 of the
c@309 20 License, or (at your option) any later version. See the file
c@309 21 COPYING included with this distribution for more information.
c@225 22 */
c@225 23
c@225 24 #include "DFProcess.h"
c@241 25 #include "maths/MathUtilities.h"
c@225 26
c@272 27 #include <cstring>
c@272 28
c@225 29 //////////////////////////////////////////////////////////////////////
c@225 30 // Construction/Destruction
c@225 31 //////////////////////////////////////////////////////////////////////
c@225 32
c@225 33 DFProcess::DFProcess( DFProcConfig Config )
c@225 34 {
c@225 35 filtSrc = NULL;
c@225 36 filtDst = NULL;
c@225 37 m_filtScratchIn = NULL;
c@225 38 m_filtScratchOut = NULL;
c@225 39
c@225 40 m_FFOrd = 0;
c@225 41
c@225 42 initialise( Config );
c@225 43 }
c@225 44
c@225 45 DFProcess::~DFProcess()
c@225 46 {
c@225 47 deInitialise();
c@225 48 }
c@225 49
c@225 50 void DFProcess::initialise( DFProcConfig Config )
c@225 51 {
c@225 52 m_length = Config.length;
c@225 53 m_winPre = Config.winPre;
c@225 54 m_winPost = Config.winPost;
c@225 55 m_alphaNormParam = Config.AlphaNormParam;
c@225 56
c@225 57 m_isMedianPositive = Config.isMedianPositive;
c@225 58
c@225 59 filtSrc = new double[ m_length ];
c@225 60 filtDst = new double[ m_length ];
c@225 61
c@225 62
c@225 63 //Low Pass Smoothing Filter Config
c@225 64 m_FilterConfigParams.ord = Config.LPOrd;
c@225 65 m_FilterConfigParams.ACoeffs = Config.LPACoeffs;
c@225 66 m_FilterConfigParams.BCoeffs = Config.LPBCoeffs;
c@225 67
mathieu@321 68 m_FiltFilt = new FiltFilt( m_FilterConfigParams );
mathieu@321 69
mathieu@321 70 //add delta threshold
mathieu@321 71 m_Delta = Config.Delta;
c@225 72 }
c@225 73
c@225 74 void DFProcess::deInitialise()
c@225 75 {
c@225 76 delete [] filtSrc;
c@225 77
c@225 78 delete [] filtDst;
c@225 79
c@225 80 delete [] m_filtScratchIn;
c@225 81
c@225 82 delete [] m_filtScratchOut;
c@225 83
c@225 84 delete m_FiltFilt;
c@225 85 }
c@225 86
c@225 87 void DFProcess::process(double *src, double* dst)
c@225 88 {
c@283 89 if (m_length == 0) return;
c@283 90
c@225 91 removeDCNormalize( src, filtSrc );
c@225 92
c@225 93 m_FiltFilt->process( filtSrc, filtDst, m_length );
c@225 94
c@225 95 medianFilter( filtDst, dst );
c@225 96 }
c@225 97
c@225 98
c@225 99 void DFProcess::medianFilter(double *src, double *dst)
c@225 100 {
c@299 101 int i,k,j,l;
c@299 102 int index = 0;
c@225 103
c@225 104 double val = 0;
c@225 105
c@225 106 double* y = new double[ m_winPost + m_winPre + 1];
c@225 107 memset( y, 0, sizeof( double ) * ( m_winPost + m_winPre + 1) );
c@225 108
c@225 109 double* scratch = new double[ m_length ];
c@225 110
c@305 111 for( i = 0; i < m_winPre; i++)
c@225 112 {
c@299 113 if (index >= m_length) break;
c@299 114
c@225 115 k = i + m_winPost + 1;
c@225 116
c@225 117 for( j = 0; j < k; j++)
c@225 118 {
c@225 119 y[ j ] = src[ j ];
c@225 120 }
c@225 121 scratch[ index ] = MathUtilities::median( y, k );
c@225 122 index++;
c@225 123 }
c@225 124
c@299 125 for( i = 0; i + m_winPost + m_winPre < m_length; i ++)
c@225 126 {
c@299 127 if (index >= m_length) break;
c@299 128
c@225 129
c@225 130 l = 0;
c@225 131 for( j = i; j < ( i + m_winPost + m_winPre + 1); j++)
c@225 132 {
c@225 133 y[ l ] = src[ j ];
c@225 134 l++;
c@225 135 }
c@225 136
c@225 137 scratch[ index++ ] = MathUtilities::median( y, (m_winPost + m_winPre + 1 ));
c@225 138 }
c@225 139
c@299 140 for( i = std::max( m_length - m_winPost, 1); i < m_length; i++)
c@225 141 {
c@299 142 if (index >= m_length) break;
c@299 143
c@299 144 k = std::max( i - m_winPre, 1);
c@225 145
c@225 146 l = 0;
c@225 147 for( j = k; j < m_length; j++)
c@225 148 {
c@225 149 y[ l ] = src[ j ];
c@225 150
c@225 151 l++;
c@225 152 }
c@225 153
c@225 154 scratch[ index++ ] = MathUtilities::median( y, l);
c@225 155 }
c@225 156
c@225 157
c@225 158 for( i = 0; i < m_length; i++ )
c@225 159 {
mathieu@321 160 //add a delta threshold used as an offset when computing the smoothed detection function
mathieu@321 161 //(helps to discard noise when detecting peaks)
mathieu@321 162 val = src[ i ] - scratch[ i ] - m_Delta;
c@225 163
c@225 164 if( m_isMedianPositive )
c@225 165 {
c@225 166 if( val > 0 )
c@225 167 {
c@225 168 dst[ i ] = val;
c@225 169 }
c@225 170 else
c@225 171 {
c@225 172 dst[ i ] = 0;
c@225 173 }
c@225 174 }
c@225 175 else
c@225 176 {
c@225 177 dst[ i ] = val;
c@225 178 }
c@225 179 }
c@225 180
c@225 181 delete [] y;
c@225 182 delete [] scratch;
c@225 183 }
c@225 184
c@225 185
c@225 186 void DFProcess::removeDCNormalize( double *src, double*dst )
c@225 187 {
c@225 188 double DFmax = 0;
c@225 189 double DFMin = 0;
c@225 190 double DFAlphaNorm = 0;
c@225 191
c@225 192 MathUtilities::getFrameMinMax( src, m_length, &DFMin, &DFmax );
c@225 193
c@225 194 MathUtilities::getAlphaNorm( src, m_length, m_alphaNormParam, &DFAlphaNorm );
c@225 195
c@225 196 for( unsigned int i = 0; i< m_length; i++)
c@225 197 {
c@225 198 dst[ i ] = ( src[ i ] - DFMin ) / DFAlphaNorm;
c@225 199 }
c@225 200 }