Mercurial > hg > match-vamp
comparison src/MatchFeeder.cpp @ 60:faa523be20f9 refactors_no_float
Update both Feeders so as to recognise the end of one input before the other has ended. MatchFeeder does this by detecting trailing silence (as both its inputs are technically the same length since the shorter is zero-padded) and reporting that to Finder. MatchFeatureFeeder simply recognises missing features at the end and won't queue them.
author | Chris Cannam |
---|---|
date | Fri, 14 Nov 2014 13:53:58 +0000 |
parents | 6a5d165e5ea4 |
children | 19a93b15fcc3 a540137d393b |
comparison
equal
deleted
inserted
replaced
57:47f7649ab9d5 | 60:faa523be20f9 |
---|---|
17 #include "MatchFeeder.h" | 17 #include "MatchFeeder.h" |
18 | 18 |
19 using std::vector; | 19 using std::vector; |
20 | 20 |
21 MatchFeeder::MatchFeeder(Matcher *m1, Matcher *m2) : | 21 MatchFeeder::MatchFeeder(Matcher *m1, Matcher *m2) : |
22 pm1(m1), pm2(m2) | 22 pm1(m1), pm2(m2), n(0), lastIn1(0), lastIn2(0) |
23 { | 23 { |
24 fftSize = m1->m_params.fftSize; | 24 fftSize = m1->m_params.fftSize; |
25 finder = new Finder(m1, m2); | 25 finder = new Finder(m1, m2); |
26 reBuffer = new double[fftSize/2+1]; | 26 reBuffer = new double[fftSize/2+1]; |
27 imBuffer = new double[fftSize/2+1]; | 27 imBuffer = new double[fftSize/2+1]; |
51 // It loops, processing up to one block per matcher, until a queue | 51 // It loops, processing up to one block per matcher, until a queue |
52 // is empty. Then it returns, to be called again with more data. | 52 // is empty. Then it returns, to be called again with more data. |
53 | 53 |
54 prepare(input); | 54 prepare(input); |
55 | 55 |
56 while (!q1.empty() && !q2.empty()) { | 56 while (!q1.empty() || !q2.empty()) { |
57 // std::cerr << "MatchFeeder::feed: q1 " << q1.size() << " q2 " << q2.size() << std::endl; | 57 // std::cerr << "MatchFeeder::feed: q1 " << q1.size() << " q2 " << q2.size() << std::endl; |
58 (void)feedBlock(); | 58 (void)feedBlock(); |
59 } | 59 } |
60 } | 60 } |
61 | 61 |
64 { | 64 { |
65 prepare(input); | 65 prepare(input); |
66 | 66 |
67 Features all; | 67 Features all; |
68 | 68 |
69 while (!q1.empty() && !q2.empty()) { | 69 while (!q1.empty() || !q2.empty()) { |
70 Features ff = feedBlock(); | 70 Features ff = feedBlock(); |
71 all.f1.insert(all.f1.end(), ff.f1.begin(), ff.f1.end()); | 71 all.f1.insert(all.f1.end(), ff.f1.begin(), ff.f1.end()); |
72 all.f2.insert(all.f2.end(), ff.f2.begin(), ff.f2.end()); | 72 all.f2.insert(all.f2.end(), ff.f2.begin(), ff.f2.end()); |
73 } | 73 } |
74 | 74 |
76 } | 76 } |
77 | 77 |
78 void | 78 void |
79 MatchFeeder::prepare(const float *const *input) | 79 MatchFeeder::prepare(const float *const *input) |
80 { | 80 { |
81 float threshold = 1e-5; | |
82 | |
81 float *block = new float[fftSize+2]; | 83 float *block = new float[fftSize+2]; |
84 float rms = 0; | |
85 | |
82 for (size_t i = 0; i < fftSize+2; ++i) { | 86 for (size_t i = 0; i < fftSize+2; ++i) { |
83 block[i] = input[0][i]; | 87 block[i] = input[0][i]; |
88 rms += block[i] * block[i]; | |
89 } | |
90 rms = sqrtf(rms / (fftSize+2)); | |
91 if (rms > threshold) { | |
92 lastIn1 = n; | |
84 } | 93 } |
85 q1.push(block); | 94 q1.push(block); |
86 | 95 |
87 block = new float[fftSize+2]; | 96 block = new float[fftSize+2]; |
97 rms = 0; | |
98 | |
88 for (size_t i = 0; i < fftSize+2; ++i) { | 99 for (size_t i = 0; i < fftSize+2; ++i) { |
89 block[i] = input[1][i]; | 100 block[i] = input[1][i]; |
101 rms += block[i] * block[i]; | |
102 } | |
103 rms = sqrtf(rms / (fftSize+2)); | |
104 if (rms > threshold) { | |
105 lastIn2 = n; | |
90 } | 106 } |
91 q2.push(block); | 107 q2.push(block); |
108 | |
109 ++n; | |
110 finder->setDurations(lastIn1, lastIn2); | |
92 } | 111 } |
93 | 112 |
94 MatchFeeder::Features | 113 MatchFeeder::Features |
95 MatchFeeder::feedBlock() | 114 MatchFeeder::feedBlock() |
96 { | 115 { |
97 Features ff; | 116 Features ff; |
98 vector<double> f1, f2; | 117 vector<double> f1, f2; |
99 | 118 |
100 if (pm1->m_frameCount < pm1->m_blockSize) { // fill initial block | 119 if (q1.empty()) { |
120 feed2(); | |
121 } else if (q2.empty()) { | |
122 feed1(); | |
123 } else if (pm1->m_frameCount < pm1->m_blockSize) { // fill initial block | |
101 // std::cerr << "feeding initial block" << std::endl; | 124 // std::cerr << "feeding initial block" << std::endl; |
102 f1 = feed1(); | 125 f1 = feed1(); |
103 f2 = feed2(); | 126 f2 = feed2(); |
104 } | 127 } else if (pm1->m_runCount >= pm1->m_params.maxRunCount) { // slope constraints |
105 //!!! } else if (pm1->atEnd) { | |
106 // feed2(); | |
107 //!!! } else if (pm2->atEnd) | |
108 // feed1(); | |
109 else if (pm1->m_runCount >= pm1->m_params.maxRunCount) { // slope constraints | |
110 // std::cerr << "pm1 too slopey" << std::endl; | 128 // std::cerr << "pm1 too slopey" << std::endl; |
111 f2 = feed2(); | 129 f2 = feed2(); |
112 } else if (pm2->m_runCount >= pm2->m_params.maxRunCount) { | 130 } else if (pm2->m_runCount >= pm2->m_params.maxRunCount) { |
113 // std::cerr << "pm2 too slopey" << std::endl; | 131 // std::cerr << "pm2 too slopey" << std::endl; |
114 f1 = feed1(); | 132 f1 = feed1(); |