annotate src/MatchPipeline.cpp @ 160:581b1118ec28 refactors

Permit overriding reference frequency for second input in MatchPipeline
author Chris Cannam
date Thu, 29 Jan 2015 17:07:05 +0000
parents 6914a6a01ffc
children d23dad16d6f9
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@105 7 This file copyright 2007 Simon Dixon, Chris Cannam and QMUL.
Chris@105 8
Chris@105 9 This program is free software; you can redistribute it and/or
Chris@105 10 modify it under the terms of the GNU General Public License as
Chris@105 11 published by the Free Software Foundation; either version 2 of the
Chris@105 12 License, or (at your option) any later version. See the file
Chris@105 13 COPYING included with this distribution for more information.
Chris@105 14 */
Chris@105 15
Chris@105 16 #include "MatchPipeline.h"
Chris@105 17
Chris@140 18 //#define DEBUG_MATCH_PIPELINE 1
Chris@140 19
Chris@105 20 MatchPipeline::MatchPipeline(FeatureExtractor::Parameters feParams,
Chris@105 21 FeatureConditioner::Parameters fcParams,
Chris@143 22 DistanceMetric::Parameters dParams,
Chris@160 23 Matcher::Parameters matchParams,
Chris@160 24 double secondReferenceFrequency) :
Chris@105 25 m_fe1(feParams),
Chris@105 26 m_fe2(feParams),
Chris@105 27 m_fc1(fcParams),
Chris@105 28 m_fc2(fcParams),
Chris@143 29 m_pm1(matchParams, dParams, 0),
Chris@143 30 m_pm2(matchParams, dParams, &m_pm1),
Chris@105 31 m_feeder(&m_pm1, &m_pm2),
Chris@105 32 m_lastFrameIn1(0),
Chris@105 33 m_lastFrameIn2(0),
Chris@105 34 m_frameNo(0)
Chris@105 35 {
Chris@160 36 if (secondReferenceFrequency != 0.0) {
Chris@160 37 feParams.referenceFrequency = secondReferenceFrequency;
Chris@160 38 m_fe2 = FeatureExtractor(feParams);
Chris@160 39 }
Chris@160 40
Chris@105 41 m_pm1.setOtherMatcher(&m_pm2);
Chris@105 42 }
Chris@105 43
Chris@105 44 MatchPipeline::~MatchPipeline()
Chris@105 45 {
Chris@105 46 }
Chris@105 47
Chris@105 48 void
Chris@105 49 MatchPipeline::feedFrequencyDomainAudio(const float *arr1, const float *arr2)
Chris@105 50 {
Chris@105 51 feedFeatures(m_fe1.process(arr1), m_fe2.process(arr2));
Chris@105 52 }
Chris@105 53
Chris@105 54 void
Chris@105 55 MatchPipeline::feedFeatures(const vector<double> &f1, const vector<double> &f2)
Chris@105 56 {
Chris@106 57 m_f1 = f1;
Chris@106 58 m_f2 = f2;
Chris@106 59
Chris@140 60 #ifdef DEBUG_MATCH_PIPELINE
Chris@140 61 if (m_lastFrameIn1 == 1) {
Chris@140 62 cerr << "features 1 -> ";
Chris@140 63 for (int i = 0; i < (int) m_f1.size(); ++i) {
Chris@140 64 cerr << m_f1[i] << " ";
Chris@140 65 }
Chris@140 66 cerr << endl;
Chris@140 67 }
Chris@140 68 #endif
Chris@140 69
Chris@105 70 feedConditionedFeatures(m_fc1.process(f1), m_fc2.process(f2));
Chris@105 71 }
Chris@105 72
Chris@105 73 void
Chris@106 74 MatchPipeline::feedConditionedFeatures(const vector<double> &c1, const vector<double> &c2)
Chris@105 75 {
Chris@106 76 m_c1 = c1;
Chris@106 77 m_c2 = c2;
Chris@140 78
Chris@140 79 #ifdef DEBUG_MATCH_PIPELINE
Chris@140 80 if (m_lastFrameIn1 == 1) {
Chris@140 81 cerr << "conditioned features 1 -> ";
Chris@140 82 for (int i = 0; i < (int) m_c1.size(); ++i) {
Chris@140 83 cerr << m_c1[i] << " ";
Chris@140 84 }
Chris@140 85 cerr << endl;
Chris@140 86 }
Chris@140 87 #endif
Chris@106 88
Chris@106 89 m_feeder.feed(c1, c2);
Chris@105 90
Chris@106 91 if (aboveThreshold(c1)) m_lastFrameIn1 = m_frameNo;
Chris@106 92 if (aboveThreshold(c2)) m_lastFrameIn2 = m_frameNo;
Chris@105 93
Chris@140 94 #ifdef DEBUG_MATCH_PIPELINE
Chris@140 95 cerr << "last frames are " << m_lastFrameIn1 << ", " << m_lastFrameIn2
Chris@140 96 << endl;
Chris@140 97 #endif
Chris@140 98
Chris@105 99 ++m_frameNo;
Chris@105 100 }
Chris@105 101
Chris@106 102 void
Chris@106 103 MatchPipeline::extractFeatures(vector<double> &f1, vector<double> &f2)
Chris@106 104 {
Chris@106 105 f1 = m_f1;
Chris@106 106 f2 = m_f2;
Chris@106 107 }
Chris@106 108
Chris@106 109 void
Chris@106 110 MatchPipeline::extractConditionedFeatures(vector<double> &c1, vector<double> &c2)
Chris@106 111 {
Chris@106 112 c1 = m_c1;
Chris@106 113 c2 = m_c2;
Chris@106 114 }
Chris@106 115
Chris@105 116 bool
Chris@105 117 MatchPipeline::aboveThreshold(const vector<double> &f)
Chris@105 118 {
Chris@140 119 // This threshold is used only to determine when either of the
Chris@140 120 // input streams has ended -- the last frame for a stream is
Chris@140 121 // considered to be the last one that was above the
Chris@140 122 // threshold. This is different from the silence threshold in
Chris@140 123 // FeatureConditioner.
Chris@105 124 double threshold = 1e-4f;
Chris@105 125 double sum = 0.f;
Chris@105 126 for (int i = 0; i < int(f.size()); ++i) {
Chris@105 127 sum += f[i] * f[i];
Chris@105 128 }
Chris@140 129 #ifdef DEBUG_MATCH_PIPELINE
Chris@140 130 cerr << "aboveThreshold: sum " << sum << ", 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@105 140 getFinder()->setDurations(m_lastFrameIn1, m_lastFrameIn2);
Chris@105 141 }
Chris@105 142
Chris@135 143 MatchFeatureFeeder *
Chris@135 144 MatchPipeline::getFeeder()
Chris@135 145 {
Chris@135 146 return &m_feeder;
Chris@135 147 }
Chris@135 148
Chris@105 149 Finder *
Chris@105 150 MatchPipeline::getFinder()
Chris@105 151 {
Chris@105 152 return m_feeder.getFinder();
Chris@105 153 }
Chris@105 154
Chris@105 155
Chris@105 156
Chris@105 157