c@225: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ c@225: c@225: /* c@225: QM DSP Library c@225: c@225: Centre for Digital Music, Queen Mary, University of London. c@225: This file copyright 2005-2006 Christian Landone. c@225: All rights reserved. c@225: */ c@225: c@225: #include "DetectionFunction.h" c@225: c@225: ////////////////////////////////////////////////////////////////////// c@225: // Construction/Destruction c@225: ////////////////////////////////////////////////////////////////////// c@225: c@225: DetectionFunction::DetectionFunction( DFConfig Config ) : c@225: m_window(0) c@225: { c@225: magHistory = NULL; c@225: phaseHistory = NULL; c@225: phaseHistoryOld = NULL; c@225: j = ComplexData( 0, 1 ); c@225: c@225: initialise( Config ); c@225: } c@225: c@225: DetectionFunction::~DetectionFunction() c@225: { c@225: deInitialise(); c@225: } c@225: c@225: c@225: void DetectionFunction::initialise( DFConfig Config ) c@225: { c@225: m_dataLength = Config.frameLength; c@225: m_halfLength = m_dataLength/2; c@225: m_DFType = Config.DFType; c@225: c@225: magHistory = new double[ m_halfLength ]; c@225: memset(magHistory,0, m_halfLength*sizeof(double)); c@225: c@225: phaseHistory = new double[ m_halfLength ]; c@225: memset(phaseHistory,0, m_halfLength*sizeof(double)); c@225: c@225: phaseHistoryOld = new double[ m_halfLength ]; c@225: memset(phaseHistoryOld,0, m_halfLength*sizeof(double)); c@225: c@225: m_phaseVoc = new PhaseVocoder; c@225: c@225: m_DFWindowedFrame = new double[ m_dataLength ]; c@225: m_magnitude = new double[ m_halfLength ]; c@225: m_thetaAngle = new double[ m_halfLength ]; c@225: c@225: m_window = new Window(HanningWindow, m_dataLength); c@225: } c@225: c@225: void DetectionFunction::deInitialise() c@225: { c@225: delete [] magHistory ; c@225: delete [] phaseHistory ; c@225: delete [] phaseHistoryOld ; c@225: c@225: delete m_phaseVoc; c@225: c@225: delete [] m_DFWindowedFrame; c@225: delete [] m_magnitude; c@225: delete [] m_thetaAngle; c@225: c@225: delete m_window; c@225: } c@225: c@225: double DetectionFunction::process( double *TDomain ) c@225: { c@225: double retVal = 0; c@225: c@225: m_window->cut( TDomain, m_DFWindowedFrame ); c@225: c@225: m_phaseVoc->process( m_dataLength, m_DFWindowedFrame, m_magnitude, m_thetaAngle ); c@225: c@225: switch( m_DFType ) c@225: { c@225: case DF_HFC: c@225: retVal = HFC( m_halfLength, m_magnitude); c@225: break; c@225: c@225: case DF_SPECDIFF: c@225: retVal = specDiff( m_halfLength, m_magnitude); c@225: break; c@225: c@225: case DF_PHASEDEV: c@225: retVal = phaseDev( m_halfLength, m_magnitude, m_thetaAngle); c@225: break; c@225: c@225: case DF_COMPLEXSD: c@225: retVal = complexSD( m_halfLength, m_magnitude, m_thetaAngle); c@225: break; c@225: } c@225: c@225: return retVal; c@225: } c@225: c@225: double DetectionFunction::HFC(unsigned int length, double *src) c@225: { c@225: unsigned int i; c@225: double val = 0; c@225: c@225: for( i = 0; i < length; i++) c@225: { c@225: val += src[ i ] * ( i + 1); c@225: } c@225: return val; c@225: } c@225: c@225: double DetectionFunction::specDiff(unsigned int length, double *src) c@225: { c@225: unsigned int i; c@225: double val = 0.0; c@225: double temp = 0.0; c@225: double diff = 0.0; c@225: c@225: for( i = 0; i < length; i++) c@225: { c@225: temp = fabs( (src[ i ] * src[ i ]) - (magHistory[ i ] * magHistory[ i ]) ); c@225: c@225: diff= sqrt(temp); c@225: c@225: if( src[ i ] > 0.1) c@225: { c@225: val += diff; c@225: } c@225: c@225: magHistory[ i ] = src[ i ]; c@225: } c@225: c@225: return val; c@225: } c@225: c@225: c@225: double DetectionFunction::phaseDev(unsigned int length, double *srcMagnitude, double *srcPhase) c@225: { c@225: unsigned int i; c@225: double tmpPhase = 0; c@225: double tmpVal = 0; c@225: double val = 0; c@225: c@225: double dev = 0; c@225: c@225: for( i = 0; i < length; i++) c@225: { c@225: tmpPhase = (srcPhase[ i ]- 2*phaseHistory[ i ]+phaseHistoryOld[ i ]); c@225: dev = MathUtilities::princarg( tmpPhase ); c@225: c@225: if( srcMagnitude[ i ] > 0.1) c@225: { c@225: tmpVal = fabs( dev); c@225: val += tmpVal ; c@225: } c@225: c@225: phaseHistoryOld[ i ] = phaseHistory[ i ] ; c@225: phaseHistory[ i ] = srcPhase[ i ]; c@225: } c@225: c@225: c@225: return val; c@225: } c@225: c@225: c@225: double DetectionFunction::complexSD(unsigned int length, double *srcMagnitude, double *srcPhase) c@225: { c@225: unsigned int i; c@225: double val = 0; c@225: double tmpPhase = 0; c@225: double tmpReal = 0; c@225: double tmpImag = 0; c@225: c@225: double dev = 0; c@225: ComplexData meas = ComplexData( 0, 0 ); c@225: c@225: for( i = 0; i < length; i++) c@225: { c@225: tmpPhase = (srcPhase[ i ]- 2*phaseHistory[ i ]+phaseHistoryOld[ i ]); c@225: dev= MathUtilities::princarg( tmpPhase ); c@225: c@225: meas = magHistory[i] - ( srcMagnitude[ i ] * exp( j * dev) ); c@225: c@225: tmpReal = real( meas ); c@225: tmpImag = imag( meas ); c@225: c@225: val += sqrt( (tmpReal * tmpReal) + (tmpImag * tmpImag) ); c@225: c@225: phaseHistoryOld[ i ] = phaseHistory[ i ] ; c@225: phaseHistory[ i ] = srcPhase[ i ]; c@225: magHistory[ i ] = srcMagnitude[ i ]; c@225: } c@225: c@225: return val; c@225: } c@225: c@225: double* DetectionFunction::getSpectrumMagnitude() c@225: { c@225: return m_magnitude; c@225: } c@225: