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 "DFProcess.h" 00025 #include "maths/MathUtilities.h" 00026 00027 #include <cstring> 00028 00030 // Construction/Destruction 00032 00033 DFProcess::DFProcess( DFProcConfig Config ) 00034 { 00035 filtSrc = NULL; 00036 filtDst = NULL; 00037 m_filtScratchIn = NULL; 00038 m_filtScratchOut = NULL; 00039 00040 m_FFOrd = 0; 00041 00042 initialise( Config ); 00043 } 00044 00045 DFProcess::~DFProcess() 00046 { 00047 deInitialise(); 00048 } 00049 00050 void DFProcess::initialise( DFProcConfig Config ) 00051 { 00052 m_length = Config.length; 00053 m_winPre = Config.winPre; 00054 m_winPost = Config.winPost; 00055 m_alphaNormParam = Config.AlphaNormParam; 00056 00057 m_isMedianPositive = Config.isMedianPositive; 00058 00059 filtSrc = new double[ m_length ]; 00060 filtDst = new double[ m_length ]; 00061 00062 00063 //Low Pass Smoothing Filter Config 00064 m_FilterConfigParams.ord = Config.LPOrd; 00065 m_FilterConfigParams.ACoeffs = Config.LPACoeffs; 00066 m_FilterConfigParams.BCoeffs = Config.LPBCoeffs; 00067 00068 m_FiltFilt = new FiltFilt( m_FilterConfigParams ); 00069 00070 //add delta threshold 00071 m_Delta = Config.Delta; 00072 } 00073 00074 void DFProcess::deInitialise() 00075 { 00076 delete [] filtSrc; 00077 00078 delete [] filtDst; 00079 00080 delete [] m_filtScratchIn; 00081 00082 delete [] m_filtScratchOut; 00083 00084 delete m_FiltFilt; 00085 } 00086 00087 void DFProcess::process(double *src, double* dst) 00088 { 00089 if (m_length == 0) return; 00090 00091 removeDCNormalize( src, filtSrc ); 00092 00093 m_FiltFilt->process( filtSrc, filtDst, m_length ); 00094 00095 medianFilter( filtDst, dst ); 00096 } 00097 00098 00099 void DFProcess::medianFilter(double *src, double *dst) 00100 { 00101 int i,k,j,l; 00102 int index = 0; 00103 00104 double val = 0; 00105 00106 double* y = new double[ m_winPost + m_winPre + 1]; 00107 memset( y, 0, sizeof( double ) * ( m_winPost + m_winPre + 1) ); 00108 00109 double* scratch = new double[ m_length ]; 00110 00111 for( i = 0; i < m_winPre; i++) 00112 { 00113 if (index >= m_length) break; 00114 00115 k = i + m_winPost + 1; 00116 00117 for( j = 0; j < k; j++) 00118 { 00119 y[ j ] = src[ j ]; 00120 } 00121 scratch[ index ] = MathUtilities::median( y, k ); 00122 index++; 00123 } 00124 00125 for( i = 0; i + m_winPost + m_winPre < m_length; i ++) 00126 { 00127 if (index >= m_length) break; 00128 00129 00130 l = 0; 00131 for( j = i; j < ( i + m_winPost + m_winPre + 1); j++) 00132 { 00133 y[ l ] = src[ j ]; 00134 l++; 00135 } 00136 00137 scratch[ index++ ] = MathUtilities::median( y, (m_winPost + m_winPre + 1 )); 00138 } 00139 00140 for( i = std::max( m_length - m_winPost, 1); i < m_length; i++) 00141 { 00142 if (index >= m_length) break; 00143 00144 k = std::max( i - m_winPre, 1); 00145 00146 l = 0; 00147 for( j = k; j < m_length; j++) 00148 { 00149 y[ l ] = src[ j ]; 00150 00151 l++; 00152 } 00153 00154 scratch[ index++ ] = MathUtilities::median( y, l); 00155 } 00156 00157 00158 for( i = 0; i < m_length; i++ ) 00159 { 00160 //add a delta threshold used as an offset when computing the smoothed detection function 00161 //(helps to discard noise when detecting peaks) 00162 val = src[ i ] - scratch[ i ] - m_Delta; 00163 00164 if( m_isMedianPositive ) 00165 { 00166 if( val > 0 ) 00167 { 00168 dst[ i ] = val; 00169 } 00170 else 00171 { 00172 dst[ i ] = 0; 00173 } 00174 } 00175 else 00176 { 00177 dst[ i ] = val; 00178 } 00179 } 00180 00181 delete [] y; 00182 delete [] scratch; 00183 } 00184 00185 00186 void DFProcess::removeDCNormalize( double *src, double*dst ) 00187 { 00188 double DFmax = 0; 00189 double DFMin = 0; 00190 double DFAlphaNorm = 0; 00191 00192 MathUtilities::getFrameMinMax( src, m_length, &DFMin, &DFmax ); 00193 00194 MathUtilities::getAlphaNorm( src, m_length, m_alphaNormParam, &DFAlphaNorm ); 00195 00196 for( unsigned int i = 0; i< m_length; i++) 00197 { 00198 dst[ i ] = ( src[ i ] - DFMin ) / DFAlphaNorm; 00199 } 00200 }