Mercurial > hg > qm-dsp
changeset 239:135f16b49065
* add adaptive whitening and simple power metric
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Thu, 09 Aug 2007 16:30:26 +0000 |
parents | e8e5f9130b49 |
children | 1a406914b3a9 |
files | dsp/onsets/DetectionFunction.cpp dsp/onsets/DetectionFunction.h |
diffstat | 2 files changed, 60 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/dsp/onsets/DetectionFunction.cpp Wed May 23 15:22:10 2007 +0000 +++ b/dsp/onsets/DetectionFunction.cpp Thu Aug 09 16:30:26 2007 +0000 @@ -20,6 +20,7 @@ m_magHistory = NULL; m_phaseHistory = NULL; m_phaseHistoryOld = NULL; + m_magPeaks = NULL; initialise( Config ); } @@ -34,10 +35,17 @@ { m_dataLength = Config.frameLength; m_halfLength = m_dataLength/2; + m_DFType = Config.DFType; m_stepSecs = Config.stepSecs; m_stepSize = Config.stepSize; + m_whiten = Config.adaptiveWhitening; + m_whitenRelaxCoeff = Config.whiteningRelaxCoeff; + m_whitenFloor = Config.whiteningFloor; + if (m_whitenRelaxCoeff < 0) m_whitenRelaxCoeff = 0.9997; + if (m_whitenFloor < 0) m_whitenFloor = 0.01; + m_magHistory = new double[ m_halfLength ]; memset(m_magHistory,0, m_halfLength*sizeof(double)); @@ -47,6 +55,9 @@ m_phaseHistoryOld = new double[ m_halfLength ]; memset(m_phaseHistoryOld,0, m_halfLength*sizeof(double)); + m_magPeaks = new double[ m_halfLength ]; + memset(m_magPeaks,0, m_halfLength*sizeof(double)); + m_phaseVoc = new PhaseVocoder; m_DFWindowedFrame = new double[ m_dataLength ]; @@ -61,6 +72,7 @@ delete [] m_magHistory ; delete [] m_phaseHistory ; delete [] m_phaseHistoryOld ; + delete [] m_magPeaks ; delete m_phaseVoc; @@ -77,6 +89,8 @@ m_phaseVoc->process( m_dataLength, m_DFWindowedFrame, m_magnitude, m_thetaAngle ); + if (m_whiten) whiten(); + return runDF(); } @@ -87,9 +101,24 @@ m_thetaAngle[i] = phases[i]; } + if (m_whiten) whiten(); + return runDF(); } +void DetectionFunction::whiten() +{ + for (unsigned int i = 0; i < m_halfLength; ++i) { + double m = m_magnitude[i]; + if (m < m_magPeaks[i]) { + m = m + (m_magPeaks[i] - m) * m_whitenRelaxCoeff; + } + if (m < m_whitenFloor) m = m_whitenFloor; + m_magPeaks[i] = m; + m_magnitude[i] /= m; + } +} + double DetectionFunction::runDF() { double retVal = 0; @@ -105,7 +134,7 @@ break; case DF_PHASEDEV: - retVal = phaseDev( m_halfLength, m_magnitude, m_thetaAngle); + retVal = phaseDev( m_halfLength, m_thetaAngle); break; case DF_COMPLEXSD: @@ -113,7 +142,12 @@ break; case DF_BROADBAND: - retVal = broadband( m_halfLength, m_magnitude, m_thetaAngle); + retVal = broadband( m_halfLength, m_magnitude); + break; + + case DF_POWER: + retVal = power( m_halfLength, m_magnitude ); + break; } return retVal; @@ -155,7 +189,7 @@ } -double DetectionFunction::phaseDev(unsigned int length, double *srcMagnitude, double *srcPhase) +double DetectionFunction::phaseDev(unsigned int length, double *srcPhase) { unsigned int i; double tmpPhase = 0; @@ -221,11 +255,11 @@ return val; } -double DetectionFunction::broadband(unsigned int length, double *srcMagnitude, double *srcPhase) +double DetectionFunction::broadband(unsigned int length, double *src) { double val = 0; for (unsigned int i = 0; i < length; ++i) { - double sqrmag = srcMagnitude[i] * srcMagnitude[i]; + double sqrmag = src[i] * src[i]; if (m_magHistory[i] > 0.0) { double diff = 10.0 * log10(sqrmag / m_magHistory[i]); if (diff > m_dbRise) val = val + 1; @@ -235,6 +269,15 @@ return val; } +double DetectionFunction::power(unsigned int length, double *src) +{ + double val = 0; + for (unsigned int i = 0; i < length; ++i) { + val += src[i]; + } + return val; +} + double* DetectionFunction::getSpectrumMagnitude() { return m_magnitude;
--- a/dsp/onsets/DetectionFunction.h Wed May 23 15:22:10 2007 +0000 +++ b/dsp/onsets/DetectionFunction.h Thu Aug 09 16:30:26 2007 +0000 @@ -21,6 +21,7 @@ #define DF_PHASEDEV (3) #define DF_COMPLEXSD (4) #define DF_BROADBAND (5) +#define DF_POWER (6) struct DFConfig{ double stepSecs; // DF step in seconds @@ -28,6 +29,9 @@ unsigned int frameLength; // DF analysis window - usually 2*step int DFType; // type of detection function ( see defines ) double dbRise; // only used for broadband df (and required for it) + bool adaptiveWhitening; // perform adaptive whitening + double whiteningRelaxCoeff; // if < 0, a sensible default will be used + double whiteningFloor; // if < 0, a sensible default will be used }; class DetectionFunction @@ -40,13 +44,15 @@ double process( double* magnitudes, double* phases ); private: + void whiten(); double runDF(); double HFC( unsigned int length, double* src); double specDiff( unsigned int length, double* src); - double phaseDev(unsigned int length, double *srcMagnitude, double *srcPhase); + double phaseDev(unsigned int length, double *srcPhase); double complexSD(unsigned int length, double *srcMagnitude, double *srcPhase); - double broadband(unsigned int length, double *srcMagnitude, double *srcPhase); + double broadband(unsigned int length, double *srcMagnitude); + double power(unsigned int length, double *src); private: void initialise( DFConfig Config ); @@ -58,10 +64,14 @@ double m_stepSecs; unsigned int m_stepSize; double m_dbRise; + bool m_whiten; + double m_whitenRelaxCoeff; + double m_whitenFloor; double* m_magHistory; double* m_phaseHistory; double* m_phaseHistoryOld; + double* m_magPeaks; double* m_DFWindowedFrame; // Array for windowed analysis frame double* m_magnitude; // Magnitude of analysis frame ( frequency domain )