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.
|
Chris@236
|
8 Copyright (c) 2007-2020 Simon Dixon, Chris Cannam, and Queen Mary
|
Chris@230
|
9 University of London, Copyright (c) 2014-2015 Tido GmbH.
|
cannam@0
|
10
|
cannam@0
|
11 This program is free software; you can redistribute it and/or
|
cannam@0
|
12 modify it under the terms of the GNU General Public License as
|
cannam@0
|
13 published by the Free Software Foundation; either version 2 of the
|
cannam@0
|
14 License, or (at your option) any later version. See the file
|
cannam@0
|
15 COPYING included with this distribution for more information.
|
cannam@0
|
16 */
|
cannam@0
|
17
|
Chris@24
|
18 #include "MatchFeatureFeeder.h"
|
cannam@0
|
19
|
Chris@14
|
20 using std::vector;
|
Chris@235
|
21 using std::cerr;
|
Chris@235
|
22 using std::endl;
|
Chris@14
|
23
|
Chris@24
|
24 MatchFeatureFeeder::MatchFeatureFeeder(Matcher *m1, Matcher *m2) :
|
Chris@167
|
25 m_pm1(m1),
|
Chris@167
|
26 m_pm2(m2),
|
Chris@167
|
27 m_finder(m_pm1)
|
cannam@0
|
28 {
|
cannam@0
|
29 }
|
cannam@0
|
30
|
Chris@24
|
31 MatchFeatureFeeder::~MatchFeatureFeeder()
|
cannam@0
|
32 {
|
cannam@0
|
33 }
|
cannam@0
|
34
|
Chris@154
|
35 void
|
Chris@183
|
36 MatchFeatureFeeder::feed(feature_t f1, feature_t f2)
|
cannam@0
|
37 {
|
Chris@49
|
38 // We maintain two FIFO queues of feature vectors, one per input
|
Chris@49
|
39 // stream. When the match-feeder function is entered, it knows
|
Chris@49
|
40 // that it has at least one feature in each queue. It loops,
|
Chris@49
|
41 // processing up to one feature per matcher, until a queue is
|
Chris@49
|
42 // empty. Then it returns, to be called again with more data.
|
Chris@49
|
43
|
Chris@60
|
44 if (!f1.empty()) {
|
Chris@74
|
45 m_q1.push(f1);
|
Chris@60
|
46 }
|
Chris@60
|
47
|
Chris@60
|
48 if (!f2.empty()) {
|
Chris@74
|
49 m_q2.push(f2);
|
Chris@60
|
50 }
|
Chris@14
|
51
|
Chris@74
|
52 while (!m_q1.empty() && !m_q2.empty()) {
|
Chris@63
|
53 feedBlock();
|
Chris@63
|
54 }
|
Chris@63
|
55 }
|
Chris@63
|
56
|
Chris@167
|
57 int
|
Chris@167
|
58 MatchFeatureFeeder::getEstimatedReferenceFrame()
|
Chris@167
|
59 {
|
Chris@167
|
60 if (m_pm1->getFrameCount() == 0 || m_pm2->getFrameCount() == 0) {
|
Chris@167
|
61 return 0;
|
Chris@167
|
62 }
|
Chris@167
|
63 int bestRow = 0;
|
Chris@191
|
64 normpathcost_t bestCost = 0;
|
Chris@167
|
65 if (!m_finder.getBestColCost(m_pm2->getFrameCount()-1, bestRow, bestCost)) {
|
Chris@167
|
66 return -1;
|
Chris@167
|
67 } else {
|
Chris@167
|
68 return bestRow;
|
Chris@167
|
69 }
|
Chris@167
|
70 }
|
Chris@167
|
71
|
Chris@63
|
72 void
|
Chris@63
|
73 MatchFeatureFeeder::finish()
|
Chris@63
|
74 {
|
Chris@74
|
75 while (!m_q1.empty() || !m_q2.empty()) {
|
Chris@24
|
76 feedBlock();
|
Chris@14
|
77 }
|
Chris@200
|
78
|
Chris@200
|
79 // cerr << "MatchFeatureFeeder::finish: have " << m_pm1->getFrameCount()
|
Chris@200
|
80 // << " reference and " << m_pm2->getFrameCount() << " other frames"
|
Chris@200
|
81 // << endl;
|
Chris@14
|
82 }
|
Chris@14
|
83
|
Chris@24
|
84 void
|
Chris@24
|
85 MatchFeatureFeeder::feedBlock()
|
Chris@14
|
86 {
|
Chris@74
|
87 if (m_q1.empty()) { // ended
|
Chris@60
|
88 feed2();
|
Chris@74
|
89 } else if (m_q2.empty()) { // ended
|
Chris@60
|
90 feed1();
|
Chris@171
|
91 } else if (m_pm1->isFillingInitialBlock()) {
|
Chris@24
|
92 feed1();
|
Chris@24
|
93 feed2();
|
Chris@78
|
94 } else if (m_pm1->isOverrunning()) { // slope constraints
|
Chris@24
|
95 feed2();
|
Chris@78
|
96 } else if (m_pm2->isOverrunning()) {
|
Chris@24
|
97 feed1();
|
cannam@0
|
98 } else {
|
Chris@171
|
99 switch (m_finder.getExpandDirection()) {
|
Chris@181
|
100 case AdvanceThis:
|
Chris@24
|
101 feed1();
|
cannam@0
|
102 break;
|
Chris@181
|
103 case AdvanceOther:
|
Chris@24
|
104 feed2();
|
cannam@0
|
105 break;
|
Chris@181
|
106 case AdvanceBoth:
|
Chris@24
|
107 feed1();
|
Chris@24
|
108 feed2();
|
cannam@0
|
109 break;
|
Chris@181
|
110 case AdvanceNone:
|
Chris@74
|
111 cerr << "m_finder says AdvanceNone!" << endl;
|
Chris@45
|
112 break;
|
cannam@0
|
113 }
|
cannam@0
|
114 }
|
Chris@135
|
115
|
Chris@135
|
116 m_fpx.push_back(m_pm2->getFrameCount());
|
Chris@135
|
117 m_fpy.push_back(m_pm1->getFrameCount());
|
cannam@0
|
118 }
|
cannam@0
|
119
|
Chris@24
|
120 void
|
Chris@24
|
121 MatchFeatureFeeder::feed1()
|
cannam@0
|
122 {
|
Chris@74
|
123 m_pm1->consumeFeatureVector(m_q1.front());
|
Chris@74
|
124 m_q1.pop();
|
cannam@0
|
125 }
|
cannam@0
|
126
|
Chris@24
|
127 void
|
Chris@24
|
128 MatchFeatureFeeder::feed2()
|
cannam@0
|
129 {
|
Chris@74
|
130 m_pm2->consumeFeatureVector(m_q2.front());
|
Chris@74
|
131 m_q2.pop();
|
cannam@0
|
132 }
|
cannam@0
|
133
|