changeset 62:ad417dd05e0b cheap_diagonals

Merge from branch "refactors_no_float"
author Chris Cannam
date Fri, 14 Nov 2014 13:57:12 +0000
parents fb6e4829c1af (diff) faa523be20f9 (current diff)
children a1ff2d45548c
files src/Finder.cpp src/Finder.h src/MatchFeatureFeeder.cpp src/MatchFeeder.cpp src/Matcher.h
diffstat 10 files changed, 180 insertions(+), 176 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.linux	Fri Nov 14 13:53:58 2014 +0000
+++ b/Makefile.linux	Fri Nov 14 13:57:12 2014 +0000
@@ -1,5 +1,5 @@
 
-CXXFLAGS	+= -fPIC -ffast-math -O3 -Wall -Werror
+CXXFLAGS	+= -fPIC -ffast-math -O3 -Wall -Werror -Wfloat-conversion
 #CXXFLAGS	+= -fPIC -g -Wall -Werror
 
 LDFLAGS		+= -shared -Wl,-Bstatic -lvamp-sdk -Wl,-Bdynamic -Wl,-Bsymbolic -Wl,-z,defs -lpthread -Wl,--version-script=vamp-plugin.map
--- a/src/DistanceMetric.cpp	Fri Nov 14 13:53:58 2014 +0000
+++ b/src/DistanceMetric.cpp	Fri Nov 14 13:57:12 2014 +0000
@@ -56,12 +56,3 @@
     return d / sum * weight;
 }
 
-int
-DistanceMetric::calcDistanceScaled(const vector<double> &f1,
-				   const vector<double> &f2,
-				   double scale)
-{
-    double distance = calcDistance(f1, f2);
-    return int(distance * scale);
-}
-
--- a/src/DistanceMetric.h	Fri Nov 14 13:53:58 2014 +0000
+++ b/src/DistanceMetric.h	Fri Nov 14 13:57:12 2014 +0000
@@ -51,21 +51,6 @@
     double calcDistance(const std::vector<double> &f1,
 			const std::vector<double> &f2);
     
-    /** Calculates the Manhattan distance between two vectors, with an
-     *  optional normalisation by the combined values in the
-     *  vectors. Since the vectors contain energy, this could be
-     *  considered as a squared Euclidean distance metric. Note that
-     *  normalisation assumes the values are all non-negative.
-     *
-     *  @param f1 one of the vectors involved in the distance calculation
-     *  @param f2 one of the vectors involved in the distance calculation
-     *  @param scale the scaling factor to place the result in integer range
-     *  @return the distance, scaled by scale and truncated to an integer
-     */
-    int calcDistanceScaled(const std::vector<double> &f1,
-			   const std::vector<double> &f2,
-			   double scale);
-
 private:
     DistanceNormalisation m_norm;
 };
--- a/src/Finder.cpp	Fri Nov 14 13:53:58 2014 +0000
+++ b/src/Finder.cpp	Fri Nov 14 13:57:12 2014 +0000
@@ -72,23 +72,23 @@
     range[1] = pm2->m_last[col];
 } // getRowRange()
 
-int
+Matcher::Advance
 Finder::getExpandDirection(int row, int col)
 {
     return getExpandDirection(row, col, false);
 } // getExpandDirection()
 
-int
+Matcher::Advance
 Finder::getExpandDirection(int row, int col, bool check)
 {
-    int min = getPathCost(row, col);
+    double min = getPathCost(row, col);
     bestRow = row;
     bestCol = col;
     getRowRange(col, rowRange);
     if (rowRange[1] > row+1)
         rowRange[1] = row+1;	// don't cheat by looking at future :)
     for (int index = rowRange[0]; index < rowRange[1]; index++) {
-        int tmp = getPathCost(index, col);
+        double tmp = getPathCost(index, col);
         if (tmp < min) {
             min = tmp;
             bestRow = index;
@@ -98,7 +98,7 @@
     if (colRange[1] > col+1)
         colRange[1] = col+1;	// don't cheat by looking at future :)
     for (int index = colRange[0]; index < colRange[1]; index++) {
-        int tmp = getPathCost(row, index);
+        double tmp = getPathCost(row, index);
         if (tmp < min) {
             min = tmp;
             bestCol = index;
@@ -109,17 +109,28 @@
     //	System.err.println(" " + pm1->frameCount + " " + pm2->frameCount);
     if (check) {
         //		System.err.println(find(row+1, col) + " " + find(row, col+1));
-        if (!find(row, col+1))
-            return ADVANCE_THIS;
-        if (!find(row+1, col))
-            return ADVANCE_OTHER;
+        if (!find(row, col+1)) {
+            return Matcher::AdvanceThis;
+        } else if (!find(row+1, col)) {
+            return Matcher::AdvanceOther;
+        }
     }
-    return ((bestRow==row)? ADVANCE_THIS: 0) |
-        ((bestCol==col)? ADVANCE_OTHER: 0);
+
+    if (bestRow == row) {
+        if (bestCol == col) {
+            return Matcher::AdvanceBoth;
+        } else {
+            return Matcher::AdvanceThis;
+        }
+    } else if (bestCol == col) {
+        return Matcher::AdvanceOther;
+    } else {
+        return Matcher::AdvanceNone;
+    }
 
 } // getExpandDirection()
 	
-unsigned char
+float
 Finder::getDistance(int row, int col) 
 {
     if (find(row, col)) {
@@ -130,7 +141,7 @@
 } // getDistance()/2
 
 void
-Finder::setDistance(int row, int col, unsigned char b)
+Finder::setDistance(int row, int col, float b)
 {
     if (find(row, col)) {
         pm1->m_distance[row][col - pm1->m_first[row]] = b;
@@ -140,16 +151,16 @@
     throw "setDistance index out of bounds";
 } // setDistance()
 
-int
+double
 Finder::getPathCost(int row, int col)
 {
     if (find(row, col)) // "1" avoids div by 0 below
-        return pm1->m_bestPathCost[row][col - pm1->m_first[row]]*100/ (1+row+col);
+        return pm1->m_bestPathCost[row][col - pm1->m_first[row]] / float(1+row+col);
     std::cerr << "getPathCost(" << row << "," << col << "): out of bounds" << std::endl;
     throw "getPathCost index out of bounds";
 } // getPathCost()
 	
-int
+double
 Finder::getRawPathCost(int row, int col)
 {
     if (find(row, col))
@@ -159,43 +170,57 @@
 } // getRawPathCost()
 
 void
-Finder::setPathCost(int row, int col, int i)
+Finder::setPathCost(int row, int col, double cost)
 {
     if (find(row, col)) {
-         pm1->m_bestPathCost[row][col - pm1->m_first[row]] = i;
+         pm1->m_bestPathCost[row][col - pm1->m_first[row]] = cost;
          return;
     }
-    std::cerr << "setPathCost(" << row << "," << col << "," << i << "): out of bounds" << std::endl;
+    std::cerr << "setPathCost(" << row << "," << col << "," << cost << "): out of bounds" << std::endl;
     throw "setPathCost index out of bounds";
 } // setPathCost()
 
-unsigned char
+Matcher::Advance
+Finder::getAdvance()
+{
+    return pm1->m_advance[index1][index2];
+}
+
+void
+Finder::setAdvance(Matcher::Advance a)
+{
+    pm1->m_advance[index1][index2] = a;
+}
+
+float
 Finder::getDistance() 
 {
     return pm1->m_distance[index1][index2];
 } // getDistance()/0
 
 void
-Finder::setDistance(int b)
+Finder::setDistance(float b)
 {
-    pm1->m_distance[index1][index2] = (unsigned char)b;
+    pm1->m_distance[index1][index2] = b;
 } // setDistance()
 
-int
+double
 Finder::getPathCost()
 {
     return pm1->m_bestPathCost[index1][index2];
 } // getPathCost()
 
 void
-Finder::setPathCost(int i)
+Finder::setPathCost(double cost)
 {
-    pm1->m_bestPathCost[index1][index2] = i;
+    pm1->m_bestPathCost[index1][index2] = cost;
 } // setPathCost()
 
 void
 Finder::recalculatePathCostMatrix(int r1, int c1, int r2, int c2) 
 {
+    float diagonalWeight = sqrtf(2.f);
+    
     if (!find(r1,c1)) {
         std::cerr << "recalculatePathCostMatrix(" << r1 << "," << c1 << "): out of bounds" << std::endl;
         throw "recalculatePathCostMatrix index out of bounds";
@@ -209,31 +234,31 @@
         for (c = thisRowStart; c <= c2; c++) {
             if (find(r,c)) {
                 int i2 = index2;
-                int newCost = pm1->m_distance[r][i2];
-                int dir = 0;
+                float newCost = pm1->m_distance[r][i2];
+                Matcher::Advance dir = Matcher::AdvanceNone;
                 if (r > r1) {	// not first row
-                    int min = -1;
+                    double min = -1;
                     if ((c > prevRowStart) && (c <= prevRowStop)) {
                         // diagonal from (r-1,c-1)
                         min = pm1->m_bestPathCost[r-1][c-pm1->m_first[r-1]-1] +
-                            newCost * 2;
-                        dir = ADVANCE_BOTH;
+                            newCost * diagonalWeight;
+                        dir = Matcher::AdvanceBoth;
                     }
                     if ((c >= prevRowStart) && (c < prevRowStop)) {
                         // vertical from (r-1,c)
-                        int cost = pm1->m_bestPathCost[r-1][c-pm1->m_first[r-1]] +
+                        double cost = pm1->m_bestPathCost[r-1][c-pm1->m_first[r-1]] +
                             newCost;
                         if ((min == -1) || (cost < min)) {
                             min = cost;
-                            dir = ADVANCE_THIS;
+                            dir = Matcher::AdvanceThis;
                         }
                     }
                     if (c > thisRowStart) {
                         // horizontal from (r,c-1)
-                        int cost =pm1->m_bestPathCost[r][i2-1]+newCost;
+                        double cost =pm1->m_bestPathCost[r][i2-1]+newCost;
                         if ((min == -1) || (cost < min)) {
                             min = cost;
-                            dir = ADVANCE_OTHER;
+                            dir = Matcher::AdvanceOther;
                         }
                     }
                     pm1->m_bestPathCost[r][i2] = min;
@@ -241,12 +266,9 @@
                     // horizontal from (r,c-1)
                     pm1->m_bestPathCost[r][i2] = pm1->m_bestPathCost[r][i2-1] +
                         newCost;
-                    dir = ADVANCE_OTHER;
+                    dir = Matcher::AdvanceOther;
                 }
-                if ((r != r1) || (c != c1)) {
-                    pm1->m_distance[r][i2] = (unsigned char)
-                        ((pm1->m_distance[r][i2] & MASK) | dir);
-                }
+                pm1->m_advance[r][i2] = dir;
             } else
                 break;	// end of row
         }
@@ -280,21 +302,21 @@
         pathx.push_back(x);
         pathy.push_back(y);
 
-        switch (getDistance() & ADVANCE_BOTH) {
-        case ADVANCE_THIS:
+        switch (getAdvance()) {
+        case Matcher::AdvanceThis:
 //            cerr << ", going down (dist = " << (int)getDistance() << ")" << endl;
             y--;
             break;
-        case ADVANCE_OTHER:
+        case Matcher::AdvanceOther:
 //            cerr << ", going left (dist = " << (int)getDistance() << ")" << endl;
             x--;
             break;
-        case ADVANCE_BOTH:
+        case Matcher::AdvanceBoth:
 //            cerr << ", going diag (dist = " << (int)getDistance() << ")" << endl;
             x--;
             y--;
             break;
-        default: // this would indicate a bug, but we wouldn't want to hang
+        case Matcher::AdvanceNone: // this would indicate a bug, but we wouldn't want to hang
 //            cerr << "WARNING: Neither matcher advanced in path backtrack at (" << x << "," << y << ")" << endl;
             if (x > y) {
                 x--;
--- a/src/Finder.h	Fri Nov 14 13:53:58 2014 +0000
+++ b/src/Finder.h	Fri Nov 14 13:57:12 2014 +0000
@@ -67,21 +67,24 @@
      *  column. */
     void getRowRange(int col, int *range);
 
-    int getExpandDirection(int row, int col);
-    int getExpandDirection(int row, int col, bool check);
+    Matcher::Advance getExpandDirection(int row, int col);
+    Matcher::Advance getExpandDirection(int row, int col, bool check);
 	
-    unsigned char getDistance(int row, int col);
-    void setDistance(int row, int col, unsigned char b);
+    float getDistance(int row, int col);
+    void setDistance(int row, int col, float b);
 
-    int getPathCost(int row, int col);
-    int getRawPathCost(int row, int col);
-    void setPathCost(int row, int col, int i);
+    double getPathCost(int row, int col);
+    double getRawPathCost(int row, int col); //!!!???
+    void setPathCost(int row, int col, double i);
 
-    unsigned char getDistance();
-    void setDistance(int b);
+    Matcher::Advance getAdvance();
+    void setAdvance(Matcher::Advance a);
+    
+    float getDistance();
+    void setDistance(float b);
 
-    int getPathCost();
-    void setPathCost(int i);
+    double getPathCost();
+    void setPathCost(double i);
 
     /** Calculates a rectangle of the path cost matrix so that the
      *  minimum cost path between the bottom left and top right
--- a/src/MatchFeatureFeeder.cpp	Fri Nov 14 13:53:58 2014 +0000
+++ b/src/MatchFeatureFeeder.cpp	Fri Nov 14 13:57:12 2014 +0000
@@ -68,16 +68,19 @@
     } else {
         switch (finder->getExpandDirection
                 (pm1->m_frameCount-1, pm2->m_frameCount-1)) {
-        case ADVANCE_THIS:
+        case Matcher::AdvanceThis:
             feed1();
             break;
-        case ADVANCE_OTHER:
+        case Matcher::AdvanceOther:
             feed2();
             break;
-        case ADVANCE_BOTH:
+        case Matcher::AdvanceBoth:
             feed1();
             feed2();
             break;
+        case Matcher::AdvanceNone:
+            cerr << "finder says AdvanceNone!" << endl;
+            break;
         }
     }
 }
--- a/src/MatchFeeder.cpp	Fri Nov 14 13:53:58 2014 +0000
+++ b/src/MatchFeeder.cpp	Fri Nov 14 13:57:12 2014 +0000
@@ -78,7 +78,7 @@
 void
 MatchFeeder::prepare(const float *const *input)
 {
-    float threshold = 1e-5;
+    float threshold = 1e-5f;
     
     float *block = new float[fftSize+2];
     float rms = 0;
@@ -133,19 +133,19 @@
     } else {
         switch (finder->getExpandDirection
                 (pm1->m_frameCount-1, pm2->m_frameCount-1)) {
-        case ADVANCE_THIS:
-//            std::cerr << "finder says ADVANCE_THIS" << std::endl;
+        case Matcher::AdvanceThis:
             f1 = feed1();
             break;
-        case ADVANCE_OTHER:
-//            std::cerr << "finder says ADVANCE_OTHER" << std::endl;
+        case Matcher::AdvanceOther:
             f2 = feed2();
             break;
-        case ADVANCE_BOTH:
-//            std::cerr << "finder says ADVANCE_BOTH" << std::endl;
+        case Matcher::AdvanceBoth:
             f1 = feed1();
             f2 = feed2();
             break;
+        case Matcher::AdvanceNone:
+            cerr << "finder says AdvanceNone!" << endl;
+            break;
         }
     }
 
--- a/src/MatchVampPlugin.cpp	Fri Nov 14 13:53:58 2014 +0000
+++ b/src/MatchVampPlugin.cpp	Fri Nov 14 13:57:12 2014 +0000
@@ -45,11 +45,11 @@
 // sample rates
 static float sampleRateMin = 5000.f;
 
-static float defaultStepTime = 0.020;
+static float defaultStepTime = 0.020f;
 
 MatchVampPlugin::MatchVampPlugin(float inputSampleRate) :
     Plugin(inputSampleRate),
-    m_stepSize(inputSampleRate * defaultStepTime + 0.001),
+    m_stepSize(int(inputSampleRate * defaultStepTime + 0.001)),
     m_stepTime(defaultStepTime),
     m_blockSize(2048),
     m_serialise(false),
@@ -219,7 +219,7 @@
     desc.description = "Width of the search zone (error margin) either side of the ongoing match position, in seconds";
     desc.minValue = 1;
     desc.maxValue = 60;
-    desc.defaultValue = m_defaultParams.blockTime;
+    desc.defaultValue = (float)m_defaultParams.blockTime;
     desc.isQuantized = true;
     desc.quantizeStep = 1;
     desc.unit = "s";
@@ -255,7 +255,7 @@
     } else if (name == "gradientlimit") {
         return m_params.maxRunCount;
     } else if (name == "zonewidth") {
-        return m_params.blockTime;
+        return (float)m_params.blockTime;
     } else if (name == "smooth") {
         return m_smooth ? 1.0 : 0.0;
     }
@@ -288,7 +288,7 @@
 size_t
 MatchVampPlugin::getPreferredStepSize() const
 {
-    return m_inputSampleRate * defaultStepTime;
+    return int(m_inputSampleRate * defaultStepTime + 0.001);
 }
 
 size_t
@@ -354,7 +354,7 @@
 {
     OutputList list;
 
-    float outRate = 1.0 / m_stepTime;
+    float outRate = 1.0f / m_stepTime;
 
     OutputDescriptor desc;
     desc.identifier = "path";
@@ -483,7 +483,7 @@
     for (int i = 0; i < (int)ff.f1.size(); ++i) {
         f.values.clear();
         for (int j = 0; j < (int)ff.f1[i].size(); ++j) {
-            f.values.push_back(ff.f1[i][j]);
+            f.values.push_back(float(ff.f1[i][j]));
         }
         returnFeatures[m_aFeaturesOutNo].push_back(f);
     }
@@ -491,7 +491,7 @@
     for (int i = 0; i < (int)ff.f2.size(); ++i) {
         f.values.clear();
         for (int j = 0; j < (int)ff.f2[i].size(); ++j) {
-            f.values.push_back(ff.f2[i][j]);
+            f.values.push_back(float(ff.f2[i][j]));
         }
         returnFeatures[m_bFeaturesOutNo].push_back(f);
     }
@@ -529,7 +529,7 @@
         feature.hasTimestamp = true;
         feature.timestamp = m_startTime + xt;
         feature.values.clear();
-        feature.values.push_back(yt.sec + double(yt.nsec)/1.0e9);
+        feature.values.push_back(float(yt.sec + double(yt.nsec)/1.0e9));
         returnFeatures[m_pathOutNo].push_back(feature);
         
         if (x != prevx) {
@@ -537,12 +537,12 @@
             feature.hasTimestamp = true;
             feature.timestamp = m_startTime + xt;
             feature.values.clear();
-            feature.values.push_back(yt.sec + yt.msec()/1000.0);
+            feature.values.push_back(float(yt.sec + yt.msec()/1000.0));
             returnFeatures[m_abOutNo].push_back(feature);
 
             Vamp::RealTime diff = yt - xt;
             feature.values.clear();
-            feature.values.push_back(diff.sec + diff.msec()/1000.0);
+            feature.values.push_back(float(diff.sec + diff.msec()/1000.0));
             returnFeatures[m_abDivOutNo].push_back(feature);
 
             if (i > 0) {
@@ -565,7 +565,7 @@
             feature.hasTimestamp = true;
             feature.timestamp = m_startTime + yt;
             feature.values.clear();
-            feature.values.push_back(xt.sec + xt.msec()/1000.0);
+            feature.values.push_back(float(xt.sec + xt.msec()/1000.0));
             returnFeatures[m_baOutNo].push_back(feature);
         }
 
--- a/src/Matcher.cpp	Fri Nov 14 13:53:58 2014 +0000
+++ b/src/Matcher.cpp	Fri Nov 14 13:57:12 2014 +0000
@@ -89,6 +89,7 @@
         (m_blockSize, vector<double>(m_featureSize, 0));
 
     m_distXSize = m_blockSize * 2;
+
     size();
 
     m_frameCount = 0;
@@ -101,8 +102,9 @@
 Matcher::size()
 {
     int distSize = (m_params.maxRunCount + 1) * m_blockSize;
-    m_bestPathCost.resize(m_distXSize, vector<int>(distSize, 0));
-    m_distance.resize(m_distXSize, vector<unsigned char>(distSize, 0));
+    m_bestPathCost.resize(m_distXSize, vector<double>(distSize, 0));
+    m_distance.resize(m_distXSize, vector<float>(distSize, 0));
+    m_advance.resize(m_distXSize, vector<Advance>(distSize, AdvanceNone));
     m_distYSizes.resize(m_distXSize, distSize);
     m_first.resize(m_distXSize, 0);
     m_last.resize(m_distXSize, 0);
@@ -158,18 +160,13 @@
 */
         m_distance[m_frameCount] = m_distance[m_frameCount - m_blockSize];
         m_distance[m_frameCount - m_blockSize].resize(len, 0);
-        for (int i = 0; i < len; ++i) {
-            m_distance[m_frameCount - m_blockSize][i] =
-                m_distance[m_frameCount][i];
-        }
 
         m_bestPathCost[m_frameCount] = m_bestPathCost[m_frameCount - m_blockSize];
         m_bestPathCost[m_frameCount - m_blockSize].resize(len, 0);
-        for (int i = 0; i < len; ++i) {
-            m_bestPathCost[m_frameCount - m_blockSize][i] =
-                m_bestPathCost[m_frameCount][i];
-        }
 
+        m_advance[m_frameCount] = m_advance[m_frameCount - m_blockSize];
+        m_advance[m_frameCount - m_blockSize].resize(len, AdvanceNone);
+        
         m_distYSizes[m_frameCount] = m_distYSizes[m_frameCount - m_blockSize];
         m_distYSizes[m_frameCount - m_blockSize] = len;
     }
@@ -181,15 +178,13 @@
     m_first[m_frameCount] = index;
     m_last[m_frameCount] = stop;
 
-    bool overflow = false;
-    int mn= -1;
-    int mx= -1;
+    float mn= -1;
+    float mx= -1;
     for ( ; index < stop; index++) {
 
-        int dMN = m_metric.calcDistanceScaled
+        float dMN = (float) m_metric.calcDistance
             (m_frames[frameIndex],
-             m_otherMatcher->m_frames[index % m_blockSize],
-             m_params.distanceScale);
+             m_otherMatcher->m_frames[index % m_blockSize]);
         
         if (mx<0)
             mx = mn = dMN;
@@ -197,49 +192,45 @@
             mx = dMN;
         else if (dMN < mn)
             mn = dMN;
-        if (dMN >= 255) {
-            overflow = true;
-            dMN = 255;
-        }
 
         if ((m_frameCount == 0) && (index == 0))    // first element
-            setValue(0, 0, 0, 0, dMN);
+            setValue(0, 0, AdvanceNone, 0, dMN);
         else if (m_frameCount == 0)                 // first row
-            setValue(0, index, ADVANCE_OTHER,
+            setValue(0, index, AdvanceOther,
                      getValue(0, index-1, true), dMN);
         else if (index == 0)                      // first column
-            setValue(m_frameCount, index, ADVANCE_THIS,
+            setValue(m_frameCount, index, AdvanceThis,
                      getValue(m_frameCount - 1, 0, true), dMN);
         else if (index == m_otherMatcher->m_frameCount - m_blockSize) {
             // missing value(s) due to cutoff
             //  - no previous value in current row (resp. column)
             //  - no diagonal value if prev. dir. == curr. dirn
-            int min2 = getValue(m_frameCount - 1, index, true);
+            double min2 = getValue(m_frameCount - 1, index, true);
             //	if ((m_firstPM && (first[m_frameCount - 1] == index)) ||
             //			(!m_firstPM && (m_last[index-1] < m_frameCount)))
             if (m_first[m_frameCount - 1] == index)
-                setValue(m_frameCount, index, ADVANCE_THIS, min2, dMN);
+                setValue(m_frameCount, index, AdvanceThis, min2, dMN);
             else {
-                int min1 = getValue(m_frameCount - 1, index - 1, true);
+                double min1 = getValue(m_frameCount - 1, index - 1, true);
                 if (min1 + dMN <= min2)
-                    setValue(m_frameCount, index, ADVANCE_BOTH, min1,dMN);
+                    setValue(m_frameCount, index, AdvanceBoth, min1,dMN);
                 else
-                    setValue(m_frameCount, index, ADVANCE_THIS, min2,dMN);
+                    setValue(m_frameCount, index, AdvanceThis, min2,dMN);
             }
         } else {
-            int min1 = getValue(m_frameCount, index-1, true);
-            int min2 = getValue(m_frameCount - 1, index, true);
-            int min3 = getValue(m_frameCount - 1, index-1, true);
+            double min1 = getValue(m_frameCount, index-1, true);
+            double min2 = getValue(m_frameCount - 1, index, true);
+            double min3 = getValue(m_frameCount - 1, index-1, true);
             if (min1 <= min2) {
                 if (min3 + dMN <= min1)
-                    setValue(m_frameCount, index, ADVANCE_BOTH, min3,dMN);
+                    setValue(m_frameCount, index, AdvanceBoth, min3,dMN);
                 else
-                    setValue(m_frameCount, index, ADVANCE_OTHER,min1,dMN);
+                    setValue(m_frameCount, index, AdvanceOther,min1,dMN);
             } else {
                 if (min3 + dMN <= min2)
-                    setValue(m_frameCount, index, ADVANCE_BOTH, min3,dMN);
+                    setValue(m_frameCount, index, AdvanceBoth, min3,dMN);
                 else
-                    setValue(m_frameCount, index, ADVANCE_THIS, min2,dMN);
+                    setValue(m_frameCount, index, AdvanceThis, min2,dMN);
             }
         }
         m_otherMatcher->m_last[index]++;
@@ -249,14 +240,9 @@
     m_runCount++;
 
     m_otherMatcher->m_runCount = 0;
-
-    if (overflow) {
-        cerr << "WARNING: overflow in distance metric: "
-             << "frame " << m_frameCount << ", val = " << mx << endl;
-    }
 }
 
-int
+double
 Matcher::getValue(int i, int j, bool firstAttempt)
 {
     if (m_firstPM)
@@ -266,18 +252,31 @@
 } // getValue()
 
 void
-Matcher::setValue(int i, int j, int dir, int value, int dMN)
+Matcher::setValue(int i, int j, Advance dir, double value, float dMN)
 {
+    float diagonalWeight = sqrtf(2.f);
+    
+    if (dir == AdvanceBoth) {
+        dMN *= diagonalWeight;
+    }
+    
     if (m_firstPM) {
-        m_distance[i][j - m_first[i]] = (unsigned char)((dMN & MASK) | dir);
-        m_bestPathCost[i][j - m_first[i]] =
-            (value + (dir==ADVANCE_BOTH? dMN*2: dMN));
+
+        int jdx = j - m_first[i];
+        m_distance[i][jdx] = dMN;
+        m_advance[i][jdx] = dir;
+        m_bestPathCost[i][jdx] = value + dMN;
+
     } else {
-        if (dir == ADVANCE_THIS)
-            dir = ADVANCE_OTHER;
-        else if (dir == ADVANCE_OTHER)
-            dir = ADVANCE_THIS;
+
+        if (dir == AdvanceThis) {
+            dir = AdvanceOther;
+        } else if (dir == AdvanceOther) {
+            dir = AdvanceThis;
+        }
+
         int idx = i - m_otherMatcher->m_first[j];
+        
         if (idx == (int)m_otherMatcher->m_distYSizes[j]) {
             // This should never happen, but if we allow arbitrary
             // pauses in either direction, and arbitrary lengths at
@@ -286,10 +285,12 @@
             m_otherMatcher->m_distYSizes[j] = idx * 2;
             m_otherMatcher->m_bestPathCost[j].resize(idx * 2, 0);
             m_otherMatcher->m_distance[j].resize(idx * 2, 0);
+            m_otherMatcher->m_advance[j].resize(idx * 2, AdvanceNone);
         }
-        m_otherMatcher->m_distance[j][idx] = (unsigned char)((dMN & MASK) | dir);
-        m_otherMatcher->m_bestPathCost[j][idx] =
-            (value + (dir==ADVANCE_BOTH? dMN*2: dMN));
+
+        m_otherMatcher->m_distance[j][idx] = dMN;
+        m_otherMatcher->m_advance[j][idx] = dir;
+        m_otherMatcher->m_bestPathCost[j][idx] = value + dMN;
     }
 } // setValue()
 
--- a/src/Matcher.h	Fri Nov 14 13:53:58 2014 +0000
+++ b/src/Matcher.h	Fri Nov 14 13:57:12 2014 +0000
@@ -22,11 +22,6 @@
 #include <sstream>
 #include <cmath>
 
-#define ADVANCE_THIS 1
-#define ADVANCE_OTHER 2
-#define ADVANCE_BOTH 3
-#define MASK 0xfc
-
 #include "DistanceMetric.h"
 #include "FeatureExtractor.h"
 
@@ -37,19 +32,23 @@
 
 /** Represents an audio stream that can be matched to another audio
  *  stream of the same piece of music.  The matching algorithm uses
- *  dynamic time warping.  The distance metric is a Euclidean metric
- *  on the FFT data with the higher frequencies mapped onto a linear
- *  scale.
+ *  dynamic time warping.
  */
 class Matcher
 {
 public:
+    enum Advance {
+        AdvanceNone,
+        AdvanceBoth,
+        AdvanceThis,
+        AdvanceOther
+    };
+
     struct Parameters {
 
         Parameters(float rate_, double hopTime_, int fftSize_) :
             sampleRate(rate_),
             distanceNorm(DistanceMetric::NormaliseDistanceToLogSum),
-            distanceScale(90.0),
             hopTime(hopTime_),
             fftSize(fftSize_),
             blockTime(10.0),
@@ -62,12 +61,6 @@
         /** Type of distance metric normalisation */
         DistanceMetric::DistanceNormalisation distanceNorm;
 
-        /** Scaling factor for distance metric; must guarantee that the
-         *  final value fits in the data type used, that is, unsigned
-         *  char.
-         */
-        double distanceScale;
-
         /** Spacing of audio frames (determines the amount of overlap or
          *  skip between frames). This value is expressed in
          *  seconds. */
@@ -175,7 +168,7 @@
      *  @param j the frame number of the other Matcher
      *  @return the cost of the minimum cost path to this location
      */
-    int getValue(int i, int j, bool firstAttempt);
+    double getValue(int i, int j, bool firstAttempt);
 
     /** Stores entries in the distance matrix and the optimal path matrix.
      *
@@ -186,7 +179,7 @@
      *  @param value the cost of the minimum path except the current step
      *  @param dMN the distance cost between the two frames
      */
-    void setValue(int i, int j, int dir, int value, int dMN);
+    void setValue(int i, int j, Advance dir, double value, float dMN);
 
     void calcAdvance();
 
@@ -228,19 +221,25 @@
     vector<vector<double> > m_frames;
 
     /** The best path cost matrix. */
-    vector<vector<int> > m_bestPathCost;
+    vector<vector<double> > m_bestPathCost;
 
     /** The distance matrix. */
-    vector<vector<unsigned char> > m_distance;
+    vector<vector<float> > m_distance;
 
-    /** The bounds of each row of data in the distance and path cost matrices.*/
+    /** The advance direction matrix. */
+    vector<vector<Advance> > m_advance;
+
+    /** The bounds of each row of data in the distance, path cost, and
+     * advance direction matrices.*/
     vector<int> m_first;
     vector<int> m_last;
 
-    /** Height of each column in distance and bestPathCost matrices */
+    /** Height of each column in distance, path cost, and advance
+     * direction matrices. */
     vector<int> m_distYSizes;
 
-    /** Width of distance and bestPathCost matrices and first and last vectors */
+    /** Width of distance, path cost, and advance direction matrices
+     * and first and last vectors */
     int m_distXSize;
 
     bool m_initialised;