changeset 188:487261a22b18 re-minimise

distance_t * diagonalWeight might not fit in distance_t; use pathcost_t for it. Also remove C-style casts.
author Chris Cannam
date Thu, 26 Feb 2015 12:19:17 +0000
parents ba0d2104abec
children d4b3b5c2cb58
files Makefile.linux src/FeatureExtractor.cpp src/Finder.cpp src/MatchTypes.h src/MatchVampPlugin.cpp src/Matcher.cpp src/Matcher.h src/Path.cpp src/Path.h test/TestFeatureExtractor.cpp
diffstat 10 files changed, 173 insertions(+), 141 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.linux	Thu Feb 26 10:48:36 2015 +0000
+++ b/Makefile.linux	Thu Feb 26 12:19:17 2015 +0000
@@ -1,5 +1,6 @@
 
-CXXFLAGS	+= -fPIC -ffast-math -O3 -Wall -Werror -Wconversion -std=c++11
+CXXFLAGS	+= -fPIC -ffast-math -O3 -Wall -Werror -Werror=old-style-cast -Wconversion -std=c++11 -DUSE_COMPACT_TYPES -DPERFORM_ERROR_CHECKS=1
+
 #CXXFLAGS	+= -fPIC -g -Wall -Werror -Wconversion -DPERFORM_ERROR_CHECKS=1 -std=c++11
 
 LDFLAGS		+= -Wl,-Bstatic -lvamp-sdk -Wl,-Bdynamic
--- a/src/FeatureExtractor.cpp	Thu Feb 26 10:48:36 2015 +0000
+++ b/src/FeatureExtractor.cpp	Thu Feb 26 12:19:17 2015 +0000
@@ -89,7 +89,7 @@
     
     double refFreq = 440.; // See above -- *not* the parameter!
     double binWidth = double(m_params.sampleRate) / m_params.fftSize;
-    int crossoverBin = (int)(2 / (pow(2, 1/12.0) - 1));
+    int crossoverBin = int(2 / (pow(2, 1/12.0) - 1));
     int crossoverMidi = int(log(crossoverBin * binWidth / refFreq)/
                             log(2.0) * 12 + 69 + 0.5);
 
@@ -133,7 +133,7 @@
 {
     double refFreq = m_params.referenceFrequency;
     double binWidth = double(m_params.sampleRate) / m_params.fftSize;
-    int crossoverBin = (int)(1 / (pow(2, 1/12.0) - 1));
+    int crossoverBin = int(1 / (pow(2, 1/12.0) - 1));
     int i = 0;
     while (i <= crossoverBin) {
         double freq = i * binWidth;
--- a/src/Finder.cpp	Thu Feb 26 10:48:36 2015 +0000
+++ b/src/Finder.cpp	Thu Feb 26 12:19:17 2015 +0000
@@ -172,8 +172,6 @@
 {
     int prevRowStart = 0, prevRowStop = 0;
 
-    float diagonalWeight = m_m->getDiagonalWeight();
-    
     for (int r = r1; r <= r2; r++) {
 
         pair<int, int> colRange = m_m->getColRange(r);
@@ -183,20 +181,21 @@
         
         for (int c = rowStart; c < rowStop; c++) {
 
-            distance_t newStep = m_m->getDistance(r, c);
             advance_t dir = AdvanceNone;
+            pathcost_t straightIncrement = m_m->getDistance(r, c);
+            pathcost_t diagIncrement = pathcost_t(straightIncrement *
+                                                  m_m->getDiagonalWeight());
 
             if (r > r1) {	// not first row
                 pathcost_t min = -1;
                 if ((c > prevRowStart) && (c <= prevRowStop)) {
                     // diagonal from (r-1,c-1)
-                    min = m_m->getPathCost(r-1, c-1) +
-                        distance_t(newStep * diagonalWeight);
+                    min = m_m->getPathCost(r-1, c-1) + diagIncrement;
                     dir = AdvanceBoth;
                 }
                 if ((c >= prevRowStart) && (c < prevRowStop)) {
                     // vertical from (r-1,c)
-                    pathcost_t cost = m_m->getPathCost(r-1, c) + newStep;
+                    pathcost_t cost = m_m->getPathCost(r-1, c) + straightIncrement;
                     if ((min < 0) || (cost < min)) {
                         min = cost;
                         dir = AdvanceThis;
@@ -204,7 +203,7 @@
                 }
                 if (c > rowStart) {
                     // horizontal from (r,c-1)
-                    pathcost_t cost = m_m->getPathCost(r, c-1) + newStep;
+                    pathcost_t cost = m_m->getPathCost(r, c-1) + straightIncrement;
                     if ((min < 0) || (cost < min)) {
                         min = cost;
                         dir = AdvanceOther;
@@ -216,7 +215,7 @@
             } else if (c > rowStart) {	// first row
                 // horizontal from (r,c-1)
                 m_m->setPathCost(r, c, AdvanceOther,
-                                   m_m->getPathCost(r, c-1) + newStep);
+                                 m_m->getPathCost(r, c-1) + straightIncrement);
             }
         }
 
@@ -242,8 +241,6 @@
 
     int prevRowStart = 0, prevRowStop = 0;
 
-    float diagonalWeight = m_m->getDiagonalWeight();
-    
     for (int r = r1; r <= r2; r++) {
 
         pair<int, int> colRange = m_m->getColRange(r);
@@ -253,36 +250,36 @@
         
         for (int c = rowStart; c < rowStop; c++) {
 
-            distance_t newStep = m_m->getDistance(r, c);
+            advance_t dir = AdvanceNone;
             pathcost_t updateTo = InvalidPathCost;
-            advance_t dir = AdvanceNone;
+            distance_t distance = m_m->getDistance(r, c);
+            pathcost_t straightIncrement = distance;
+            pathcost_t diagIncrement = pathcost_t(distance * m_m->getDiagonalWeight());
+            err.distance = distance;
 
             if (r > r1) { // not first row
                 pathcost_t min = -1;
                 if ((c > prevRowStart) && (c <= prevRowStop)) {
                     // diagonal from (r-1,c-1)
-                    min = m_m->getPathCost(r-1, c-1) + distance_t(newStep * diagonalWeight);
+                    min = m_m->getPathCost(r-1, c-1) + diagIncrement;
                     err.prevCost = m_m->getPathCost(r-1, c-1);
-                    err.distance = distance_t(newStep * diagonalWeight);
                     dir = AdvanceBoth;
                 }
                 if ((c >= prevRowStart) && (c < prevRowStop)) {
                     // vertical from (r-1,c)
-                    pathcost_t cost = m_m->getPathCost(r-1, c) + newStep;
+                    pathcost_t cost = m_m->getPathCost(r-1, c) + straightIncrement;
                     if ((min < 0) || (cost < min)) {
                         min = cost;
                         err.prevCost = m_m->getPathCost(r-1, c);
-                        err.distance = newStep;
                         dir = AdvanceThis;
                     }
                 }
                 if (c > rowStart) {
                     // horizontal from (r,c-1)
-                    pathcost_t cost = m_m->getPathCost(r, c-1) + newStep;
+                    pathcost_t cost = m_m->getPathCost(r, c-1) + straightIncrement;
                     if ((min < 0) || (cost < min)) {
                         min = cost;
                         err.prevCost = m_m->getPathCost(r, c-1);
-                        err.distance = newStep;
                         dir = AdvanceOther;
                     }
                 }
@@ -293,9 +290,8 @@
 
                 if (c > rowStart) {
                     // horizontal from (r,c-1)
-                    updateTo = m_m->getPathCost(r, c-1) + newStep;
+                    updateTo = m_m->getPathCost(r, c-1) + straightIncrement;
                     err.prevCost = m_m->getPathCost(r, c-1);
-                    err.distance = newStep;
                     dir = AdvanceOther;
                 }
             }
@@ -366,7 +362,7 @@
              << ", advance in matrix is "
              << Matcher::advanceToString(err.advanceWas)
              << "\nPrev cost " << err.prevCost
-             << " plus distance " << err.distance << " gives "
+             << " plus distance " << err.distance << " [perhaps diagonalised] gives "
              << err.costShouldBe << ", matrix contains " << err.costWas
              << endl;
         cerr << "Note: diagonal weight = " << m_m->getDiagonalWeight() << endl;
--- a/src/MatchTypes.h	Thu Feb 26 10:48:36 2015 +0000
+++ b/src/MatchTypes.h	Thu Feb 26 12:19:17 2015 +0000
@@ -19,36 +19,22 @@
 #include <vector>
 #include <cstdint>
 
+#ifdef USE_COMPACT_TYPES
+
 /// A single value in a feature vector
 typedef float featurebin_t;
 
-/// A feature vector
-typedef std::vector<featurebin_t> feature_t;
-
-/// A sequence of feature vectors
-typedef std::vector<feature_t> featureseq_t;
-
 /// The distance between two feature vectors
 typedef uint8_t distance_t;
 
+const int MaxDistance = 0xfe;
 const int InvalidDistance = 0xff;
 
-/// A distance vector
-typedef std::vector<distance_t> distancevec_t;
-
-/// A distance matrix
-typedef std::vector<distancevec_t> distancemat_t;
-
 /// The integrated distance (path cost) from the origin to a given point
 typedef uint32_t pathcost_t;
 
-const int InvalidPathCost = 0xdeadbeef;
-
-/// A vector of path costs
-typedef std::vector<pathcost_t> pathcostvec_t;
-
-/// A matrix of path costs
-typedef std::vector<pathcostvec_t> pathcostmat_t;
+const int MaxPathCost = 0xfffffffe;
+const int InvalidPathCost = 0xffffffff;
 
 /// A direction advance instruction or state
 enum advance_t : uint8_t {
@@ -58,6 +44,56 @@
     AdvanceOther
 };
 
+#else
+
+#ifndef USE_PRECISE_TYPES
+#error You must define either USE_COMPACT_TYPES or USE_PRECISE_TYPES
+#endif
+
+/// A single value in a feature vector
+typedef double featurebin_t;
+
+/// The distance between two feature vectors
+typedef float distance_t;
+
+const float MaxDistance = FLOAT_MAX;
+const float InvalidDistance = -1.f;
+
+/// The integrated distance (path cost) from the origin to a given point
+typedef double pathcost_t;
+
+const double MaxPathCost = DOUBLE_MAX;
+const double InvalidPathCost = -1.;
+
+/// A direction advance instruction or state
+enum advance_t {
+    AdvanceNone,
+    AdvanceBoth,
+    AdvanceThis,
+    AdvanceOther
+};
+
+#endif
+
+
+/// A feature vector
+typedef std::vector<featurebin_t> feature_t;
+
+/// A sequence of feature vectors
+typedef std::vector<feature_t> featureseq_t;
+
+/// A distance vector
+typedef std::vector<distance_t> distancevec_t;
+
+/// A distance matrix
+typedef std::vector<distancevec_t> distancemat_t;
+
+/// A vector of path costs
+typedef std::vector<pathcost_t> pathcostvec_t;
+
+/// A matrix of path costs
+typedef std::vector<pathcostvec_t> pathcostmat_t;
+
 /// A vector of advance directions
 typedef std::vector<advance_t> advancevec_t;
 
--- a/src/MatchVampPlugin.cpp	Thu Feb 26 10:48:36 2015 +0000
+++ b/src/MatchVampPlugin.cpp	Thu Feb 26 12:19:17 2015 +0000
@@ -152,7 +152,7 @@
     desc.description = "Tuning frequency (concert A) for the reference audio.";
     desc.minValue = 220.0;
     desc.maxValue = 880.0;
-    desc.defaultValue = (float)m_defaultFeParams.referenceFrequency;
+    desc.defaultValue = float(m_defaultFeParams.referenceFrequency);
     desc.isQuantized = false;
     desc.unit = "Hz";
     list.push_back(desc);
@@ -162,7 +162,7 @@
     desc.description = "Tuning frequency (concert A) for the other audio.";
     desc.minValue = 220.0;
     desc.maxValue = 880.0;
-    desc.defaultValue = (float)m_defaultFeParams.referenceFrequency;
+    desc.defaultValue = float(m_defaultFeParams.referenceFrequency);
     desc.isQuantized = false;
     desc.unit = "Hz";
     list.push_back(desc);
@@ -171,8 +171,8 @@
     desc.name = "Minimum frequency";
     desc.description = "Minimum frequency to include in features.";
     desc.minValue = 0.0;
-    desc.maxValue = (float)m_inputSampleRate / 4.f;
-    desc.defaultValue = (float)m_defaultFeParams.minFrequency;
+    desc.maxValue = float(m_inputSampleRate / 4.f);
+    desc.defaultValue = float(m_defaultFeParams.minFrequency);
     desc.isQuantized = false;
     desc.unit = "Hz";
     list.push_back(desc);
@@ -181,8 +181,8 @@
     desc.name = "Maximum frequency";
     desc.description = "Maximum frequency to include in features.";
     desc.minValue = 1000.0;
-    desc.maxValue = (float)m_inputSampleRate / 2.f;
-    desc.defaultValue = (float)m_defaultFeParams.maxFrequency;
+    desc.maxValue = float(m_inputSampleRate / 2.f);
+    desc.defaultValue = float(m_defaultFeParams.maxFrequency);
     desc.isQuantized = false;
     desc.unit = "Hz";
     list.push_back(desc);
@@ -209,7 +209,7 @@
     desc.description = "Whether to use half-wave rectified feature-to-feature difference instead of straight spectral or chroma feature";
     desc.minValue = 0;
     desc.maxValue = 1;
-    desc.defaultValue = (float)m_defaultFcParams.order;
+    desc.defaultValue = float(m_defaultFcParams.order);
     desc.isQuantized = true;
     desc.quantizeStep = 1;
     list.push_back(desc);
@@ -219,7 +219,7 @@
     desc.description = "Type of normalisation to use for features";
     desc.minValue = 0;
     desc.maxValue = 2;
-    desc.defaultValue = (float)m_defaultFcParams.norm;
+    desc.defaultValue = float(m_defaultFcParams.norm);
     desc.isQuantized = true;
     desc.quantizeStep = 1;
     desc.valueNames.clear();
@@ -228,14 +228,14 @@
     desc.valueNames.push_back("Long-term average");
     list.push_back(desc);
     desc.valueNames.clear();
-    desc.defaultValue = (float)m_defaultFcParams.silenceThreshold;
+    desc.defaultValue = float(m_defaultFcParams.silenceThreshold);
 
     desc.identifier = "metric";
     desc.name = "Distance metric";
     desc.description = "Metric for distance calculations.";
     desc.minValue = 0;
     desc.maxValue = 2;
-    desc.defaultValue = (float)m_defaultDParams.metric;
+    desc.defaultValue = float(m_defaultDParams.metric);
     desc.isQuantized = true;
     desc.quantizeStep = 1;
     desc.valueNames.clear();
@@ -250,7 +250,7 @@
     desc.description = "Type of normalisation to use for distance metric";
     desc.minValue = 0;
     desc.maxValue = 2;
-    desc.defaultValue = (float)m_defaultDParams.norm;
+    desc.defaultValue = float(m_defaultDParams.norm);
     desc.isQuantized = true;
     desc.quantizeStep = 1;
     desc.valueNames.clear();
@@ -265,7 +265,7 @@
     desc.description = "Total frame energy threshold below which a feature will be regarded as silent";
     desc.minValue = 0;
     desc.maxValue = 0.1f;
-    desc.defaultValue = (float)m_defaultFcParams.silenceThreshold;
+    desc.defaultValue = float(m_defaultFcParams.silenceThreshold);
     desc.isQuantized = false;
     list.push_back(desc);
 
@@ -274,7 +274,7 @@
     desc.description = "Whether to mix in a small constant white noise term when calculating feature distance. This can improve alignment against sources containing cleanly synthesised audio.";
     desc.minValue = 0;
     desc.maxValue = 1;
-    desc.defaultValue = (float)m_defaultDParams.noise;
+    desc.defaultValue = float(m_defaultDParams.noise);
     desc.isQuantized = true;
     desc.quantizeStep = 1;
     list.push_back(desc);
@@ -284,7 +284,7 @@
     desc.description = "Limit of number of frames that will be accepted from one source without a frame from the other source being accepted";
     desc.minValue = 1;
     desc.maxValue = 10;
-    desc.defaultValue = (float)m_defaultParams.maxRunCount;
+    desc.defaultValue = float(m_defaultParams.maxRunCount);
     desc.isQuantized = true;
     desc.quantizeStep = 1;
     list.push_back(desc);
@@ -294,7 +294,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 = (float)m_defaultParams.blockTime;
+    desc.defaultValue = float(m_defaultParams.blockTime);
     desc.isQuantized = true;
     desc.quantizeStep = 1;
     desc.unit = "s";
@@ -305,7 +305,7 @@
     desc.description = "Weight applied to cost of diagonal step relative to horizontal or vertical step. The default of 2.0 is good for gross tracking of quite different performances; closer to 1.0 produces a smoother path for performances more similar in tempo";
     desc.minValue = 1.0;
     desc.maxValue = 2.0;
-    desc.defaultValue = (float)m_defaultParams.diagonalWeight;
+    desc.defaultValue = float(m_defaultParams.diagonalWeight);
     desc.isQuantized = false;
     desc.unit = "";
     list.push_back(desc);
@@ -340,35 +340,35 @@
     if (name == "serialise") {
         return m_serialise ? 1.0 : 0.0; 
     } else if (name == "framenorm") {
-        return (float)m_fcParams.norm;
+        return float(m_fcParams.norm);
     } else if (name == "distnorm") {
-        return (float)m_dParams.norm;
+        return float(m_dParams.norm);
     } else if (name == "usespecdiff") {
-        return (float)m_fcParams.order;
+        return float(m_fcParams.order);
     } else if (name == "usechroma") {
         return m_feParams.useChromaFrequencyMap ? 1.0 : 0.0;
     } else if (name == "gradientlimit") {
-        return (float)m_params.maxRunCount;
+        return float(m_params.maxRunCount);
     } else if (name == "diagonalweight") {
-        return m_params.diagonalWeight;
+        return float(m_params.diagonalWeight);
     } else if (name == "zonewidth") {
-        return (float)m_params.blockTime;
+        return float(m_params.blockTime);
     } else if (name == "smooth") {
         return m_smooth ? 1.0 : 0.0;
     } else if (name == "silencethreshold") {
-        return (float)m_fcParams.silenceThreshold;
+        return float(m_fcParams.silenceThreshold);
     } else if (name == "metric") {
-        return (float)m_dParams.metric;
+        return float(m_dParams.metric);
     } else if (name == "noise") {
         return m_dParams.noise;
     } else if (name == "freq1") {
-        return (float)m_feParams.referenceFrequency;
+        return float(m_feParams.referenceFrequency);
     } else if (name == "freq2") {
-        return (float)m_secondReferenceFrequency;
+        return float(m_secondReferenceFrequency);
     } else if (name == "minfreq") {
-        return (float)m_feParams.minFrequency;
+        return float(m_feParams.minFrequency);
     } else if (name == "maxfreq") {
-        return (float)m_feParams.maxFrequency;
+        return float(m_feParams.maxFrequency);
     }
     
     return 0.0;
@@ -380,11 +380,11 @@
     if (name == "serialise") {
         m_serialise = (value > 0.5);
     } else if (name == "framenorm") {
-        m_fcParams.norm = (FeatureConditioner::Normalisation)(int(value + 0.1));
+        m_fcParams.norm = FeatureConditioner::Normalisation(int(value + 0.1));
     } else if (name == "distnorm") {
-        m_dParams.norm = (DistanceMetric::DistanceNormalisation)(int(value + 0.1));
+        m_dParams.norm = DistanceMetric::DistanceNormalisation(int(value + 0.1));
     } else if (name == "usespecdiff") {
-        m_fcParams.order = (FeatureConditioner::OutputOrder)(int(value + 0.1));
+        m_fcParams.order = FeatureConditioner::OutputOrder(int(value + 0.1));
     } else if (name == "usechroma") {
         m_feParams.useChromaFrequencyMap = (value > 0.5);
     } else if (name == "gradientlimit") {
@@ -398,9 +398,9 @@
     } else if (name == "silencethreshold") {
         m_fcParams.silenceThreshold = value;
     } else if (name == "metric") {
-        m_dParams.metric = (DistanceMetric::Metric)(int(value + 0.1));
+        m_dParams.metric = DistanceMetric::Metric(int(value + 0.1));
     } else if (name == "noise") {
-        m_dParams.noise = (DistanceMetric::NoiseAddition)(int(value + 0.1));
+        m_dParams.noise = DistanceMetric::NoiseAddition(int(value + 0.1));
     } else if (name == "freq1") {
         m_feParams.referenceFrequency = value;
     } else if (name == "freq2") {
@@ -448,9 +448,9 @@
     if (stepSize > blockSize/2 ||
         blockSize != getPreferredBlockSize()) return false;
 
-    m_stepSize = (int)stepSize;
+    m_stepSize = int(stepSize);
     m_stepTime = float(stepSize) / m_inputSampleRate;
-    m_blockSize = (int)blockSize;
+    m_blockSize = int(blockSize);
 
     createMatchers();
     m_begin = true;
@@ -647,27 +647,19 @@
     f.hasTimestamp = false;
 
     f.values.clear();
-    for (int j = 0; j < (int)f1.size(); ++j) {
-        f.values.push_back(float(f1[j]));
-    }
+    for (auto v: f1) f.values.push_back(float(v));
     returnFeatures[m_aFeaturesOutNo].push_back(f);
 
     f.values.clear();
-    for (int j = 0; j < (int)f2.size(); ++j) {
-        f.values.push_back(float(f2[j]));
-    }
+    for (auto v: f2) f.values.push_back(float(v));
     returnFeatures[m_bFeaturesOutNo].push_back(f);
 
     f.values.clear();
-    for (int j = 0; j < (int)cf1.size(); ++j) {
-        f.values.push_back(float(cf1[j]));
-    }
+    for (auto v: cf1) f.values.push_back(float(v));
     returnFeatures[m_caFeaturesOutNo].push_back(f);
 
     f.values.clear();
-    for (int j = 0; j < (int)cf2.size(); ++j) {
-        f.values.push_back(float(cf2[j]));
-    }
+    for (auto v: cf2) f.values.push_back(float(v));
     returnFeatures[m_cbFeaturesOutNo].push_back(f);
 
 //    std::cerr << ".";
@@ -692,7 +684,7 @@
     double cost = m_pipeline->getOverallCost();
     Feature costFeature;
     costFeature.hasTimestamp = false;
-    costFeature.values.push_back((float)cost);
+    costFeature.values.push_back(float(cost));
     returnFeatures[m_overallCostOutNo].push_back(costFeature);
     
     int prevx = 0;
--- a/src/Matcher.cpp	Thu Feb 26 10:48:36 2015 +0000
+++ b/src/Matcher.cpp	Thu Feb 26 12:19:17 2015 +0000
@@ -226,7 +226,6 @@
         }
         m_otherMatcher->setPathCost(j, i, dir, pathCost);
     }
-
 }
 
 void
@@ -303,11 +302,12 @@
 
     for ( ; index < stop; index++) {
 
-        distance_t distance = (distance_t) m_metric.calcDistance
+        distance_t distance = m_metric.calcDistance
             (m_features[frameIndex],
              m_otherMatcher->m_features[index % m_blockSize]);
 
-        distance_t diagDistance = distance_t(distance * m_params.diagonalWeight);
+        pathcost_t straightIncrement(distance);
+        pathcost_t diagIncrement = pathcost_t(distance * m_params.diagonalWeight);
 
         if ((m_frameCount == 0) && (index == 0)) { // first element
 
@@ -348,7 +348,7 @@
             } else {
 
                 pathcost_t min1 = getPathCost(m_frameCount - 1, index - 1);
-                if (min1 + diagDistance <= min2 + distance) {
+                if (min1 + diagIncrement <= min2 + straightIncrement) {
                     updateValue(m_frameCount, index, AdvanceBoth,
                                 min1, distance);
                 } else {
@@ -363,9 +363,9 @@
             pathcost_t min2 = getPathCost(m_frameCount - 1, index);
             pathcost_t min3 = getPathCost(m_frameCount - 1, index - 1);
 
-            pathcost_t cost1 = min1 + distance;
-            pathcost_t cost2 = min2 + distance;
-            pathcost_t cost3 = min3 + diagDistance;
+            pathcost_t cost1 = min1 + straightIncrement;
+            pathcost_t cost2 = min2 + straightIncrement;
+            pathcost_t cost3 = min3 + diagIncrement;
 
             // Choosing is easy if there is a strict cheapest of the
             // three. If two or more share the lowest cost, we choose
@@ -408,15 +408,22 @@
 void
 Matcher::updateValue(int i, int j, advance_t dir, pathcost_t value, distance_t distance)
 {
-    distance_t weighted = distance;
+    pathcost_t increment = distance;
     if (dir == AdvanceBoth) {
-        weighted = distance_t(weighted * m_params.diagonalWeight);
+        increment = pathcost_t(increment * m_params.diagonalWeight);
+    }
+
+    pathcost_t newValue = value + increment;
+    if (MaxPathCost - increment < value) {
+        cerr << "ERROR: Path cost overflow at i=" << i << ", j=" << j << ": "
+             << value << " + " << increment << " > " << MaxPathCost << endl;
+        newValue = MaxPathCost;
     }
     
     if (m_firstPM) {
 
         setDistance(i, j, distance);
-        setPathCost(i, j, dir, value + weighted);
+        setPathCost(i, j, dir, newValue);
 
     } else {
 
@@ -425,7 +432,7 @@
 
         int idx = i - m_otherMatcher->m_first[j];
         
-        if (idx == (int)m_otherMatcher->m_distance[j].size()) {
+        if (idx < 0 || size_t(idx) == m_otherMatcher->m_distance[j].size()) {
             // This should never happen, but if we allow arbitrary
             // pauses in either direction, and arbitrary lengths at
             // end, it is better than a segmentation fault.
@@ -436,7 +443,7 @@
         }
 
         m_otherMatcher->setDistance(j, i, distance);
-        m_otherMatcher->setPathCost(j, i, dir, value + weighted);
+        m_otherMatcher->setPathCost(j, i, dir, newValue);
     }
 }
 
--- a/src/Matcher.h	Thu Feb 26 10:48:36 2015 +0000
+++ b/src/Matcher.h	Thu Feb 26 12:19:17 2015 +0000
@@ -84,7 +84,7 @@
          *  normal DTW approach for performances with similar speeds
          *  might use 1.0 or something close to it.
          */
-        float diagonalWeight;
+        double diagonalWeight;
     };
 
     /** Constructor for Matcher.
@@ -134,7 +134,7 @@
         return m_otherMatcher->getFrameCount();
     }
 
-    float getDiagonalWeight() {
+    double getDiagonalWeight() {
         return m_params.diagonalWeight;
     }
     
--- a/src/Path.cpp	Thu Feb 26 10:48:36 2015 +0000
+++ b/src/Path.cpp	Thu Feb 26 12:19:17 2015 +0000
@@ -19,55 +19,55 @@
 int
 Path::smooth(std::vector<int> &x, std::vector<int> &y, int length)
 {
-    if (length == 0)
+    if (length <= 0)
         return 0;
-    while ((int)val.size() < length) {
-        val.push_back(0);
-        len.push_back(0);
+    while (m_val.size() < static_cast<std::vector<int>::size_type>(length)) {
+        m_val.push_back(0);
+        m_len.push_back(0);
     }
     int p = 0;
-    val[0] = len[0] = 0;
+    m_val[0] = m_len[0] = 0;
     for (int i = 1; i < length; i++) {	// H = 1; V = 2; D = 3
         int current = x[i] - x[i-1] + 2 * (y[i] - y[i-1]);
-        if (current == val[p]) {
-            len[p]++;
-        } else if ((current == 3) || (val[p] == 0)) {
-            val[++p] = current;
-            len[p] = 1;
-        } else if (val[p] + current == 3) {	// 1 + 2
-            if (--len[p] == 0)
+        if (current == m_val[p]) {
+            m_len[p]++;
+        } else if ((current == 3) || (m_val[p] == 0)) {
+            m_val[++p] = current;
+            m_len[p] = 1;
+        } else if (m_val[p] + current == 3) {	// 1 + 2
+            if (--m_len[p] == 0)
                 p--;
-            if (val[p] == 3)
-                len[p]++;
+            if (m_val[p] == 3)
+                m_len[p]++;
             else {
-                val[++p] = 3;
-                len[p] = 1;
+                m_val[++p] = 3;
+                m_len[p] = 1;
             }
-        } else {	// val[p] == 3 && current != 3
-            if ((val[p-1] == current) ||
-                (val[p-1] == 0) ||
-                (len[p] > MAX_RUN_LENGTH)) {
-                val[++p] = current;
-                len[p] = 1;
+        } else {	// m_val[p] == 3 && current != 3
+            if ((m_val[p-1] == current) ||
+                (m_val[p-1] == 0) ||
+                (m_len[p] > MAX_RUN_LENGTH)) {
+                m_val[++p] = current;
+                m_len[p] = 1;
             } else {
-                if (--len[p-1] == 0) {
-                    val[p-1] = val[p];
-                    len[p-1] = len[p];
+                if (--m_len[p-1] == 0) {
+                    m_val[p-1] = m_val[p];
+                    m_len[p-1] = m_len[p];
                     p--;
-                    if (val[p-1] == 3) {
-                        len[p-1] += len[p];
+                    if (m_val[p-1] == 3) {
+                        m_len[p-1] += m_len[p];
                         p--;
                     }
                 }
-                len[p]++;
+                m_len[p]++;
             }
         }
     }
     int i = 1;
     for (int pp = 1; pp <= p; pp++) {
-        int dx = val[pp] & 1;
-        int dy = val[pp] >> 1;
-        for (int j = len[pp]; j > 0; j--, i++) {
+        int dx = m_val[pp] & 1;
+        int dy = m_val[pp] >> 1;
+        for (int j = m_len[pp]; j > 0; j--, i++) {
             x[i] = x[i-1] + dx;
             y[i] = y[i-1] + dy;
         }
--- a/src/Path.h	Thu Feb 26 10:48:36 2015 +0000
+++ b/src/Path.h	Thu Feb 26 12:19:17 2015 +0000
@@ -38,8 +38,8 @@
 protected:
     static const int MAX_RUN_LENGTH = 50;
 
-    std::vector<int> val;
-    std::vector<int> len;
+    std::vector<int> m_val;
+    std::vector<int> m_len;
 };
 
 #endif
--- a/test/TestFeatureExtractor.cpp	Thu Feb 26 10:48:36 2015 +0000
+++ b/test/TestFeatureExtractor.cpp	Thu Feb 26 12:19:17 2015 +0000
@@ -39,7 +39,7 @@
 			       vector<double> real, vector<double> imag)
 {
     vector<float> in;
-    for (int i = 0; i < (int)real.size(); ++i) {
+    for (size_t i = 0; i < real.size(); ++i) {
 	in.push_back(float(real[i]));
 	in.push_back(float(imag[i]));
     }
@@ -64,7 +64,7 @@
 	    int hs = sz / 2 + 1;
 	    int fsz = 13;
     
-	    FeatureExtractor::Parameters params((float)rate, sz);
+	    FeatureExtractor::Parameters params(float(rate), sz);
 	    params.useChromaFrequencyMap = true;
 	    FeatureExtractor fe(params);
 	    BOOST_CHECK_EQUAL(fe.getFeatureSize(), fsz);
@@ -141,7 +141,7 @@
     int hs = sz / 2 + 1;
     int fsz = 84;
     
-    FeatureExtractor::Parameters params((float)rate, sz);
+    FeatureExtractor::Parameters params(float(rate), sz);
     FeatureExtractor fe(params);
     BOOST_CHECK_EQUAL(fe.getFeatureSize(), fsz);