comparison data/model/AlignmentModel.cpp @ 1738:4abc0f08adf9 by-id

More on alignment models and paths
author Chris Cannam
date Wed, 26 Jun 2019 10:21:15 +0100
parents 5d631f6129fe
children 6d09d68165a4
comparison
equal deleted inserted replaced
1737:5d631f6129fe 1738:4abc0f08adf9
43 AlignmentModel::~AlignmentModel() 43 AlignmentModel::~AlignmentModel()
44 { 44 {
45 #ifdef DEBUG_ALIGNMENT_MODEL 45 #ifdef DEBUG_ALIGNMENT_MODEL
46 SVCERR << "AlignmentModel(" << this << ")::~AlignmentModel()" << endl; 46 SVCERR << "AlignmentModel(" << this << ")::~AlignmentModel()" << endl;
47 #endif 47 #endif
48
49 //!!! if (m_pathSource) m_pathSource->aboutToDelete();
50 // delete m_pathSource;
51
52 // if (m_path) m_path->aboutToDelete();
53 // delete m_path;
54
55 // if (m_reversePath) m_reversePath->aboutToDelete();
56 // delete m_reversePath;
57 } 48 }
58 49
59 bool 50 bool
60 AlignmentModel::isOK() const 51 AlignmentModel::isOK() const
61 { 52 {
169 { 160 {
170 #ifdef DEBUG_ALIGNMENT_MODEL 161 #ifdef DEBUG_ALIGNMENT_MODEL
171 cerr << "AlignmentModel::toReference(" << frame << ")" << endl; 162 cerr << "AlignmentModel::toReference(" << frame << ")" << endl;
172 #endif 163 #endif
173 if (!m_path) { 164 if (!m_path) {
174 if (m_pathSource.isNone()) return frame; 165 if (m_pathSource.isNone()) {
166 return frame;
167 }
175 constructPath(); 168 constructPath();
176 if (!m_path) return frame; 169 }
177 } 170 if (!m_path) {
178 return align(*m_path, frame); 171 return frame;
172 }
173
174 return performAlignment(*m_path, frame);
179 } 175 }
180 176
181 sv_frame_t 177 sv_frame_t
182 AlignmentModel::fromReference(sv_frame_t frame) const 178 AlignmentModel::fromReference(sv_frame_t frame) const
183 { 179 {
184 #ifdef DEBUG_ALIGNMENT_MODEL 180 #ifdef DEBUG_ALIGNMENT_MODEL
185 cerr << "AlignmentModel::fromReference(" << frame << ")" << endl; 181 cerr << "AlignmentModel::fromReference(" << frame << ")" << endl;
186 #endif 182 #endif
187 if (!m_reversePath) { 183 if (!m_reversePath) {
188 if (m_pathSource.isNone()) return frame; 184 if (m_pathSource.isNone()) {
185 return frame;
186 }
189 constructReversePath(); 187 constructReversePath();
190 if (!m_reversePath) return frame; 188 }
191 } 189 if (!m_reversePath) {
192 return align(*m_reversePath, frame); 190 return frame;
193 } 191 }
194 192
195 void 193 return performAlignment(*m_reversePath, frame);
196 AlignmentModel::pathSourceChanged()
197 {
198 if (m_pathComplete) {
199 /*!!!
200 cerr << "AlignmentModel: deleting raw path model" << endl;
201 if (m_pathSource) m_pathSource->aboutToDelete();
202 delete m_pathSource;
203 m_pathSource = nullptr;
204 */
205 m_pathSource = {};
206 }
207 } 194 }
208 195
209 void 196 void
210 AlignmentModel::pathSourceChangedWithin(sv_frame_t, sv_frame_t) 197 AlignmentModel::pathSourceChangedWithin(sv_frame_t, sv_frame_t)
211 { 198 {
261 if (pathSourceModel) { 248 if (pathSourceModel) {
262 cerr << "ERROR: AlignmentModel::constructPath: " 249 cerr << "ERROR: AlignmentModel::constructPath: "
263 << "No raw path available" << endl; 250 << "No raw path available" << endl;
264 return; 251 return;
265 } 252 }
266 m_path.reset(new PathModel 253 m_path.reset(new Path
267 (pathSourceModel->getSampleRate(), 254 (pathSourceModel->getSampleRate(),
268 pathSourceModel->getResolution(), false)); 255 pathSourceModel->getResolution()));
269 } else { 256 } else {
270 if (!pathSourceModel) return; 257 if (!pathSourceModel) return;
271 } 258 }
272 259
273 m_path->clear(); 260 m_path->clear();
293 if (!m_path) { 280 if (!m_path) {
294 cerr << "ERROR: AlignmentModel::constructReversePath: " 281 cerr << "ERROR: AlignmentModel::constructReversePath: "
295 << "No forward path available" << endl; 282 << "No forward path available" << endl;
296 return; 283 return;
297 } 284 }
298 m_reversePath.reset(new PathModel 285 m_reversePath.reset(new Path
299 (m_path->getSampleRate(), 286 (m_path->getSampleRate(),
300 m_path->getResolution(), false)); 287 m_path->getResolution()));
301 } else { 288 } else {
302 if (!m_path) return; 289 if (!m_path) return;
303 } 290 }
304 291
305 m_reversePath->clear(); 292 m_reversePath->clear();
306 293
307 PathModel::PointList points = m_path->getPoints(); 294 Path::Points points = m_path->getPoints();
308 295
309 for (PathModel::PointList::const_iterator i = points.begin(); 296 for (auto p: points) {
310 i != points.end(); ++i) { 297 sv_frame_t frame = p.frame;
311 sv_frame_t frame = i->frame; 298 sv_frame_t rframe = p.mapframe;
312 sv_frame_t rframe = i->mapframe;
313 m_reversePath->add(PathPoint(rframe, frame)); 299 m_reversePath->add(PathPoint(rframe, frame));
314 } 300 }
315 301
316 #ifdef DEBUG_ALIGNMENT_MODEL 302 #ifdef DEBUG_ALIGNMENT_MODEL
317 cerr << "AlignmentModel::constructReversePath: " << m_reversePath->getPointCount() << " points, at least " << (2 * m_reversePath->getPointCount() * (3 * sizeof(void *) + sizeof(int) + sizeof(PathPoint))) << " bytes" << endl; 303 cerr << "AlignmentModel::constructReversePath: " << m_reversePath->getPointCount() << " points, at least " << (2 * m_reversePath->getPointCount() * (3 * sizeof(void *) + sizeof(int) + sizeof(PathPoint))) << " bytes" << endl;
318 #endif 304 #endif
319 } 305 }
320 306
321 sv_frame_t 307 sv_frame_t
322 AlignmentModel::align(const PathModel &path, sv_frame_t frame) const 308 AlignmentModel::performAlignment(const Path &path, sv_frame_t frame) const
323 { 309 {
324 // The path consists of a series of points, each with frame equal 310 // The path consists of a series of points, each with frame equal
325 // to the frame on the source model and mapframe equal to the 311 // to the frame on the source model and mapframe equal to the
326 // frame on the target model. Both should be monotonically 312 // frame on the target model. Both should be monotonically
327 // increasing. 313 // increasing.
328 314
329 const PathModel::PointList &points = path.getPoints(); 315 const Path::Points &points = path.getPoints();
330 316
331 if (points.empty()) { 317 if (points.empty()) {
332 #ifdef DEBUG_ALIGNMENT_MODEL 318 #ifdef DEBUG_ALIGNMENT_MODEL
333 cerr << "AlignmentModel::align: No points" << endl; 319 cerr << "AlignmentModel::align: No points" << endl;
334 #endif 320 #endif
338 #ifdef DEBUG_ALIGNMENT_MODEL 324 #ifdef DEBUG_ALIGNMENT_MODEL
339 cerr << "AlignmentModel::align: frame " << frame << " requested" << endl; 325 cerr << "AlignmentModel::align: frame " << frame << " requested" << endl;
340 #endif 326 #endif
341 327
342 PathPoint point(frame); 328 PathPoint point(frame);
343 PathModel::PointList::const_iterator i = points.lower_bound(point); 329 Path::Points::const_iterator i = points.lower_bound(point);
344 if (i == points.end()) { 330 if (i == points.end()) {
345 #ifdef DEBUG_ALIGNMENT_MODEL 331 #ifdef DEBUG_ALIGNMENT_MODEL
346 cerr << "Note: i == points.end()" << endl; 332 cerr << "Note: i == points.end()" << endl;
347 #endif 333 #endif
348 --i; 334 --i;
349 } 335 }
350 while (i != points.begin() && i->frame > frame) --i; 336 while (i != points.begin() && i->frame > frame) {
337 --i;
338 }
351 339
352 sv_frame_t foundFrame = i->frame; 340 sv_frame_t foundFrame = i->frame;
353 sv_frame_t foundMapFrame = i->mapframe; 341 sv_frame_t foundMapFrame = i->mapframe;
354 342
355 sv_frame_t followingFrame = foundFrame; 343 sv_frame_t followingFrame = foundFrame;
371 cerr << "foundFrame = " << foundFrame << ", foundMapFrame = " << foundMapFrame 359 cerr << "foundFrame = " << foundFrame << ", foundMapFrame = " << foundMapFrame
372 << ", followingFrame = " << followingFrame << ", followingMapFrame = " 360 << ", followingFrame = " << followingFrame << ", followingMapFrame = "
373 << followingMapFrame << endl; 361 << followingMapFrame << endl;
374 #endif 362 #endif
375 363
376 if (foundMapFrame < 0) return 0; 364 if (foundMapFrame < 0) {
365 return 0;
366 }
377 367
378 sv_frame_t resultFrame = foundMapFrame; 368 sv_frame_t resultFrame = foundMapFrame;
379 369
380 if (followingFrame != foundFrame && frame > foundFrame) { 370 if (followingFrame != foundFrame && frame > foundFrame) {
381 double interp = 371 double interp =
398 388
399 auto pathSourceModel = 389 auto pathSourceModel =
400 ModelById::getAs<SparseTimeValueModel>(m_pathSource); 390 ModelById::getAs<SparseTimeValueModel>(m_pathSource);
401 391
402 if (pathSourceModel) { 392 if (pathSourceModel) {
403
404 connect(pathSourceModel.get(), SIGNAL(modelChanged()),
405 this, SLOT(pathSourceChanged()));
406 393
407 connect(pathSourceModel.get(), 394 connect(pathSourceModel.get(),
408 SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)), 395 SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)),
409 this, SLOT(pathSourceChangedWithin(sv_frame_t, sv_frame_t))); 396 this, SLOT(pathSourceChangedWithin(sv_frame_t, sv_frame_t)));
410 397
419 } 406 }
420 } 407 }
421 } 408 }
422 409
423 void 410 void
424 AlignmentModel::setPath(const PathModel &path) 411 AlignmentModel::setPath(const Path &path)
425 { 412 {
426 //!!! if (m_path) m_path->aboutToDelete(); 413 m_path.reset(new Path(path));
427 // delete m_path;
428 m_path = path;
429 m_pathComplete = true; 414 m_pathComplete = true;
430 #ifdef DEBUG_ALIGNMENT_MODEL
431 cerr << "AlignmentModel::setPath: path = " << m_path << endl;
432 #endif
433 constructReversePath(); 415 constructReversePath();
434 #ifdef DEBUG_ALIGNMENT_MODEL
435 cerr << "AlignmentModel::setPath: after construction path = "
436 << m_path << ", rpath = " << m_reversePath << endl;
437 #endif
438 } 416 }
439 417
440 void 418 void
441 AlignmentModel::toXml(QTextStream &stream, 419 AlignmentModel::toXml(QTextStream &stream,
442 QString indent, 420 QString indent,
449 427
450 m_path->toXml(stream, indent, ""); 428 m_path->toXml(stream, indent, "");
451 429
452 Model::toXml(stream, indent, 430 Model::toXml(stream, indent,
453 QString("type=\"alignment\" reference=\"%1\" aligned=\"%2\" path=\"%3\" %4") 431 QString("type=\"alignment\" reference=\"%1\" aligned=\"%2\" path=\"%3\" %4")
454 .arg(m_reference->getExportId()) 432 .arg(ModelById::getExportId(m_reference))
455 .arg(m_aligned->getExportId()) 433 .arg(ModelById::getExportId(m_aligned))
456 .arg(m_path->getExportId()) 434 .arg(m_path->getExportId())
457 .arg(extraAttributes)); 435 .arg(extraAttributes));
458 } 436 }
459
460