annotate Finder.cpp @ 15:a82276091bbd

Pull out Matcher parameters into an object
author Chris Cannam
date Fri, 10 Oct 2014 12:55:05 +0100
parents 640f92242cc1
children 7784b0a0dd4d
rev   line source
cannam@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@0 2
cannam@0 3 /*
cannam@0 4 Vamp feature extraction plugin using the MATCH audio alignment
cannam@0 5 algorithm.
cannam@0 6
cannam@0 7 Centre for Digital Music, Queen Mary, University of London.
cannam@0 8 This file copyright 2007 Simon Dixon, Chris Cannam and QMUL.
cannam@0 9
cannam@0 10 This program is free software; you can redistribute it and/or
cannam@0 11 modify it under the terms of the GNU General Public License as
cannam@0 12 published by the Free Software Foundation; either version 2 of the
cannam@0 13 License, or (at your option) any later version. See the file
cannam@0 14 COPYING included with this distribution for more information.
cannam@0 15 */
cannam@0 16
cannam@0 17 #include "Finder.h"
cannam@0 18
cannam@0 19
cannam@0 20 Finder::Finder(Matcher *p1, Matcher *p2)
cannam@0 21 {
cannam@0 22 if (!p1->firstPM)
cannam@0 23 std::cerr << "Warning: wrong args in Finder()" << std::endl;
cannam@0 24 pm1 = p1;
cannam@0 25 pm2 = p2;
cannam@0 26 index1 = 0;
cannam@0 27 index2 = 0;
cannam@0 28 rowRange = new int[2];
cannam@0 29 colRange = new int[2];
cannam@0 30 } // constructor
cannam@0 31
cannam@0 32 Finder::~Finder()
cannam@0 33 {
cannam@0 34 delete[] rowRange;
cannam@0 35 delete[] colRange;
cannam@0 36 }
cannam@0 37
cannam@0 38 bool
cannam@0 39 Finder::find(int i1, int i2)
cannam@0 40 {
cannam@0 41 if (i1 >= 0) {
cannam@0 42 index1 = i1;
cannam@0 43 index2 = i2 - pm1->first[i1];
cannam@0 44 }
cannam@0 45 return (i1 >= 0) && (i2 >= pm1->first[i1]) && (i2 < pm1->last[i1]);
cannam@0 46 } // find()
cannam@0 47
cannam@0 48 void
cannam@0 49 Finder::getColRange(int row, int *range)
cannam@0 50 {
cannam@0 51 range[0] = pm1->first[row];
cannam@0 52 range[1] = pm1->last[row];
cannam@0 53 } // getColRange()
cannam@0 54
cannam@0 55 void
cannam@0 56 Finder::getRowRange(int col, int *range)
cannam@0 57 {
cannam@0 58 range[0] = pm2->first[col];
cannam@0 59 range[1] = pm2->last[col];
cannam@0 60 } // getRowRange()
cannam@0 61
cannam@0 62 int
cannam@0 63 Finder::getExpandDirection(int row, int col)
cannam@0 64 {
cannam@0 65 return getExpandDirection(row, col, false);
cannam@0 66 } // getExpandDirection()
cannam@0 67
cannam@0 68 int
cannam@0 69 Finder::getExpandDirection(int row, int col, bool check)
cannam@0 70 {
cannam@0 71 int min = getPathCost(row, col);
cannam@0 72 bestRow = row;
cannam@0 73 bestCol = col;
cannam@0 74 getRowRange(col, rowRange);
cannam@0 75 if (rowRange[1] > row+1)
cannam@0 76 rowRange[1] = row+1; // don't cheat by looking at future :)
cannam@0 77 for (int index = rowRange[0]; index < rowRange[1]; index++) {
cannam@0 78 int tmp = getPathCost(index, col);
cannam@0 79 if (tmp < min) {
cannam@0 80 min = tmp;
cannam@0 81 bestRow = index;
cannam@0 82 }
cannam@0 83 }
cannam@0 84 getColRange(row, colRange);
cannam@0 85 if (colRange[1] > col+1)
cannam@0 86 colRange[1] = col+1; // don't cheat by looking at future :)
cannam@0 87 for (int index = colRange[0]; index < colRange[1]; index++) {
cannam@0 88 int tmp = getPathCost(row, index);
cannam@0 89 if (tmp < min) {
cannam@0 90 min = tmp;
cannam@0 91 bestCol = index;
cannam@0 92 bestRow = row;
cannam@0 93 }
cannam@0 94 }
cannam@0 95 // System.err.print(" BEST: " + bestRow + " " + bestCol + " " + check);
cannam@0 96 // System.err.println(" " + pm1->frameCount + " " + pm2->frameCount);
cannam@0 97 if (check) {
cannam@0 98 // System.err.println(find(row+1, col) + " " + find(row, col+1));
cannam@0 99 if (!find(row, col+1))
cannam@0 100 return ADVANCE_THIS;
cannam@0 101 if (!find(row+1, col))
cannam@0 102 return ADVANCE_OTHER;
cannam@0 103 }
cannam@0 104 return ((bestRow==row)? ADVANCE_THIS: 0) |
cannam@0 105 ((bestCol==col)? ADVANCE_OTHER: 0);
cannam@0 106
cannam@0 107 } // getExpandDirection()
cannam@0 108
cannam@0 109 unsigned char
cannam@0 110 Finder::getDistance(int row, int col)
cannam@0 111 {
cannam@0 112 if (find(row, col)) {
cannam@0 113 return pm1->distance[row][col - pm1->first[row]];
cannam@0 114 }
cannam@0 115 std::cerr << "getDistance(" << row << "," << col << "): out of bounds" << std::endl;
cannam@0 116 throw "getDistance index out of bounds";
cannam@0 117 } // getDistance()/2
cannam@0 118
cannam@0 119 void
cannam@0 120 Finder::setDistance(int row, int col, unsigned char b)
cannam@0 121 {
cannam@0 122 if (find(row, col)) {
cannam@0 123 pm1->distance[row][col - pm1->first[row]] = b;
cannam@0 124 return;
cannam@0 125 }
cannam@0 126 std::cerr << "setDistance(" << row << "," << col << "," << b << "): out of bounds" << std::endl;
cannam@0 127 throw "setDistance index out of bounds";
cannam@0 128 } // setDistance()
cannam@0 129
cannam@0 130 int
cannam@0 131 Finder::getPathCost(int row, int col)
cannam@0 132 {
cannam@0 133 if (find(row, col)) // "1" avoids div by 0 below
cannam@0 134 return pm1->bestPathCost[row][col - pm1->first[row]]*100/ (1+row+col);
cannam@0 135 std::cerr << "getPathCost(" << row << "," << col << "): out of bounds" << std::endl;
cannam@0 136 throw "getPathCost index out of bounds";
cannam@0 137 } // getPathCost()
cannam@0 138
cannam@0 139 int
cannam@0 140 Finder::getRawPathCost(int row, int col)
cannam@0 141 {
cannam@0 142 if (find(row, col))
cannam@0 143 return pm1->bestPathCost[row][col - pm1->first[row]];
cannam@0 144 std::cerr << "getRawPathCost(" << row << "," << col << "): out of bounds" << std::endl;
cannam@0 145 throw "getRawPathCost index out of bounds";
cannam@0 146 } // getRawPathCost()
cannam@0 147
cannam@0 148 void
cannam@0 149 Finder::setPathCost(int row, int col, int i)
cannam@0 150 {
cannam@0 151 if (find(row, col)) {
cannam@0 152 pm1->bestPathCost[row][col - pm1->first[row]] = i;
cannam@0 153 return;
cannam@0 154 }
cannam@0 155 std::cerr << "setPathCost(" << row << "," << col << "," << i << "): out of bounds" << std::endl;
cannam@0 156 throw "setPathCost index out of bounds";
cannam@0 157 } // setPathCost()
cannam@0 158
cannam@0 159 unsigned char
cannam@0 160 Finder::getDistance()
cannam@0 161 {
cannam@0 162 return pm1->distance[index1][index2];
cannam@0 163 } // getDistance()/0
cannam@0 164
cannam@0 165 void
cannam@0 166 Finder::setDistance(int b)
cannam@0 167 {
cannam@0 168 pm1->distance[index1][index2] = (unsigned char)b;
cannam@0 169 } // setDistance()
cannam@0 170
cannam@0 171 int
cannam@0 172 Finder::getPathCost()
cannam@0 173 {
cannam@0 174 return pm1->bestPathCost[index1][index2];
cannam@0 175 } // getPathCost()
cannam@0 176
cannam@0 177 void
cannam@0 178 Finder::setPathCost(int i)
cannam@0 179 {
cannam@0 180 pm1->bestPathCost[index1][index2] = i;
cannam@0 181 } // setPathCost()
cannam@0 182
cannam@0 183 void
cannam@0 184 Finder::recalculatePathCostMatrix(int r1, int c1, int r2, int c2)
cannam@0 185 {
cannam@0 186 if (!find(r1,c1)) {
cannam@0 187 std::cerr << "recalculatePathCostMatrix(" << r1 << "," << c1 << "): out of bounds" << std::endl;
cannam@0 188 throw "recalculatePathCostMatrix index out of bounds";
cannam@0 189 }
cannam@0 190 int thisRowStart, c;
cannam@0 191 int prevRowStart = 0, prevRowStop = 0;
cannam@0 192 for (int r = r1; r <= r2; r++) {
cannam@0 193 thisRowStart = pm1->first[r];
cannam@0 194 if (thisRowStart < c1)
cannam@0 195 thisRowStart = c1;
cannam@0 196 for (c = thisRowStart; c <= c2; c++) {
cannam@0 197 if (find(r,c)) {
cannam@0 198 int i2 = index2;
cannam@0 199 int newCost = pm1->distance[r][i2];
cannam@0 200 int dir = 0;
cannam@0 201 if (r > r1) { // not first row
cannam@0 202 int min = -1;
cannam@0 203 if ((c > prevRowStart) && (c <= prevRowStop)) {
cannam@0 204 // diagonal from (r-1,c-1)
cannam@0 205 min = pm1->bestPathCost[r-1][c-pm1->first[r-1]-1] +
cannam@0 206 newCost * 2;
cannam@0 207 dir = ADVANCE_BOTH;
cannam@0 208 }
cannam@0 209 if ((c >= prevRowStart) && (c < prevRowStop)) {
cannam@0 210 // vertical from (r-1,c)
cannam@0 211 int cost = pm1->bestPathCost[r-1][c-pm1->first[r-1]] +
cannam@0 212 newCost;
cannam@0 213 if ((min == -1) || (cost < min)) {
cannam@0 214 min = cost;
cannam@0 215 dir = ADVANCE_THIS;
cannam@0 216 }
cannam@0 217 }
cannam@0 218 if (c > thisRowStart) {
cannam@0 219 // horizontal from (r,c-1)
cannam@0 220 int cost =pm1->bestPathCost[r][i2-1]+newCost;
cannam@0 221 if ((min == -1) || (cost < min)) {
cannam@0 222 min = cost;
cannam@0 223 dir = ADVANCE_OTHER;
cannam@0 224 }
cannam@0 225 }
cannam@0 226 pm1->bestPathCost[r][i2] = min;
cannam@0 227 } else if (c > thisRowStart) { // first row
cannam@0 228 // horizontal from (r,c-1)
cannam@0 229 pm1->bestPathCost[r][i2] = pm1->bestPathCost[r][i2-1] +
cannam@0 230 newCost;
cannam@0 231 dir = ADVANCE_OTHER;
cannam@0 232 }
cannam@0 233 if ((r != r1) || (c != c1)) {
cannam@0 234 pm1->distance[r][i2] = (unsigned char)
cannam@0 235 ((pm1->distance[r][i2] & MASK) | dir);
cannam@0 236 }
cannam@0 237 } else
cannam@0 238 break; // end of row
cannam@0 239 }
cannam@0 240 prevRowStart = thisRowStart;
cannam@0 241 prevRowStop = c;
cannam@0 242 }
cannam@0 243 } // recalculatePathCostMatrix()