Mercurial > hg > svcore
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 |
