annotate dsp/onsets/PeakPicking.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 37449f085a4c
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
mathieu@321 21 COPYING included with this distribution for more information.
c@225 22 */
c@225 23
c@225 24 #include "PeakPicking.h"
c@241 25 #include "maths/Polyfit.h"
c@225 26
c@237 27 #include <iostream>
c@272 28 #include <cstring>
c@272 29
c@225 30
c@225 31 //////////////////////////////////////////////////////////////////////
c@225 32 // Construction/Destruction
c@225 33 //////////////////////////////////////////////////////////////////////
c@225 34
c@225 35 PeakPicking::PeakPicking( PPickParams Config )
c@225 36 {
c@225 37 m_workBuffer = NULL;
c@225 38 initialise( Config );
c@225 39 }
c@225 40
c@225 41 PeakPicking::~PeakPicking()
c@225 42 {
c@225 43 deInitialise();
c@225 44 }
c@225 45
c@225 46 void PeakPicking::initialise( PPickParams Config )
c@225 47 {
c@225 48 m_DFLength = Config.length ;
c@225 49 Qfilta = Config.QuadThresh.a ;
c@225 50 Qfiltb = Config.QuadThresh.b ;
c@225 51 Qfiltc = Config.QuadThresh.c ;
c@225 52
c@225 53 m_DFProcessingParams.length = m_DFLength;
c@225 54 m_DFProcessingParams.LPOrd = Config.LPOrd;
c@225 55 m_DFProcessingParams.LPACoeffs = Config.LPACoeffs;
c@225 56 m_DFProcessingParams.LPBCoeffs = Config.LPBCoeffs;
c@225 57 m_DFProcessingParams.winPre = Config.WinT.pre;
c@225 58 m_DFProcessingParams.winPost = Config.WinT.post;
c@225 59 m_DFProcessingParams.AlphaNormParam = Config.alpha;
c@225 60 m_DFProcessingParams.isMedianPositive = false;
mathieu@321 61 m_DFProcessingParams.Delta = Config.delta; //add the delta threshold as an adjustable parameter
mathieu@321 62
c@225 63 m_DFSmoothing = new DFProcess( m_DFProcessingParams );
c@225 64
c@225 65 m_workBuffer = new double[ m_DFLength ];
c@225 66 memset( m_workBuffer, 0, sizeof(double)*m_DFLength);
c@225 67 }
c@225 68
c@225 69 void PeakPicking::deInitialise()
c@225 70 {
c@225 71 delete [] m_workBuffer;
c@225 72 delete m_DFSmoothing;
c@225 73 m_workBuffer = NULL;
c@225 74 }
c@225 75
c@225 76 void PeakPicking::process( double* src, unsigned int len, vector<int> &onsets )
c@225 77 {
c@283 78 if (len < 4) return;
c@283 79
c@225 80 vector <double> m_maxima;
c@225 81
c@225 82 // Signal conditioning
c@225 83 m_DFSmoothing->process( src, m_workBuffer );
c@225 84
c@225 85 for( unsigned int u = 0; u < len; u++)
c@225 86 {
c@225 87 m_maxima.push_back( m_workBuffer[ u ] );
c@225 88 }
c@225 89
c@225 90 quadEval( m_maxima, onsets );
c@225 91
c@225 92 for( int b = 0; b < m_maxima.size(); b++)
c@225 93 {
c@225 94 src[ b ] = m_maxima[ b ];
c@225 95 }
c@225 96 }
c@225 97
c@225 98 int PeakPicking::quadEval( vector<double> &src, vector<int> &idx )
c@225 99 {
c@225 100 unsigned int maxLength;
c@225 101
c@225 102 vector <int> m_maxIndex;
c@225 103 vector <int> m_onsetPosition;
c@225 104
c@225 105 vector <double> m_maxFit;
c@225 106 vector <double> m_poly;
c@225 107 vector <double> m_err;
c@225 108
c@225 109 double p;
c@225 110
c@225 111 m_poly.push_back(0);
c@225 112 m_poly.push_back(0);
c@225 113 m_poly.push_back(0);
c@225 114
c@225 115 for( int t = -2; t < 3; t++)
c@225 116 {
c@225 117 m_err.push_back( (double)t );
c@225 118 }
c@225 119 for( unsigned int i = 2; i < src.size() - 2; i++)
c@225 120 {
c@237 121 if( (src[i] > src[i-1]) && (src[i] > src[i+1]) && (src[i] > 0) )
c@225 122 {
c@237 123 // m_maxIndex.push_back( i + 1 );
c@237 124 m_maxIndex.push_back(i);
c@225 125 }
c@225 126 }
c@225 127
c@225 128 maxLength = m_maxIndex.size();
c@225 129
c@225 130 double selMax = 0;
c@225 131
c@225 132 for( unsigned int j = 0; j < maxLength ; j++)
c@225 133 {
c@237 134 for (int k = -2; k <= 2; ++k)
c@225 135 {
c@225 136 selMax = src[ m_maxIndex[j] + k ] ;
c@225 137 m_maxFit.push_back(selMax);
c@225 138 }
c@225 139
c@225 140 p = TPolyFit::PolyFit2( m_err, m_maxFit, m_poly);
c@225 141
c@225 142 double f = m_poly[0];
c@225 143 double g = m_poly[1];
c@225 144 double h = m_poly[2];
c@225 145
c@225 146 int kk = m_poly.size();
c@237 147
c@237 148 if (h < -Qfilta || f > Qfiltc)
c@237 149 {
c@237 150 idx.push_back(m_maxIndex[j]);
c@237 151 }
c@225 152
c@237 153 m_maxFit.clear();
c@225 154 }
c@225 155
c@225 156 return 1;
c@225 157 }