cannam@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ cannam@0: cannam@0: /* cannam@0: Vamp feature extraction plugin using the MATCH audio alignment cannam@0: algorithm. cannam@0: cannam@0: Centre for Digital Music, Queen Mary, University of London. Chris@236: Copyright (c) 2007-2020 Simon Dixon, Chris Cannam, and Queen Mary Chris@230: University of London, Copyright (c) 2014-2015 Tido GmbH. Chris@230: cannam@0: This program is free software; you can redistribute it and/or cannam@0: modify it under the terms of the GNU General Public License as cannam@0: published by the Free Software Foundation; either version 2 of the cannam@0: License, or (at your option) any later version. See the file cannam@0: COPYING included with this distribution for more information. cannam@0: */ cannam@0: cannam@0: #ifndef _FINDER_H_ cannam@0: #define _FINDER_H_ cannam@0: cannam@0: #include cannam@0: #include cannam@0: cannam@0: #include "Matcher.h" cannam@0: Chris@72: class Finder Chris@72: { cannam@0: public: Chris@72: Finder(Matcher *pm); cannam@0: Chris@167: // default copy ctor and operator= are fine Chris@167: cannam@0: ~Finder(); cannam@0: Chris@154: void setMatcher(Matcher *pm); Chris@154: Chris@60: /** Chris@60: * Tell the finder that one or both files ends sooner than it Chris@60: * thought, i.e. that some of the trailing features are silence or Chris@60: * otherwise to be ignored. d1 and d2 are feature frame counts for Chris@60: * matchers 1 and 2 respectively. If this is not called, the full Chris@60: * duration of each input will be considered. Chris@60: */ Chris@60: void setDurations(int d1, int d2); Chris@147: Chris@147: /** Chris@191: * Find the location and normalised path cost of the column with Chris@191: * the cheapest path cost within the given row. If the row is out Chris@191: * of range, return false and leave the bestCol and bestCost Chris@191: * variables unchanged. Chris@154: */ Chris@191: bool getBestRowCost(int row, int &bestCol, normpathcost_t &bestCost); Chris@154: Chris@154: /** Chris@191: * Find the location and normalised path cost of the row with the Chris@191: * cheapest path cost within the given column. If the column is Chris@191: * out of range, return false and leave the bestRow and bestCost Chris@191: * variables unchanged. Chris@154: */ Chris@191: bool getBestColCost(int col, int &bestRow, normpathcost_t &bestCost); Chris@154: Chris@154: /** Chris@191: * Find the location and normalised path cost of the cheapest path Chris@191: * cost within the final row and column of the search area, given Chris@191: * that the area extends as far as the point at (row, col). This Chris@191: * is used by getExpandDirection and can also be used, for Chris@191: * example, to determine the current best estimate alignment for a Chris@191: * frame we have just reached. Chris@147: */ Chris@147: void getBestEdgeCost(int row, int col, Chris@147: int &bestRow, int &bestCol, Chris@191: normpathcost_t &bestCost); Chris@147: Chris@147: /** Chris@147: * Calculate which direction to expand the search area in, given Chris@171: * its current extents. Chris@171: */ Chris@181: advance_t getExpandDirection(); Chris@171: Chris@171: /** Chris@171: * Calculate which direction to expand the search area in, given Chris@147: * that so far it extends as far as the point at (row, col). Chris@147: */ Chris@181: advance_t getExpandDirection(int row, int col); Chris@45: cannam@0: /** Calculates a rectangle of the path cost matrix so that the cannam@0: * minimum cost path between the bottom left and top right cannam@0: * corners can be computed. Caches previous values to avoid cannam@0: * calling find() multiple times, and is several times faster as cannam@0: * a result. cannam@0: * cannam@0: * @param r1 the bottom of the rectangle to be calculated cannam@0: * @param c1 the left side of the rectangle to be calculated cannam@0: * @param r2 the top of the rectangle to be calculated cannam@0: * @param c2 the right side of the rectangle to be calculated cannam@0: */ cannam@0: void recalculatePathCostMatrix(int r1, int c1, int r2, int c2); cannam@0: Chris@30: /** Chris@30: * Track back after all of the matchers have been fed in order to Chris@30: * obtain the lowest cost path available. Path x and y coordinate Chris@30: * pairs are returned in corresponding elements of pathx and Chris@30: * pathy. Return value is the length of the returned path: only Chris@30: * this many elements from pathx and pathy are valid (any Chris@30: * subsequent ones may be spurious). Chris@31: * Chris@31: * @param smooth whether to smooth the path before returning it Chris@30: */ Chris@31: int retrievePath(bool smooth, std::vector &pathx, std::vector &pathy); Chris@72: Chris@163: /** Chris@163: * Get the path cost for the overall path to the end of both Chris@163: * sources. Chris@163: */ Chris@182: pathcost_t getOverallCost(); Chris@163: Chris@72: protected: Chris@82: #ifdef PERFORM_ERROR_CHECKS Chris@81: struct ErrorPosition { Chris@86: enum Type { NoError = 0, WrongCost, WrongAdvance, NoAdvance }; Chris@81: ErrorPosition() : type(NoError) { } Chris@81: Type type; Chris@81: int r; Chris@81: int c; Chris@182: pathcost_t prevCost; Chris@182: distance_t distance; Chris@182: pathcost_t costWas; Chris@182: pathcost_t costShouldBe; Chris@181: advance_t advanceWas; Chris@181: advance_t advanceShouldBe; Chris@81: }; Chris@81: ErrorPosition checkPathCostMatrix(); Chris@92: void checkAndReport(); Chris@82: #endif Chris@167: Chris@147: Matcher *m_m; // I do not own this Chris@147: Chris@72: int m_duration1; Chris@72: int m_duration2; Chris@147: }; cannam@0: cannam@0: #endif