Mercurial > hg > match-vamp
comparison src/Matcher.cpp @ 43:6a5d165e5ea4 refactors
refactor: m_ prefix
author | Chris Cannam |
---|---|
date | Thu, 13 Nov 2014 13:53:52 +0000 |
parents | 9aec2304b9f6 |
children | a1b7df871496 |
comparison
equal
deleted
inserted
replaced
42:8dd16749c3c3 | 43:6a5d165e5ea4 |
---|---|
19 #include <iostream> | 19 #include <iostream> |
20 | 20 |
21 #include <cstdlib> | 21 #include <cstdlib> |
22 #include <cassert> | 22 #include <cassert> |
23 | 23 |
24 bool Matcher::silent = true; | |
25 | |
26 //#define DEBUG_MATCHER 1 | 24 //#define DEBUG_MATCHER 1 |
27 | 25 |
28 Matcher::Matcher(Parameters parameters, | 26 Matcher::Matcher(Parameters parameters, |
29 FeatureExtractor::Parameters feParams, | 27 FeatureExtractor::Parameters feParams, |
30 Matcher *p) : | 28 Matcher *p) : |
31 params(parameters), | 29 m_params(parameters), |
32 featureExtractor(feParams), | 30 m_featureExtractor(feParams), |
33 metric(parameters.distanceNorm) | 31 m_metric(parameters.distanceNorm) |
34 { | 32 { |
35 #ifdef DEBUG_MATCHER | 33 #ifdef DEBUG_MATCHER |
36 cerr << "Matcher::Matcher(" << params.sampleRate << ", " << p << ")" << endl; | 34 cerr << "Matcher::Matcher(" << m_params.sampleRate << ", " << p << ")" << endl; |
37 #endif | 35 #endif |
38 | 36 |
39 otherMatcher = p; // the first matcher will need this to be set later | 37 m_otherMatcher = p; // the first matcher will need this to be set later |
40 firstPM = (!p); | 38 m_firstPM = (!p); |
41 frameCount = 0; | 39 m_frameCount = 0; |
42 runCount = 0; | 40 m_runCount = 0; |
43 featureSize = featureExtractor.getFeatureSize(); | 41 m_featureSize = m_featureExtractor.getFeatureSize(); |
44 blockSize = 0; | 42 m_blockSize = 0; |
45 | 43 |
46 blockSize = lrint(params.blockTime / params.hopTime); | 44 m_blockSize = lrint(m_params.blockTime / m_params.hopTime); |
47 #ifdef DEBUG_MATCHER | 45 #ifdef DEBUG_MATCHER |
48 cerr << "Matcher: blockSize = " << blockSize << endl; | 46 cerr << "Matcher: m_blockSize = " << m_blockSize << endl; |
49 #endif | 47 #endif |
50 | 48 |
51 initialised = false; | 49 m_initialised = false; |
52 } | 50 } |
53 | 51 |
54 Matcher::Matcher(Parameters parameters, Matcher *p, int featureSize_) : | 52 Matcher::Matcher(Parameters parameters, Matcher *p, int m_featureSize_) : |
55 params(parameters), | 53 m_params(parameters), |
56 featureSize(featureSize_), | 54 m_featureSize(m_featureSize_), |
57 featureExtractor(FeatureExtractor::Parameters(params.sampleRate, params.fftSize)), // unused default config | 55 m_featureExtractor(FeatureExtractor::Parameters(m_params.sampleRate, m_params.fftSize)), // unused default config |
58 metric(parameters.distanceNorm) | 56 m_metric(parameters.distanceNorm) |
59 { | 57 { |
60 #ifdef DEBUG_MATCHER | 58 #ifdef DEBUG_MATCHER |
61 cerr << "Matcher::Matcher(" << params.sampleRate << ", " << p << ", " << featureSize << ")" << endl; | 59 cerr << "Matcher::Matcher(" << m_params.sampleRate << ", " << p << ", " << m_featureSize << ")" << endl; |
62 #endif | 60 #endif |
63 | 61 |
64 otherMatcher = p; // the first matcher will need this to be set later | 62 m_otherMatcher = p; // the first matcher will need this to be set later |
65 firstPM = (!p); | 63 m_firstPM = (!p); |
66 frameCount = 0; | 64 m_frameCount = 0; |
67 runCount = 0; | 65 m_runCount = 0; |
68 blockSize = 0; | 66 m_blockSize = 0; |
69 | 67 |
70 blockSize = lrint(params.blockTime / params.hopTime); | 68 m_blockSize = lrint(m_params.blockTime / m_params.hopTime); |
71 #ifdef DEBUG_MATCHER | 69 #ifdef DEBUG_MATCHER |
72 cerr << "Matcher: blockSize = " << blockSize << endl; | 70 cerr << "Matcher: m_blockSize = " << m_blockSize << endl; |
73 #endif | 71 #endif |
74 | 72 |
75 initialised = false; | 73 m_initialised = false; |
76 } | 74 } |
77 | 75 |
78 Matcher::~Matcher() | 76 Matcher::~Matcher() |
79 { | 77 { |
80 #ifdef DEBUG_MATCHER | 78 #ifdef DEBUG_MATCHER |
83 } | 81 } |
84 | 82 |
85 void | 83 void |
86 Matcher::init() | 84 Matcher::init() |
87 { | 85 { |
88 if (initialised) return; | 86 if (m_initialised) return; |
89 | 87 |
90 frames = vector<vector<double> > | 88 m_frames = vector<vector<double> > |
91 (blockSize, vector<double>(featureSize, 0)); | 89 (m_blockSize, vector<double>(m_featureSize, 0)); |
92 | 90 |
93 distXSize = blockSize * 2; | 91 m_distXSize = m_blockSize * 2; |
94 size(); | 92 size(); |
95 | 93 |
96 frameCount = 0; | 94 m_frameCount = 0; |
97 runCount = 0; | 95 m_runCount = 0; |
98 | 96 |
99 initialised = true; | 97 m_initialised = true; |
100 } | 98 } |
101 | 99 |
102 void | 100 void |
103 Matcher::size() | 101 Matcher::size() |
104 { | 102 { |
105 int distSize = (params.maxRunCount + 1) * blockSize; | 103 int distSize = (m_params.maxRunCount + 1) * m_blockSize; |
106 bestPathCost.resize(distXSize, vector<int>(distSize, 0)); | 104 m_bestPathCost.resize(m_distXSize, vector<int>(distSize, 0)); |
107 distance.resize(distXSize, vector<unsigned char>(distSize, 0)); | 105 m_distance.resize(m_distXSize, vector<unsigned char>(distSize, 0)); |
108 distYSizes.resize(distXSize, distSize); | 106 m_distYSizes.resize(m_distXSize, distSize); |
109 first.resize(distXSize, 0); | 107 m_first.resize(m_distXSize, 0); |
110 last.resize(distXSize, 0); | 108 m_last.resize(m_distXSize, 0); |
111 } | 109 } |
112 | 110 |
113 vector<double> | 111 vector<double> |
114 Matcher::consumeFrame(double *reBuffer, double *imBuffer) | 112 Matcher::consumeFrame(double *reBuffer, double *imBuffer) |
115 { | 113 { |
116 if (!initialised) init(); | 114 if (!m_initialised) init(); |
117 | 115 |
118 vector<double> real(reBuffer, reBuffer + params.fftSize/2 + 1); | 116 vector<double> real(reBuffer, reBuffer + m_params.fftSize/2 + 1); |
119 vector<double> imag(imBuffer, imBuffer + params.fftSize/2 + 1); | 117 vector<double> imag(imBuffer, imBuffer + m_params.fftSize/2 + 1); |
120 vector<double> feature = featureExtractor.process(real, imag); | 118 vector<double> feature = m_featureExtractor.process(real, imag); |
121 int frameIndex = frameCount % blockSize; | 119 int frameIndex = m_frameCount % m_blockSize; |
122 frames[frameIndex] = feature; | 120 m_frames[frameIndex] = feature; |
123 calcAdvance(); | 121 calcAdvance(); |
124 | 122 |
125 return feature; | 123 return feature; |
126 } | 124 } |
127 | 125 |
128 void | 126 void |
129 Matcher::consumeFeatureVector(std::vector<double> feature) | 127 Matcher::consumeFeatureVector(std::vector<double> feature) |
130 { | 128 { |
131 if (!initialised) init(); | 129 if (!m_initialised) init(); |
132 int frameIndex = frameCount % blockSize; | 130 int frameIndex = m_frameCount % m_blockSize; |
133 frames[frameIndex] = feature; | 131 m_frames[frameIndex] = feature; |
134 calcAdvance(); | 132 calcAdvance(); |
135 } | 133 } |
136 | 134 |
137 void | 135 void |
138 Matcher::calcAdvance() | 136 Matcher::calcAdvance() |
139 { | 137 { |
140 int frameIndex = frameCount % blockSize; | 138 int frameIndex = m_frameCount % m_blockSize; |
141 | 139 |
142 if (frameCount >= distXSize) { | 140 if (m_frameCount >= m_distXSize) { |
143 distXSize *= 2; | 141 m_distXSize *= 2; |
144 size(); | 142 size(); |
145 } | 143 } |
146 | 144 |
147 if (firstPM && (frameCount >= blockSize)) { | 145 if (m_firstPM && (m_frameCount >= m_blockSize)) { |
148 | 146 |
149 int len = last[frameCount - blockSize] - | 147 int len = m_last[m_frameCount - m_blockSize] - |
150 first[frameCount - blockSize]; | 148 m_first[m_frameCount - m_blockSize]; |
151 | 149 |
152 // We need to copy distance[frameCount-blockSize] to | 150 // We need to copy distance[m_frameCount-m_blockSize] to |
153 // distance[frameCount], and then truncate | 151 // distance[m_frameCount], and then truncate |
154 // distance[frameCount-blockSize] to its first len elements. | 152 // distance[m_frameCount-m_blockSize] to its first len elements. |
155 // Same for bestPathCost. | 153 // Same for bestPathCost. |
156 /* | 154 /* |
157 std::cerr << "Matcher(" << this << "): moving " << distYSizes[frameCount - blockSize] << " from " << frameCount - blockSize << " to " | 155 std::cerr << "Matcher(" << this << "): moving " << distYSizes[m_frameCount - m_blockSize] << " from " << m_frameCount - m_blockSize << " to " |
158 << frameCount << ", allocating " << len << " for " | 156 << m_frameCount << ", allocating " << len << " for " |
159 << frameCount - blockSize << std::endl; | 157 << m_frameCount - m_blockSize << std::endl; |
160 */ | 158 */ |
161 distance[frameCount] = distance[frameCount - blockSize]; | 159 m_distance[m_frameCount] = m_distance[m_frameCount - m_blockSize]; |
162 distance[frameCount - blockSize].resize(len, 0); | 160 m_distance[m_frameCount - m_blockSize].resize(len, 0); |
163 for (int i = 0; i < len; ++i) { | 161 for (int i = 0; i < len; ++i) { |
164 distance[frameCount - blockSize][i] = | 162 m_distance[m_frameCount - m_blockSize][i] = |
165 distance[frameCount][i]; | 163 m_distance[m_frameCount][i]; |
166 } | 164 } |
167 | 165 |
168 bestPathCost[frameCount] = bestPathCost[frameCount - blockSize]; | 166 m_bestPathCost[m_frameCount] = m_bestPathCost[m_frameCount - m_blockSize]; |
169 bestPathCost[frameCount - blockSize].resize(len, 0); | 167 m_bestPathCost[m_frameCount - m_blockSize].resize(len, 0); |
170 for (int i = 0; i < len; ++i) { | 168 for (int i = 0; i < len; ++i) { |
171 bestPathCost[frameCount - blockSize][i] = | 169 m_bestPathCost[m_frameCount - m_blockSize][i] = |
172 bestPathCost[frameCount][i]; | 170 m_bestPathCost[m_frameCount][i]; |
173 } | 171 } |
174 | 172 |
175 distYSizes[frameCount] = distYSizes[frameCount - blockSize]; | 173 m_distYSizes[m_frameCount] = m_distYSizes[m_frameCount - m_blockSize]; |
176 distYSizes[frameCount - blockSize] = len; | 174 m_distYSizes[m_frameCount - m_blockSize] = len; |
177 } | 175 } |
178 | 176 |
179 int stop = otherMatcher->frameCount; | 177 int stop = m_otherMatcher->m_frameCount; |
180 int index = stop - blockSize; | 178 int index = stop - m_blockSize; |
181 if (index < 0) | 179 if (index < 0) |
182 index = 0; | 180 index = 0; |
183 first[frameCount] = index; | 181 m_first[m_frameCount] = index; |
184 last[frameCount] = stop; | 182 m_last[m_frameCount] = stop; |
185 | 183 |
186 bool overflow = false; | 184 bool overflow = false; |
187 int mn= -1; | 185 int mn= -1; |
188 int mx= -1; | 186 int mx= -1; |
189 for ( ; index < stop; index++) { | 187 for ( ; index < stop; index++) { |
190 | 188 |
191 int dMN = metric.calcDistanceScaled | 189 int dMN = m_metric.calcDistanceScaled |
192 (frames[frameIndex], | 190 (m_frames[frameIndex], |
193 otherMatcher->frames[index % blockSize], | 191 m_otherMatcher->m_frames[index % m_blockSize], |
194 params.distanceScale); | 192 m_params.distanceScale); |
195 | 193 |
196 if (mx<0) | 194 if (mx<0) |
197 mx = mn = dMN; | 195 mx = mn = dMN; |
198 else if (dMN > mx) | 196 else if (dMN > mx) |
199 mx = dMN; | 197 mx = dMN; |
202 if (dMN >= 255) { | 200 if (dMN >= 255) { |
203 overflow = true; | 201 overflow = true; |
204 dMN = 255; | 202 dMN = 255; |
205 } | 203 } |
206 | 204 |
207 if ((frameCount == 0) && (index == 0)) // first element | 205 if ((m_frameCount == 0) && (index == 0)) // first element |
208 setValue(0, 0, 0, 0, dMN); | 206 setValue(0, 0, 0, 0, dMN); |
209 else if (frameCount == 0) // first row | 207 else if (m_frameCount == 0) // first row |
210 setValue(0, index, ADVANCE_OTHER, | 208 setValue(0, index, ADVANCE_OTHER, |
211 getValue(0, index-1, true), dMN); | 209 getValue(0, index-1, true), dMN); |
212 else if (index == 0) // first column | 210 else if (index == 0) // first column |
213 setValue(frameCount, index, ADVANCE_THIS, | 211 setValue(m_frameCount, index, ADVANCE_THIS, |
214 getValue(frameCount - 1, 0, true), dMN); | 212 getValue(m_frameCount - 1, 0, true), dMN); |
215 else if (index == otherMatcher->frameCount - blockSize) { | 213 else if (index == m_otherMatcher->m_frameCount - m_blockSize) { |
216 // missing value(s) due to cutoff | 214 // missing value(s) due to cutoff |
217 // - no previous value in current row (resp. column) | 215 // - no previous value in current row (resp. column) |
218 // - no diagonal value if prev. dir. == curr. dirn | 216 // - no diagonal value if prev. dir. == curr. dirn |
219 int min2 = getValue(frameCount - 1, index, true); | 217 int min2 = getValue(m_frameCount - 1, index, true); |
220 // if ((firstPM && (first[frameCount - 1] == index)) || | 218 // if ((m_firstPM && (first[m_frameCount - 1] == index)) || |
221 // (!firstPM && (last[index-1] < frameCount))) | 219 // (!m_firstPM && (m_last[index-1] < m_frameCount))) |
222 if (first[frameCount - 1] == index) | 220 if (m_first[m_frameCount - 1] == index) |
223 setValue(frameCount, index, ADVANCE_THIS, min2, dMN); | 221 setValue(m_frameCount, index, ADVANCE_THIS, min2, dMN); |
224 else { | 222 else { |
225 int min1 = getValue(frameCount - 1, index - 1, true); | 223 int min1 = getValue(m_frameCount - 1, index - 1, true); |
226 if (min1 + dMN <= min2) | 224 if (min1 + dMN <= min2) |
227 setValue(frameCount, index, ADVANCE_BOTH, min1,dMN); | 225 setValue(m_frameCount, index, ADVANCE_BOTH, min1,dMN); |
228 else | 226 else |
229 setValue(frameCount, index, ADVANCE_THIS, min2,dMN); | 227 setValue(m_frameCount, index, ADVANCE_THIS, min2,dMN); |
230 } | 228 } |
231 } else { | 229 } else { |
232 int min1 = getValue(frameCount, index-1, true); | 230 int min1 = getValue(m_frameCount, index-1, true); |
233 int min2 = getValue(frameCount - 1, index, true); | 231 int min2 = getValue(m_frameCount - 1, index, true); |
234 int min3 = getValue(frameCount - 1, index-1, true); | 232 int min3 = getValue(m_frameCount - 1, index-1, true); |
235 if (min1 <= min2) { | 233 if (min1 <= min2) { |
236 if (min3 + dMN <= min1) | 234 if (min3 + dMN <= min1) |
237 setValue(frameCount, index, ADVANCE_BOTH, min3,dMN); | 235 setValue(m_frameCount, index, ADVANCE_BOTH, min3,dMN); |
238 else | 236 else |
239 setValue(frameCount, index, ADVANCE_OTHER,min1,dMN); | 237 setValue(m_frameCount, index, ADVANCE_OTHER,min1,dMN); |
240 } else { | 238 } else { |
241 if (min3 + dMN <= min2) | 239 if (min3 + dMN <= min2) |
242 setValue(frameCount, index, ADVANCE_BOTH, min3,dMN); | 240 setValue(m_frameCount, index, ADVANCE_BOTH, min3,dMN); |
243 else | 241 else |
244 setValue(frameCount, index, ADVANCE_THIS, min2,dMN); | 242 setValue(m_frameCount, index, ADVANCE_THIS, min2,dMN); |
245 } | 243 } |
246 } | 244 } |
247 otherMatcher->last[index]++; | 245 m_otherMatcher->m_last[index]++; |
248 } // loop for row (resp. column) | 246 } // loop for row (resp. column) |
249 | 247 |
250 frameCount++; | 248 m_frameCount++; |
251 runCount++; | 249 m_runCount++; |
252 | 250 |
253 otherMatcher->runCount = 0; | 251 m_otherMatcher->m_runCount = 0; |
254 | 252 |
255 if (overflow && !silent) | 253 if (overflow) { |
256 cerr << "WARNING: overflow in distance metric: " | 254 cerr << "WARNING: overflow in distance metric: " |
257 << "frame " << frameCount << ", val = " << mx << endl; | 255 << "frame " << m_frameCount << ", val = " << mx << endl; |
258 | 256 } |
259 if (!silent) | |
260 std::cerr << "Frame " << frameCount << ", d = " << (mx-mn) << std::endl; | |
261 } | 257 } |
262 | 258 |
263 int | 259 int |
264 Matcher::getValue(int i, int j, bool firstAttempt) | 260 Matcher::getValue(int i, int j, bool firstAttempt) |
265 { | 261 { |
266 if (firstPM) | 262 if (m_firstPM) |
267 return bestPathCost[i][j - first[i]]; | 263 return m_bestPathCost[i][j - m_first[i]]; |
268 else | 264 else |
269 return otherMatcher->bestPathCost[j][i - otherMatcher->first[j]]; | 265 return m_otherMatcher->m_bestPathCost[j][i - m_otherMatcher->m_first[j]]; |
270 } // getValue() | 266 } // getValue() |
271 | 267 |
272 void | 268 void |
273 Matcher::setValue(int i, int j, int dir, int value, int dMN) | 269 Matcher::setValue(int i, int j, int dir, int value, int dMN) |
274 { | 270 { |
275 if (firstPM) { | 271 if (m_firstPM) { |
276 distance[i][j - first[i]] = (unsigned char)((dMN & MASK) | dir); | 272 m_distance[i][j - m_first[i]] = (unsigned char)((dMN & MASK) | dir); |
277 bestPathCost[i][j - first[i]] = | 273 m_bestPathCost[i][j - m_first[i]] = |
278 (value + (dir==ADVANCE_BOTH? dMN*2: dMN)); | 274 (value + (dir==ADVANCE_BOTH? dMN*2: dMN)); |
279 } else { | 275 } else { |
280 if (dir == ADVANCE_THIS) | 276 if (dir == ADVANCE_THIS) |
281 dir = ADVANCE_OTHER; | 277 dir = ADVANCE_OTHER; |
282 else if (dir == ADVANCE_OTHER) | 278 else if (dir == ADVANCE_OTHER) |
283 dir = ADVANCE_THIS; | 279 dir = ADVANCE_THIS; |
284 int idx = i - otherMatcher->first[j]; | 280 int idx = i - m_otherMatcher->m_first[j]; |
285 if (idx == (int)otherMatcher->distYSizes[j]) { | 281 if (idx == (int)m_otherMatcher->m_distYSizes[j]) { |
286 // This should never happen, but if we allow arbitrary | 282 // This should never happen, but if we allow arbitrary |
287 // pauses in either direction, and arbitrary lengths at | 283 // pauses in either direction, and arbitrary lengths at |
288 // end, it is better than a segmentation fault. | 284 // end, it is better than a segmentation fault. |
289 std::cerr << "Emergency resize: " << idx << " -> " << idx * 2 << std::endl; | 285 std::cerr << "Emergency resize: " << idx << " -> " << idx * 2 << std::endl; |
290 otherMatcher->distYSizes[j] = idx * 2; | 286 m_otherMatcher->m_distYSizes[j] = idx * 2; |
291 otherMatcher->bestPathCost[j].resize(idx * 2, 0); | 287 m_otherMatcher->m_bestPathCost[j].resize(idx * 2, 0); |
292 otherMatcher->distance[j].resize(idx * 2, 0); | 288 m_otherMatcher->m_distance[j].resize(idx * 2, 0); |
293 } | 289 } |
294 otherMatcher->distance[j][idx] = (unsigned char)((dMN & MASK) | dir); | 290 m_otherMatcher->m_distance[j][idx] = (unsigned char)((dMN & MASK) | dir); |
295 otherMatcher->bestPathCost[j][idx] = | 291 m_otherMatcher->m_bestPathCost[j][idx] = |
296 (value + (dir==ADVANCE_BOTH? dMN*2: dMN)); | 292 (value + (dir==ADVANCE_BOTH? dMN*2: dMN)); |
297 } | 293 } |
298 } // setValue() | 294 } // setValue() |
299 | 295 |