annotate src/MatchPipeline.cpp @ 246:aac9ad4064ea subsequence tip

Fix incorrect handling of silent tail in the non-subsequence MATCH phase; some debug output changes
author Chris Cannam
date Fri, 24 Jul 2020 14:29:55 +0100
parents 2f3ecf5d2651
children
rev   line source
Chris@105 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@105 2 /*
Chris@105 3 Vamp feature extraction plugin using the MATCH audio alignment
Chris@105 4 algorithm.
Chris@105 5
Chris@105 6 Centre for Digital Music, Queen Mary, University of London.
Chris@236 7 Copyright (c) 2007-2020 Simon Dixon, Chris Cannam, and Queen Mary
Chris@230 8 University of London, Copyright (c) 2014-2015 Tido GmbH.
Chris@105 9
Chris@105 10 This program is free software; you can redistribute it and/or
Chris@105 11 modify it under the terms of the GNU General Public License as
Chris@105 12 published by the Free Software Foundation; either version 2 of the
Chris@105 13 License, or (at your option) any later version. See the file
Chris@105 14 COPYING included with this distribution for more information.
Chris@105 15 */
Chris@105 16
Chris@105 17 #include "MatchPipeline.h"
Chris@105 18
Chris@140 19 //#define DEBUG_MATCH_PIPELINE 1
Chris@140 20
Chris@105 21 MatchPipeline::MatchPipeline(FeatureExtractor::Parameters feParams,
Chris@105 22 FeatureConditioner::Parameters fcParams,
Chris@143 23 DistanceMetric::Parameters dParams,
Chris@160 24 Matcher::Parameters matchParams,
Chris@160 25 double secondReferenceFrequency) :
Chris@105 26 m_fe1(feParams),
Chris@166 27 m_fe2(paramsWithFreq(feParams, secondReferenceFrequency)),
Chris@105 28 m_fc1(fcParams),
Chris@105 29 m_fc2(fcParams),
Chris@143 30 m_pm1(matchParams, dParams, 0),
Chris@143 31 m_pm2(matchParams, dParams, &m_pm1),
Chris@105 32 m_feeder(&m_pm1, &m_pm2),
Chris@105 33 m_lastFrameIn1(0),
Chris@105 34 m_lastFrameIn2(0),
Chris@105 35 m_frameNo(0)
Chris@105 36 {
Chris@105 37 m_pm1.setOtherMatcher(&m_pm2);
Chris@105 38 }
Chris@105 39
Chris@105 40 MatchPipeline::~MatchPipeline()
Chris@105 41 {
Chris@105 42 }
Chris@105 43
Chris@166 44 FeatureExtractor::Parameters
Chris@166 45 MatchPipeline::paramsWithFreq(FeatureExtractor::Parameters params, double freq)
Chris@166 46 {
Chris@166 47 if (freq == 0.0) return params;
Chris@166 48 params.referenceFrequency = freq;
Chris@166 49 return params;
Chris@166 50 }
Chris@166 51
Chris@105 52 void
Chris@105 53 MatchPipeline::feedFrequencyDomainAudio(const float *arr1, const float *arr2)
Chris@105 54 {
Chris@105 55 feedFeatures(m_fe1.process(arr1), m_fe2.process(arr2));
Chris@105 56 }
Chris@105 57
Chris@105 58 void
Chris@183 59 MatchPipeline::feedFeatures(const feature_t &f1, const feature_t &f2)
Chris@105 60 {
Chris@106 61 m_f1 = f1;
Chris@106 62 m_f2 = f2;
Chris@106 63
Chris@140 64 #ifdef DEBUG_MATCH_PIPELINE
Chris@140 65 if (m_lastFrameIn1 == 1) {
Chris@140 66 cerr << "features 1 -> ";
Chris@200 67 for (int i = 0; i < int(m_f1.size()); ++i) {
Chris@140 68 cerr << m_f1[i] << " ";
Chris@140 69 }
Chris@140 70 cerr << endl;
Chris@140 71 }
Chris@140 72 #endif
Chris@140 73
Chris@105 74 feedConditionedFeatures(m_fc1.process(f1), m_fc2.process(f2));
Chris@105 75 }
Chris@105 76
Chris@105 77 void
Chris@183 78 MatchPipeline::feedConditionedFeatures(const feature_t &c1, const feature_t &c2)
Chris@105 79 {
Chris@106 80 m_c1 = c1;
Chris@106 81 m_c2 = c2;
Chris@140 82
Chris@140 83 #ifdef DEBUG_MATCH_PIPELINE
Chris@140 84 if (m_lastFrameIn1 == 1) {
Chris@140 85 cerr << "conditioned features 1 -> ";
Chris@200 86 for (int i = 0; i < int(m_c1.size()); ++i) {
Chris@140 87 cerr << m_c1[i] << " ";
Chris@140 88 }
Chris@140 89 cerr << endl;
Chris@140 90 }
Chris@140 91 #endif
Chris@106 92
Chris@106 93 m_feeder.feed(c1, c2);
Chris@105 94
Chris@237 95 if (isAboveEndingThreshold(c1)) m_lastFrameIn1 = m_frameNo;
Chris@237 96 if (isAboveEndingThreshold(c2)) m_lastFrameIn2 = m_frameNo;
Chris@105 97
Chris@140 98 #ifdef DEBUG_MATCH_PIPELINE
Chris@140 99 cerr << "last frames are " << m_lastFrameIn1 << ", " << m_lastFrameIn2
Chris@140 100 << endl;
Chris@140 101 #endif
Chris@140 102
Chris@105 103 ++m_frameNo;
Chris@105 104 }
Chris@105 105
Chris@106 106 void
Chris@183 107 MatchPipeline::extractFeatures(feature_t &f1, feature_t &f2)
Chris@106 108 {
Chris@106 109 f1 = m_f1;
Chris@106 110 f2 = m_f2;
Chris@106 111 }
Chris@106 112
Chris@106 113 void
Chris@183 114 MatchPipeline::extractConditionedFeatures(feature_t &c1, feature_t &c2)
Chris@106 115 {
Chris@106 116 c1 = m_c1;
Chris@106 117 c2 = m_c2;
Chris@106 118 }
Chris@106 119
Chris@105 120 bool
Chris@237 121 MatchPipeline::isAboveEndingThreshold(const feature_t &f)
Chris@105 122 {
Chris@105 123 double threshold = 1e-4f;
Chris@105 124 double sum = 0.f;
Chris@105 125 for (int i = 0; i < int(f.size()); ++i) {
Chris@105 126 sum += f[i] * f[i];
Chris@105 127 }
Chris@140 128 #ifdef DEBUG_MATCH_PIPELINE
Chris@237 129 cerr << "isAboveEndingThreshold: sum " << sum
Chris@237 130 << ", threshold " << threshold
Chris@140 131 << ", returning " << (sum >= threshold) << endl;
Chris@140 132 #endif
Chris@105 133 return (sum >= threshold);
Chris@105 134 }
Chris@105 135
Chris@105 136 void
Chris@105 137 MatchPipeline::finish()
Chris@105 138 {
Chris@105 139 m_feeder.finish();
Chris@200 140 m_feeder.getFinder()->setDurations(m_lastFrameIn1 + 1, m_lastFrameIn2 + 1);
Chris@105 141 }
Chris@105 142
Chris@155 143 int
Chris@155 144 MatchPipeline::retrievePath(bool smooth, std::vector<int> &pathx, std::vector<int> &pathy)
Chris@135 145 {
Chris@155 146 return m_feeder.getFinder()->retrievePath(smooth, pathx, pathy);
Chris@135 147 }
Chris@135 148
Chris@155 149 void
Chris@155 150 MatchPipeline::retrieveForwardPath(std::vector<int> &pathx, std::vector<int> &pathy) {
Chris@155 151 return m_feeder.retrieveForwardPath(pathx, pathy);
Chris@105 152 }
Chris@105 153
Chris@173 154 double
Chris@173 155 MatchPipeline::getOverallCost()
Chris@173 156 {
Chris@173 157 return m_feeder.getFinder()->getOverallCost();
Chris@173 158 }
Chris@105 159