annotate dsp/onsets/PeakPicking.cpp @ 12:da277e8b5244

* Some fixes to peak picker * Add broadband energy rise detection function (same as the percussive onset detector in the Vamp example plugins)
author cannam
date Fri, 18 May 2007 16:43:17 +0000
parents d7116e3183f8
children 2e3f5d2d62c1
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.
cannam@0 7 This file copyright 2005-2006 Christian Landone.
cannam@0 8 All rights reserved.
cannam@0 9 */
cannam@0 10
cannam@0 11 #include "PeakPicking.h"
cannam@0 12 #include "dsp/maths/Polyfit.h"
cannam@0 13
cannam@12 14 #include <iostream>
cannam@0 15
cannam@0 16 //////////////////////////////////////////////////////////////////////
cannam@0 17 // Construction/Destruction
cannam@0 18 //////////////////////////////////////////////////////////////////////
cannam@0 19
cannam@0 20 PeakPicking::PeakPicking( PPickParams Config )
cannam@0 21 {
cannam@0 22 m_workBuffer = NULL;
cannam@0 23 initialise( Config );
cannam@0 24 }
cannam@0 25
cannam@0 26 PeakPicking::~PeakPicking()
cannam@0 27 {
cannam@0 28 deInitialise();
cannam@0 29 }
cannam@0 30
cannam@0 31 void PeakPicking::initialise( PPickParams Config )
cannam@0 32 {
cannam@0 33 m_DFLength = Config.length ;
cannam@0 34 Qfilta = Config.QuadThresh.a ;
cannam@0 35 Qfiltb = Config.QuadThresh.b ;
cannam@0 36 Qfiltc = Config.QuadThresh.c ;
cannam@0 37
cannam@0 38 m_DFProcessingParams.length = m_DFLength;
cannam@0 39 m_DFProcessingParams.LPOrd = Config.LPOrd;
cannam@0 40 m_DFProcessingParams.LPACoeffs = Config.LPACoeffs;
cannam@0 41 m_DFProcessingParams.LPBCoeffs = Config.LPBCoeffs;
cannam@0 42 m_DFProcessingParams.winPre = Config.WinT.pre;
cannam@0 43 m_DFProcessingParams.winPost = Config.WinT.post;
cannam@0 44 m_DFProcessingParams.AlphaNormParam = Config.alpha;
cannam@0 45 m_DFProcessingParams.isMedianPositive = false;
cannam@0 46
cannam@0 47 m_DFSmoothing = new DFProcess( m_DFProcessingParams );
cannam@0 48
cannam@0 49 m_workBuffer = new double[ m_DFLength ];
cannam@0 50 memset( m_workBuffer, 0, sizeof(double)*m_DFLength);
cannam@0 51 }
cannam@0 52
cannam@0 53 void PeakPicking::deInitialise()
cannam@0 54 {
cannam@0 55 delete [] m_workBuffer;
cannam@0 56 delete m_DFSmoothing;
cannam@0 57 m_workBuffer = NULL;
cannam@0 58 }
cannam@0 59
cannam@0 60 void PeakPicking::process( double* src, unsigned int len, vector<int> &onsets )
cannam@0 61 {
cannam@0 62 vector <double> m_maxima;
cannam@0 63
cannam@0 64 // Signal conditioning
cannam@0 65 m_DFSmoothing->process( src, m_workBuffer );
cannam@0 66
cannam@0 67 for( unsigned int u = 0; u < len; u++)
cannam@0 68 {
cannam@0 69 m_maxima.push_back( m_workBuffer[ u ] );
cannam@0 70 }
cannam@0 71
cannam@0 72 quadEval( m_maxima, onsets );
cannam@0 73
cannam@0 74 for( int b = 0; b < m_maxima.size(); b++)
cannam@0 75 {
cannam@0 76 src[ b ] = m_maxima[ b ];
cannam@0 77 }
cannam@0 78 }
cannam@0 79
cannam@0 80 int PeakPicking::quadEval( vector<double> &src, vector<int> &idx )
cannam@0 81 {
cannam@0 82 unsigned int maxLength;
cannam@0 83
cannam@0 84 vector <int> m_maxIndex;
cannam@0 85 vector <int> m_onsetPosition;
cannam@0 86
cannam@0 87 vector <double> m_maxFit;
cannam@0 88 vector <double> m_poly;
cannam@0 89 vector <double> m_err;
cannam@0 90
cannam@0 91 double p;
cannam@0 92
cannam@0 93 m_poly.push_back(0);
cannam@0 94 m_poly.push_back(0);
cannam@0 95 m_poly.push_back(0);
cannam@0 96
cannam@0 97 for( int t = -2; t < 3; t++)
cannam@0 98 {
cannam@0 99 m_err.push_back( (double)t );
cannam@0 100 }
cannam@0 101 for( unsigned int i = 2; i < src.size() - 2; i++)
cannam@0 102 {
cannam@12 103 if( (src[i] > src[i-1]) && (src[i] > src[i+1]) && (src[i] > 0) )
cannam@0 104 {
cannam@12 105 // m_maxIndex.push_back( i + 1 );
cannam@12 106 m_maxIndex.push_back(i);
cannam@0 107 }
cannam@0 108 }
cannam@0 109
cannam@0 110 maxLength = m_maxIndex.size();
cannam@0 111
cannam@0 112 double selMax = 0;
cannam@0 113
cannam@0 114 for( unsigned int j = 0; j < maxLength ; j++)
cannam@0 115 {
cannam@12 116 for (int k = -2; k <= 2; ++k)
cannam@0 117 {
cannam@0 118 selMax = src[ m_maxIndex[j] + k ] ;
cannam@0 119 m_maxFit.push_back(selMax);
cannam@0 120 }
cannam@0 121
cannam@0 122 p = TPolyFit::PolyFit2( m_err, m_maxFit, m_poly);
cannam@0 123
cannam@0 124 double f = m_poly[0];
cannam@0 125 double g = m_poly[1];
cannam@0 126 double h = m_poly[2];
cannam@0 127
cannam@0 128 int kk = m_poly.size();
cannam@12 129
cannam@12 130 if (h < -Qfilta || f > Qfiltc)
cannam@12 131 {
cannam@12 132 idx.push_back(m_maxIndex[j]);
cannam@12 133 }
cannam@0 134
cannam@12 135 m_maxFit.clear();
cannam@0 136 }
cannam@0 137
cannam@0 138 return 1;
cannam@0 139 }