summaryrefslogtreecommitdiff
path: root/libs/qm-dsp/dsp/onsets/PeakPicking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/qm-dsp/dsp/onsets/PeakPicking.cpp')
-rw-r--r--libs/qm-dsp/dsp/onsets/PeakPicking.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/libs/qm-dsp/dsp/onsets/PeakPicking.cpp b/libs/qm-dsp/dsp/onsets/PeakPicking.cpp
new file mode 100644
index 0000000000..879ae8813c
--- /dev/null
+++ b/libs/qm-dsp/dsp/onsets/PeakPicking.cpp
@@ -0,0 +1,148 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
+
+/*
+ QM DSP Library
+
+ Centre for Digital Music, Queen Mary, University of London.
+ This file 2005-2006 Christian Landone.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. See the file
+ COPYING included with this distribution for more information.
+*/
+
+#include "PeakPicking.h"
+#include "maths/Polyfit.h"
+
+#include <iostream>
+#include <cstring>
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+PeakPicking::PeakPicking( PPickParams Config )
+{
+ m_workBuffer = NULL;
+ initialise( Config );
+}
+
+PeakPicking::~PeakPicking()
+{
+ deInitialise();
+}
+
+void PeakPicking::initialise( PPickParams Config )
+{
+ m_DFLength = Config.length ;
+ Qfilta = Config.QuadThresh.a ;
+ Qfiltb = Config.QuadThresh.b ;
+ Qfiltc = Config.QuadThresh.c ;
+
+ m_DFProcessingParams.length = m_DFLength;
+ m_DFProcessingParams.LPOrd = Config.LPOrd;
+ m_DFProcessingParams.LPACoeffs = Config.LPACoeffs;
+ m_DFProcessingParams.LPBCoeffs = Config.LPBCoeffs;
+ m_DFProcessingParams.winPre = Config.WinT.pre;
+ m_DFProcessingParams.winPost = Config.WinT.post;
+ m_DFProcessingParams.AlphaNormParam = Config.alpha;
+ m_DFProcessingParams.isMedianPositive = false;
+
+ m_DFSmoothing = new DFProcess( m_DFProcessingParams );
+
+ m_workBuffer = new double[ m_DFLength ];
+ memset( m_workBuffer, 0, sizeof(double)*m_DFLength);
+}
+
+void PeakPicking::deInitialise()
+{
+ delete [] m_workBuffer;
+ delete m_DFSmoothing;
+ m_workBuffer = NULL;
+}
+
+void PeakPicking::process( double* src, unsigned int len, vector<int> &onsets )
+{
+ if (len < 4) return;
+
+ vector <double> m_maxima;
+
+ // Signal conditioning
+ m_DFSmoothing->process( src, m_workBuffer );
+
+ for( unsigned int u = 0; u < len; u++)
+ {
+ m_maxima.push_back( m_workBuffer[ u ] );
+ }
+
+ quadEval( m_maxima, onsets );
+
+ for( int b = 0; b < m_maxima.size(); b++)
+ {
+ src[ b ] = m_maxima[ b ];
+ }
+}
+
+int PeakPicking::quadEval( vector<double> &src, vector<int> &idx )
+{
+ unsigned int maxLength;
+
+ vector <int> m_maxIndex;
+ vector <int> m_onsetPosition;
+
+ vector <double> m_maxFit;
+ vector <double> m_poly;
+ vector <double> m_err;
+
+ double p;
+
+ m_poly.push_back(0);
+ m_poly.push_back(0);
+ m_poly.push_back(0);
+
+ for( int t = -2; t < 3; t++)
+ {
+ m_err.push_back( (double)t );
+ }
+ for( unsigned int i = 2; i < src.size() - 2; i++)
+ {
+ if( (src[i] > src[i-1]) && (src[i] > src[i+1]) && (src[i] > 0) )
+ {
+// m_maxIndex.push_back( i + 1 );
+ m_maxIndex.push_back(i);
+ }
+ }
+
+ maxLength = m_maxIndex.size();
+
+ double selMax = 0;
+
+ for( unsigned int j = 0; j < maxLength ; j++)
+ {
+ for (int k = -2; k <= 2; ++k)
+ {
+ selMax = src[ m_maxIndex[j] + k ] ;
+ m_maxFit.push_back(selMax);
+ }
+
+ p = TPolyFit::PolyFit2( m_err, m_maxFit, m_poly);
+
+ double f = m_poly[0];
+ double g = m_poly[1];
+ double h = m_poly[2];
+
+ int kk = m_poly.size();
+
+ if (h < -Qfilta || f > Qfiltc)
+ {
+ idx.push_back(m_maxIndex[j]);
+ }
+
+ m_maxFit.clear();
+ }
+
+ return 1;
+}