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. cannam@0: 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: Chris@24: #include "MatchFeatureFeeder.h" cannam@0: Chris@14: using std::vector; Chris@235: using std::cerr; Chris@235: using std::endl; Chris@14: Chris@24: MatchFeatureFeeder::MatchFeatureFeeder(Matcher *m1, Matcher *m2) : Chris@167: m_pm1(m1), Chris@167: m_pm2(m2), Chris@167: m_finder(m_pm1) cannam@0: { cannam@0: } cannam@0: Chris@24: MatchFeatureFeeder::~MatchFeatureFeeder() cannam@0: { cannam@0: } cannam@0: Chris@154: void Chris@183: MatchFeatureFeeder::feed(feature_t f1, feature_t f2) cannam@0: { Chris@49: // We maintain two FIFO queues of feature vectors, one per input Chris@49: // stream. When the match-feeder function is entered, it knows Chris@49: // that it has at least one feature in each queue. It loops, Chris@49: // processing up to one feature per matcher, until a queue is Chris@49: // empty. Then it returns, to be called again with more data. Chris@49: Chris@60: if (!f1.empty()) { Chris@74: m_q1.push(f1); Chris@60: } Chris@60: Chris@60: if (!f2.empty()) { Chris@74: m_q2.push(f2); Chris@60: } Chris@14: Chris@74: while (!m_q1.empty() && !m_q2.empty()) { Chris@63: feedBlock(); Chris@63: } Chris@63: } Chris@63: Chris@167: int Chris@167: MatchFeatureFeeder::getEstimatedReferenceFrame() Chris@167: { Chris@167: if (m_pm1->getFrameCount() == 0 || m_pm2->getFrameCount() == 0) { Chris@167: return 0; Chris@167: } Chris@167: int bestRow = 0; Chris@191: normpathcost_t bestCost = 0; Chris@167: if (!m_finder.getBestColCost(m_pm2->getFrameCount()-1, bestRow, bestCost)) { Chris@167: return -1; Chris@167: } else { Chris@167: return bestRow; Chris@167: } Chris@167: } Chris@167: Chris@63: void Chris@63: MatchFeatureFeeder::finish() Chris@63: { Chris@74: while (!m_q1.empty() || !m_q2.empty()) { Chris@24: feedBlock(); Chris@14: } Chris@200: Chris@200: // cerr << "MatchFeatureFeeder::finish: have " << m_pm1->getFrameCount() Chris@200: // << " reference and " << m_pm2->getFrameCount() << " other frames" Chris@200: // << endl; Chris@14: } Chris@14: Chris@24: void Chris@24: MatchFeatureFeeder::feedBlock() Chris@14: { Chris@74: if (m_q1.empty()) { // ended Chris@60: feed2(); Chris@74: } else if (m_q2.empty()) { // ended Chris@60: feed1(); Chris@171: } else if (m_pm1->isFillingInitialBlock()) { Chris@24: feed1(); Chris@24: feed2(); Chris@78: } else if (m_pm1->isOverrunning()) { // slope constraints Chris@24: feed2(); Chris@78: } else if (m_pm2->isOverrunning()) { Chris@24: feed1(); cannam@0: } else { Chris@171: switch (m_finder.getExpandDirection()) { Chris@181: case AdvanceThis: Chris@24: feed1(); cannam@0: break; Chris@181: case AdvanceOther: Chris@24: feed2(); cannam@0: break; Chris@181: case AdvanceBoth: Chris@24: feed1(); Chris@24: feed2(); cannam@0: break; Chris@181: case AdvanceNone: Chris@74: cerr << "m_finder says AdvanceNone!" << endl; Chris@45: break; cannam@0: } cannam@0: } Chris@135: Chris@135: m_fpx.push_back(m_pm2->getFrameCount()); Chris@135: m_fpy.push_back(m_pm1->getFrameCount()); cannam@0: } cannam@0: Chris@24: void Chris@24: MatchFeatureFeeder::feed1() cannam@0: { Chris@74: m_pm1->consumeFeatureVector(m_q1.front()); Chris@74: m_q1.pop(); cannam@0: } cannam@0: Chris@24: void Chris@24: MatchFeatureFeeder::feed2() cannam@0: { Chris@74: m_pm2->consumeFeatureVector(m_q2.front()); Chris@74: m_q2.pop(); cannam@0: } cannam@0: