annotate dsp/onsets/PeakPicking.cpp @ 96:88f3cfcff55f

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