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