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