Mercurial > hg > match-vamp
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;