qm-dsp  1.8
DFProcess.cpp
Go to the documentation of this file.
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 }