changeset 86:5eeabb24d677

Fixed implementation issue in complex spectral difference (and its HWR cousin) - thanks to @zbanks for pointing this out. Also updated README for new version
author Adam Stark <adamstark.uk@gmail.com>
date Sun, 10 Jan 2016 11:36:14 +0000
parents db22205f8ffa
children 496d12635af8 995ddf0eadd4
files README.md src/OnsetDetectionFunction.cpp
diffstat 2 files changed, 32 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/README.md	Wed Dec 09 22:58:05 2015 +0000
+++ b/README.md	Sun Jan 10 11:36:14 2016 +0000
@@ -1,7 +1,7 @@
 BTrack - A Real-Time Beat Tracker
 =================================
 
-** Version 1.0.2 **
+** Version 1.0.3 **
 
 *by Adam Stark, Matthew Davies and Mark Plumbley.*
 
@@ -22,6 +22,11 @@
 Versions
 --------
 
+==== 1.0.3 ==== (10th January 2016)
+
+* Fixed implementation error in complex spectral difference (thanks to @zbanks for pointing it out)
+* Small change to python module build script
+
 ==== 1.0.2 ==== (25th November 2014)
 
 * Added updated Max external project and associated files
--- a/src/OnsetDetectionFunction.cpp	Wed Dec 09 22:58:05 2015 +0000
+++ b/src/OnsetDetectionFunction.cpp	Sun Jan 10 11:36:14 2016 +0000
@@ -435,10 +435,9 @@
 //=======================================================================
 double OnsetDetectionFunction :: complexSpectralDifference()
 {
-	double dev,pdev;
+	double phaseDeviation;
 	double sum;
-	double mag_diff,phase_diff;
-	double value;
+	double csd;
 	
 	// perform the FFT
 	performFFT();
@@ -454,29 +453,14 @@
 		// calculate magnitude value
 		magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2));
 		
+		// phase deviation
+		phaseDeviation = phase[i] - (2*prevPhase[i]) + prevPhase2[i];
 		
-		// phase deviation
-		dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i];
-		
-		// wrap into [-pi,pi] range
-		pdev = princarg(dev);	
-		
-		
-		// calculate magnitude difference (real part of Euclidean distance between complex frames)
-		mag_diff = magSpec[i] - prevMagSpec[i];
-		
-		// calculate phase difference (imaginary part of Euclidean distance between complex frames)
-		phase_diff = -magSpec[i]*sin(pdev);
-		
-
-		
-		// square real and imaginary parts, sum and take square root
-		value = sqrt(pow(mag_diff,2) + pow(phase_diff,2));
-	
+        // calculate complex spectral difference for the current spectral bin
+		csd = sqrt(pow(magSpec[i], 2) + pow(prevMagSpec[i], 2) - 2 * magSpec[i] * prevMagSpec[i] * cos(phaseDeviation));
 			
 		// add to sum
-		sum = sum + value;
-		
+		sum = sum + csd;
 		
 		// store values for next calculation
 		prevPhase2[i] = prevPhase[i];
@@ -490,10 +474,10 @@
 //=======================================================================
 double OnsetDetectionFunction :: complexSpectralDifferenceHWR()
 {
-	double dev,pdev;
+	double phaseDeviation;
 	double sum;
-	double mag_diff,phase_diff;
-	double value;
+	double magnitudeDifference;
+	double csd;
 	
 	// perform the FFT
 	performFFT();
@@ -509,30 +493,22 @@
 		// calculate magnitude value
 		magSpec[i] = sqrt(pow(complexOut[i][0],2) + pow(complexOut[i][1],2));
 		
-		
-		// phase deviation
-		dev = phase[i] - (2*prevPhase[i]) + prevPhase2[i];
-		
-		// wrap into [-pi,pi] range
-		pdev = princarg(dev);	
-		
-		
-		// calculate magnitude difference (real part of Euclidean distance between complex frames)
-		mag_diff = magSpec[i] - prevMagSpec[i];
-		
-		// if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification)
-		if (mag_diff > 0)
-		{
-			// calculate phase difference (imaginary part of Euclidean distance between complex frames)
-			phase_diff = -magSpec[i]*sin(pdev);
-
-			// square real and imaginary parts, sum and take square root
-			value = sqrt(pow(mag_diff,2) + pow(phase_diff,2));
-		
-			// add to sum
-			sum = sum + value;
-		}
-		
+        // phase deviation
+        phaseDeviation = phase[i] - (2*prevPhase[i]) + prevPhase2[i];
+        
+        // calculate magnitude difference (real part of Euclidean distance between complex frames)
+        magnitudeDifference = magSpec[i] - prevMagSpec[i];
+        
+        // if we have a positive change in magnitude, then include in sum, otherwise ignore (half-wave rectification)
+        if (magnitudeDifference > 0)
+        {
+            // calculate complex spectral difference for the current spectral bin
+            csd = sqrt(pow(magSpec[i], 2) + pow(prevMagSpec[i], 2) - 2 * magSpec[i] * prevMagSpec[i] * cos(phaseDeviation));
+        
+            // add to sum
+            sum = sum + csd;
+        }
+        
 		// store values for next calculation
 		prevPhase2[i] = prevPhase[i];
 		prevPhase[i] = phase[i];