annotate dsp/onsets/DetectionFunction.cpp @ 2:c539af5259da

* Make it possible to provide the detection function with frequency domain inputs (i.e. phase vocoder already run)
author cannam
date Mon, 15 May 2006 11:21:47 +0000
parents d7116e3183f8
children da277e8b5244
rev   line source
cannam@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@0 2
cannam@0 3 /*
cannam@0 4 QM DSP Library
cannam@0 5
cannam@0 6 Centre for Digital Music, Queen Mary, University of London.
cannam@0 7 This file copyright 2005-2006 Christian Landone.
cannam@0 8 All rights reserved.
cannam@0 9 */
cannam@0 10
cannam@0 11 #include "DetectionFunction.h"
cannam@0 12
cannam@0 13 //////////////////////////////////////////////////////////////////////
cannam@0 14 // Construction/Destruction
cannam@0 15 //////////////////////////////////////////////////////////////////////
cannam@0 16
cannam@0 17 DetectionFunction::DetectionFunction( DFConfig Config ) :
cannam@0 18 m_window(0)
cannam@0 19 {
cannam@2 20 m_magHistory = NULL;
cannam@2 21 m_phaseHistory = NULL;
cannam@2 22 m_phaseHistoryOld = NULL;
cannam@0 23
cannam@0 24 initialise( Config );
cannam@0 25 }
cannam@0 26
cannam@0 27 DetectionFunction::~DetectionFunction()
cannam@0 28 {
cannam@0 29 deInitialise();
cannam@0 30 }
cannam@0 31
cannam@0 32
cannam@0 33 void DetectionFunction::initialise( DFConfig Config )
cannam@0 34 {
cannam@0 35 m_dataLength = Config.frameLength;
cannam@0 36 m_halfLength = m_dataLength/2;
cannam@0 37 m_DFType = Config.DFType;
cannam@0 38
cannam@2 39 m_magHistory = new double[ m_halfLength ];
cannam@2 40 memset(m_magHistory,0, m_halfLength*sizeof(double));
cannam@0 41
cannam@2 42 m_phaseHistory = new double[ m_halfLength ];
cannam@2 43 memset(m_phaseHistory,0, m_halfLength*sizeof(double));
cannam@0 44
cannam@2 45 m_phaseHistoryOld = new double[ m_halfLength ];
cannam@2 46 memset(m_phaseHistoryOld,0, m_halfLength*sizeof(double));
cannam@0 47
cannam@0 48 m_phaseVoc = new PhaseVocoder;
cannam@0 49
cannam@0 50 m_DFWindowedFrame = new double[ m_dataLength ];
cannam@0 51 m_magnitude = new double[ m_halfLength ];
cannam@0 52 m_thetaAngle = new double[ m_halfLength ];
cannam@0 53
cannam@0 54 m_window = new Window<double>(HanningWindow, m_dataLength);
cannam@0 55 }
cannam@0 56
cannam@0 57 void DetectionFunction::deInitialise()
cannam@0 58 {
cannam@2 59 delete [] m_magHistory ;
cannam@2 60 delete [] m_phaseHistory ;
cannam@2 61 delete [] m_phaseHistoryOld ;
cannam@0 62
cannam@0 63 delete m_phaseVoc;
cannam@0 64
cannam@0 65 delete [] m_DFWindowedFrame;
cannam@0 66 delete [] m_magnitude;
cannam@0 67 delete [] m_thetaAngle;
cannam@0 68
cannam@0 69 delete m_window;
cannam@0 70 }
cannam@0 71
cannam@0 72 double DetectionFunction::process( double *TDomain )
cannam@0 73 {
cannam@0 74 m_window->cut( TDomain, m_DFWindowedFrame );
cannam@0 75
cannam@0 76 m_phaseVoc->process( m_dataLength, m_DFWindowedFrame, m_magnitude, m_thetaAngle );
cannam@0 77
cannam@2 78 return runDF();
cannam@2 79 }
cannam@2 80
cannam@2 81 double DetectionFunction::process( double *magnitudes, double *phases )
cannam@2 82 {
cannam@2 83 for (size_t i = 0; i < m_halfLength; ++i) {
cannam@2 84 m_magnitude[i] = magnitudes[i];
cannam@2 85 m_thetaAngle[i] = phases[i];
cannam@2 86 }
cannam@2 87
cannam@2 88 return runDF();
cannam@2 89 }
cannam@2 90
cannam@2 91 double DetectionFunction::runDF()
cannam@2 92 {
cannam@2 93 double retVal = 0;
cannam@2 94
cannam@0 95 switch( m_DFType )
cannam@0 96 {
cannam@0 97 case DF_HFC:
cannam@0 98 retVal = HFC( m_halfLength, m_magnitude);
cannam@0 99 break;
cannam@0 100
cannam@0 101 case DF_SPECDIFF:
cannam@0 102 retVal = specDiff( m_halfLength, m_magnitude);
cannam@0 103 break;
cannam@0 104
cannam@0 105 case DF_PHASEDEV:
cannam@0 106 retVal = phaseDev( m_halfLength, m_magnitude, m_thetaAngle);
cannam@0 107 break;
cannam@0 108
cannam@0 109 case DF_COMPLEXSD:
cannam@0 110 retVal = complexSD( m_halfLength, m_magnitude, m_thetaAngle);
cannam@0 111 break;
cannam@0 112 }
cannam@0 113
cannam@0 114 return retVal;
cannam@0 115 }
cannam@0 116
cannam@0 117 double DetectionFunction::HFC(unsigned int length, double *src)
cannam@0 118 {
cannam@0 119 unsigned int i;
cannam@0 120 double val = 0;
cannam@0 121
cannam@0 122 for( i = 0; i < length; i++)
cannam@0 123 {
cannam@0 124 val += src[ i ] * ( i + 1);
cannam@0 125 }
cannam@0 126 return val;
cannam@0 127 }
cannam@0 128
cannam@0 129 double DetectionFunction::specDiff(unsigned int length, double *src)
cannam@0 130 {
cannam@0 131 unsigned int i;
cannam@0 132 double val = 0.0;
cannam@0 133 double temp = 0.0;
cannam@0 134 double diff = 0.0;
cannam@0 135
cannam@0 136 for( i = 0; i < length; i++)
cannam@0 137 {
cannam@2 138 temp = fabs( (src[ i ] * src[ i ]) - (m_magHistory[ i ] * m_magHistory[ i ]) );
cannam@0 139
cannam@0 140 diff= sqrt(temp);
cannam@0 141
cannam@0 142 if( src[ i ] > 0.1)
cannam@0 143 {
cannam@0 144 val += diff;
cannam@0 145 }
cannam@0 146
cannam@2 147 m_magHistory[ i ] = src[ i ];
cannam@0 148 }
cannam@0 149
cannam@0 150 return val;
cannam@0 151 }
cannam@0 152
cannam@0 153
cannam@0 154 double DetectionFunction::phaseDev(unsigned int length, double *srcMagnitude, double *srcPhase)
cannam@0 155 {
cannam@0 156 unsigned int i;
cannam@0 157 double tmpPhase = 0;
cannam@0 158 double tmpVal = 0;
cannam@0 159 double val = 0;
cannam@0 160
cannam@0 161 double dev = 0;
cannam@0 162
cannam@0 163 for( i = 0; i < length; i++)
cannam@0 164 {
cannam@2 165 tmpPhase = (srcPhase[ i ]- 2*m_phaseHistory[ i ]+m_phaseHistoryOld[ i ]);
cannam@0 166 dev = MathUtilities::princarg( tmpPhase );
cannam@0 167
cannam@0 168 if( srcMagnitude[ i ] > 0.1)
cannam@0 169 {
cannam@0 170 tmpVal = fabs( dev);
cannam@0 171 val += tmpVal ;
cannam@0 172 }
cannam@0 173
cannam@2 174 m_phaseHistoryOld[ i ] = m_phaseHistory[ i ] ;
cannam@2 175 m_phaseHistory[ i ] = srcPhase[ i ];
cannam@0 176 }
cannam@0 177
cannam@0 178
cannam@0 179 return val;
cannam@0 180 }
cannam@0 181
cannam@0 182
cannam@0 183 double DetectionFunction::complexSD(unsigned int length, double *srcMagnitude, double *srcPhase)
cannam@0 184 {
cannam@0 185 unsigned int i;
cannam@0 186 double val = 0;
cannam@0 187 double tmpPhase = 0;
cannam@0 188 double tmpReal = 0;
cannam@0 189 double tmpImag = 0;
cannam@0 190
cannam@0 191 double dev = 0;
cannam@0 192 ComplexData meas = ComplexData( 0, 0 );
cannam@2 193 ComplexData j = ComplexData( 0, 1 );
cannam@0 194
cannam@0 195 for( i = 0; i < length; i++)
cannam@0 196 {
cannam@2 197 tmpPhase = (srcPhase[ i ]- 2*m_phaseHistory[ i ]+m_phaseHistoryOld[ i ]);
cannam@0 198 dev= MathUtilities::princarg( tmpPhase );
cannam@0 199
cannam@2 200 meas = m_magHistory[i] - ( srcMagnitude[ i ] * exp( j * dev) );
cannam@0 201
cannam@0 202 tmpReal = real( meas );
cannam@0 203 tmpImag = imag( meas );
cannam@0 204
cannam@0 205 val += sqrt( (tmpReal * tmpReal) + (tmpImag * tmpImag) );
cannam@0 206
cannam@2 207 m_phaseHistoryOld[ i ] = m_phaseHistory[ i ] ;
cannam@2 208 m_phaseHistory[ i ] = srcPhase[ i ];
cannam@2 209 m_magHistory[ i ] = srcMagnitude[ i ];
cannam@0 210 }
cannam@0 211
cannam@0 212 return val;
cannam@0 213 }
cannam@0 214
cannam@0 215 double* DetectionFunction::getSpectrumMagnitude()
cannam@0 216 {
cannam@0 217 return m_magnitude;
cannam@0 218 }
cannam@0 219