qm-dsp
1.8
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 QM DSP Library 00005 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file 2005-2006 Christian Landone. 00008 00009 Modifications: 00010 00011 - delta threshold 00012 Description: add delta threshold used as offset in the smoothed 00013 detection function 00014 Author: Mathieu Barthet 00015 Date: June 2010 00016 00017 This program is free software; you can redistribute it and/or 00018 modify it under the terms of the GNU General Public License as 00019 published by the Free Software Foundation; either version 2 of the 00020 License, or (at your option) any later version. See the file 00021 COPYING included with this distribution for more information. 00022 */ 00023 00024 #include "PeakPicking.h" 00025 #include "maths/Polyfit.h" 00026 00027 #include <iostream> 00028 #include <cstring> 00029 00030 00032 // Construction/Destruction 00034 00035 PeakPicking::PeakPicking( PPickParams Config ) 00036 { 00037 m_workBuffer = NULL; 00038 initialise( Config ); 00039 } 00040 00041 PeakPicking::~PeakPicking() 00042 { 00043 deInitialise(); 00044 } 00045 00046 void PeakPicking::initialise( PPickParams Config ) 00047 { 00048 m_DFLength = Config.length ; 00049 Qfilta = Config.QuadThresh.a ; 00050 Qfiltb = Config.QuadThresh.b ; 00051 Qfiltc = Config.QuadThresh.c ; 00052 00053 m_DFProcessingParams.length = m_DFLength; 00054 m_DFProcessingParams.LPOrd = Config.LPOrd; 00055 m_DFProcessingParams.LPACoeffs = Config.LPACoeffs; 00056 m_DFProcessingParams.LPBCoeffs = Config.LPBCoeffs; 00057 m_DFProcessingParams.winPre = Config.WinT.pre; 00058 m_DFProcessingParams.winPost = Config.WinT.post; 00059 m_DFProcessingParams.AlphaNormParam = Config.alpha; 00060 m_DFProcessingParams.isMedianPositive = false; 00061 m_DFProcessingParams.Delta = Config.delta; //add the delta threshold as an adjustable parameter 00062 00063 m_DFSmoothing = new DFProcess( m_DFProcessingParams ); 00064 00065 m_workBuffer = new double[ m_DFLength ]; 00066 memset( m_workBuffer, 0, sizeof(double)*m_DFLength); 00067 } 00068 00069 void PeakPicking::deInitialise() 00070 { 00071 delete [] m_workBuffer; 00072 delete m_DFSmoothing; 00073 m_workBuffer = NULL; 00074 } 00075 00076 void PeakPicking::process( double* src, unsigned int len, vector<int> &onsets ) 00077 { 00078 if (len < 4) return; 00079 00080 vector <double> m_maxima; 00081 00082 // Signal conditioning 00083 m_DFSmoothing->process( src, m_workBuffer ); 00084 00085 for( unsigned int u = 0; u < len; u++) 00086 { 00087 m_maxima.push_back( m_workBuffer[ u ] ); 00088 } 00089 00090 quadEval( m_maxima, onsets ); 00091 00092 for( int b = 0; b < (int)m_maxima.size(); b++) 00093 { 00094 src[ b ] = m_maxima[ b ]; 00095 } 00096 } 00097 00098 int PeakPicking::quadEval( vector<double> &src, vector<int> &idx ) 00099 { 00100 unsigned int maxLength; 00101 00102 vector <int> m_maxIndex; 00103 vector <int> m_onsetPosition; 00104 00105 vector <double> m_maxFit; 00106 vector <double> m_poly; 00107 vector <double> m_err; 00108 00109 m_poly.push_back(0); 00110 m_poly.push_back(0); 00111 m_poly.push_back(0); 00112 00113 for( int t = -2; t < 3; t++) 00114 { 00115 m_err.push_back( (double)t ); 00116 } 00117 for( unsigned int i = 2; i < src.size() - 2; i++) 00118 { 00119 if( (src[i] > src[i-1]) && (src[i] > src[i+1]) && (src[i] > 0) ) 00120 { 00121 // m_maxIndex.push_back( i + 1 ); 00122 m_maxIndex.push_back(i); 00123 } 00124 } 00125 00126 maxLength = m_maxIndex.size(); 00127 00128 double selMax = 0; 00129 00130 for( unsigned int j = 0; j < maxLength ; j++) 00131 { 00132 for (int k = -2; k <= 2; ++k) 00133 { 00134 selMax = src[ m_maxIndex[j] + k ] ; 00135 m_maxFit.push_back(selMax); 00136 } 00137 00138 TPolyFit::PolyFit2(m_err, m_maxFit, m_poly); 00139 00140 double f = m_poly[0]; 00141 double h = m_poly[2]; 00142 00143 if (h < -Qfilta || f > Qfiltc) 00144 { 00145 idx.push_back(m_maxIndex[j]); 00146 } 00147 00148 m_maxFit.clear(); 00149 } 00150 00151 return 1; 00152 }