comparison rdf/RDFImporter.cpp @ 1752:6d09d68165a4 by-id

Further review of ById: make IDs only available when adding a model to the ById store, not by querying the item directly. This means any id encountered in the wild must have been added to the store at some point (even if later released), which simplifies reasoning about lifecycles
author Chris Cannam
date Fri, 05 Jul 2019 15:28:07 +0100
parents 565575463752
children d484490cdf69
comparison
equal deleted inserted replaced
1751:77543124651b 1752:6d09d68165a4
56 void setSampleRate(sv_samplerate_t sampleRate) { m_sampleRate = sampleRate; } 56 void setSampleRate(sv_samplerate_t sampleRate) { m_sampleRate = sampleRate; }
57 57
58 bool isOK(); 58 bool isOK();
59 QString getErrorString() const; 59 QString getErrorString() const;
60 60
61 std::vector<Model *> getDataModels(ProgressReporter *); 61 std::vector<ModelId> getDataModels(ProgressReporter *);
62 62
63 protected: 63 protected:
64 BasicStore *m_store; 64 BasicStore *m_store;
65 Uri expand(QString s) { return m_store->expand(s); } 65 Uri expand(QString s) { return m_store->expand(s); }
66 66
67 QString m_uristring; 67 QString m_uristring;
68 QString m_errorString; 68 QString m_errorString;
69 std::map<QString, Model *> m_audioModelMap; 69 std::map<QString, ModelId> m_audioModelMap;
70 sv_samplerate_t m_sampleRate; 70 sv_samplerate_t m_sampleRate;
71 71
72 std::map<Model *, std::map<QString, float> > m_labelValueMap; 72 std::map<ModelId, std::map<QString, float> > m_labelValueMap;
73 73
74 void getDataModelsAudio(std::vector<Model *> &, ProgressReporter *); 74 void getDataModelsAudio(std::vector<ModelId> &, ProgressReporter *);
75 void getDataModelsSparse(std::vector<Model *> &, ProgressReporter *); 75 void getDataModelsSparse(std::vector<ModelId> &, ProgressReporter *);
76 void getDataModelsDense(std::vector<Model *> &, ProgressReporter *); 76 void getDataModelsDense(std::vector<ModelId> &, ProgressReporter *);
77 77
78 void getDenseModelTitle(Model *, QString, QString); 78 QString getDenseModelTitle(QString featureUri, QString featureTypeUri);
79 79
80 void getDenseFeatureProperties(QString featureUri, 80 void getDenseFeatureProperties(QString featureUri,
81 sv_samplerate_t &sampleRate, int &windowLength, 81 sv_samplerate_t &sampleRate, int &windowLength,
82 int &hopSize, int &width, int &height); 82 int &hopSize, int &width, int &height);
83 83
84 void fillModel(Model *, sv_frame_t, sv_frame_t, 84 void fillModel(ModelId, sv_frame_t, sv_frame_t,
85 bool, std::vector<float> &, QString); 85 bool, std::vector<float> &, QString);
86 }; 86 };
87 87
88 QString 88 QString
89 RDFImporter::getKnownExtensions() 89 RDFImporter::getKnownExtensions()
117 RDFImporter::getErrorString() const 117 RDFImporter::getErrorString() const
118 { 118 {
119 return m_d->getErrorString(); 119 return m_d->getErrorString();
120 } 120 }
121 121
122 std::vector<Model *> 122 std::vector<ModelId>
123 RDFImporter::getDataModels(ProgressReporter *r) 123 RDFImporter::getDataModels(ProgressReporter *r)
124 { 124 {
125 return m_d->getDataModels(r); 125 return m_d->getDataModels(r);
126 } 126 }
127 127
167 RDFImporterImpl::getErrorString() const 167 RDFImporterImpl::getErrorString() const
168 { 168 {
169 return m_errorString; 169 return m_errorString;
170 } 170 }
171 171
172 std::vector<Model *> 172 std::vector<ModelId>
173 RDFImporterImpl::getDataModels(ProgressReporter *reporter) 173 RDFImporterImpl::getDataModels(ProgressReporter *reporter)
174 { 174 {
175 std::vector<Model *> models; 175 std::vector<ModelId> models;
176 176
177 getDataModelsAudio(models, reporter); 177 getDataModelsAudio(models, reporter);
178 178
179 if (m_sampleRate == 0) { 179 if (m_sampleRate == 0) {
180 m_errorString = QString("Invalid audio data model (is audio file format supported?)"); 180 m_errorString = QString("Invalid audio data model (is audio file format supported?)");
204 204
205 return models; 205 return models;
206 } 206 }
207 207
208 void 208 void
209 RDFImporterImpl::getDataModelsAudio(std::vector<Model *> &models, 209 RDFImporterImpl::getDataModelsAudio(std::vector<ModelId> &models,
210 ProgressReporter *reporter) 210 ProgressReporter *reporter)
211 { 211 {
212 Nodes sigs = m_store->match 212 Nodes sigs = m_store->match
213 (Triple(Node(), Uri("a"), expand("mo:Signal"))).subjects(); 213 (Triple(Node(), Uri("a"), expand("mo:Signal"))).subjects();
214 214
268 268
269 if (reporter) { 269 if (reporter) {
270 reporter->setMessage(RDFImporter::tr("Importing audio referenced in RDF...")); 270 reporter->setMessage(RDFImporter::tr("Importing audio referenced in RDF..."));
271 } 271 }
272 fs->waitForData(); 272 fs->waitForData();
273 ReadOnlyWaveFileModel *newModel = new ReadOnlyWaveFileModel(*fs, m_sampleRate); 273 auto newModel = std::make_shared<ReadOnlyWaveFileModel>
274 (*fs, m_sampleRate);
274 if (newModel->isOK()) { 275 if (newModel->isOK()) {
275 cerr << "Successfully created wave file model from source at \"" << source << "\"" << endl; 276 cerr << "Successfully created wave file model from source at \"" << source << "\"" << endl;
276 models.push_back(newModel); 277 auto modelId = ModelById::add(newModel);
277 m_audioModelMap[signal] = newModel; 278 models.push_back(modelId);
279 m_audioModelMap[signal] = modelId;
278 if (m_sampleRate == 0) { 280 if (m_sampleRate == 0) {
279 m_sampleRate = newModel->getSampleRate(); 281 m_sampleRate = newModel->getSampleRate();
280 } 282 }
281 } else { 283 } else {
282 m_errorString = QString("Failed to create wave file model from source at \"%1\"").arg(source); 284 m_errorString = QString("Failed to create wave file model from source at \"%1\"").arg(source);
283 delete newModel;
284 } 285 }
285 delete fs; 286 delete fs;
286 } 287 }
287 } 288 }
288 289
289 void 290 void
290 RDFImporterImpl::getDataModelsDense(std::vector<Model *> &models, 291 RDFImporterImpl::getDataModelsDense(std::vector<ModelId> &models,
291 ProgressReporter *reporter) 292 ProgressReporter *reporter)
292 { 293 {
293 if (reporter) { 294 if (reporter) {
294 reporter->setMessage(RDFImporter::tr("Importing dense signal data from RDF...")); 295 reporter->setMessage(RDFImporter::tr("Importing dense signal data from RDF..."));
295 } 296 }
340 continue; 341 continue;
341 } 342 }
342 343
343 if (height == 1) { 344 if (height == 1) {
344 345
345 SparseTimeValueModel *m = new SparseTimeValueModel 346 auto m = std::make_shared<SparseTimeValueModel>
346 (sampleRate, hopSize, false); 347 (sampleRate, hopSize, false);
347 348
348 for (int j = 0; j < values.size(); ++j) { 349 for (int j = 0; j < values.size(); ++j) {
349 float f = values[j].toFloat(); 350 float f = values[j].toFloat();
350 Event e(j * hopSize, f, ""); 351 Event e(j * hopSize, f, "");
351 m->add(e); 352 m->add(e);
352 } 353 }
353 354
354 getDenseModelTitle(m, feature, type); 355 m->setObjectName(getDenseModelTitle(feature, type));
355
356 m->setRDFTypeURI(type); 356 m->setRDFTypeURI(type);
357 357 models.push_back(ModelById::add(m));
358 models.push_back(m);
359 358
360 } else { 359 } else {
361 360
362 EditableDenseThreeDimensionalModel *m = 361 auto m = std::make_shared<EditableDenseThreeDimensionalModel>
363 new EditableDenseThreeDimensionalModel
364 (sampleRate, hopSize, height, 362 (sampleRate, hopSize, height,
365 EditableDenseThreeDimensionalModel::NoCompression, false); 363 EditableDenseThreeDimensionalModel::NoCompression, false);
366 364
367 EditableDenseThreeDimensionalModel::Column column; 365 EditableDenseThreeDimensionalModel::Column column;
368 366
378 376
379 if (!column.empty()) { 377 if (!column.empty()) {
380 m->setColumn(x++, column); 378 m->setColumn(x++, column);
381 } 379 }
382 380
383 getDenseModelTitle(m, feature, type); 381 m->setObjectName(getDenseModelTitle(feature, type));
384
385 m->setRDFTypeURI(type); 382 m->setRDFTypeURI(type);
386 383 models.push_back(ModelById::add(m));
387 models.push_back(m); 384 }
388 } 385 }
389 } 386 }
390 } 387
391 388 QString
392 void 389 RDFImporterImpl::getDenseModelTitle(QString featureUri,
393 RDFImporterImpl::getDenseModelTitle(Model *m,
394 QString featureUri,
395 QString featureTypeUri) 390 QString featureTypeUri)
396 { 391 {
397 Node n = m_store->complete 392 Node n = m_store->complete
398 (Triple(Uri(featureUri), expand("dc:title"), Node())); 393 (Triple(Uri(featureUri), expand("dc:title"), Node()));
399 394
400 if (n.type == Node::Literal && n.value != "") { 395 if (n.type == Node::Literal && n.value != "") {
401 SVDEBUG << "RDFImporterImpl::getDenseModelTitle: Title (from signal) \"" << n.value << "\"" << endl; 396 SVDEBUG << "RDFImporterImpl::getDenseModelTitle: Title (from signal) \"" << n.value << "\"" << endl;
402 m->setObjectName(n.value); 397 return n.value;
403 return;
404 } 398 }
405 399
406 n = m_store->complete 400 n = m_store->complete
407 (Triple(Uri(featureTypeUri), expand("dc:title"), Node())); 401 (Triple(Uri(featureTypeUri), expand("dc:title"), Node()));
408 402
409 if (n.type == Node::Literal && n.value != "") { 403 if (n.type == Node::Literal && n.value != "") {
410 SVDEBUG << "RDFImporterImpl::getDenseModelTitle: Title (from signal type) \"" << n.value << "\"" << endl; 404 SVDEBUG << "RDFImporterImpl::getDenseModelTitle: Title (from signal type) \"" << n.value << "\"" << endl;
411 m->setObjectName(n.value); 405 return n.value;
412 return;
413 } 406 }
414 407
415 SVDEBUG << "RDFImporterImpl::getDenseModelTitle: No title available for feature <" << featureUri << ">" << endl; 408 SVDEBUG << "RDFImporterImpl::getDenseModelTitle: No title available for feature <" << featureUri << ">" << endl;
409 return {};
416 } 410 }
417 411
418 void 412 void
419 RDFImporterImpl::getDenseFeatureProperties(QString featureUri, 413 RDFImporterImpl::getDenseFeatureProperties(QString featureUri,
420 sv_samplerate_t &sampleRate, int &windowLength, 414 sv_samplerate_t &sampleRate, int &windowLength,
479 473
480 cerr << "sr = " << sampleRate << ", hop = " << hopSize << ", win = " << windowLength << endl; 474 cerr << "sr = " << sampleRate << ", hop = " << hopSize << ", win = " << windowLength << endl;
481 } 475 }
482 476
483 void 477 void
484 RDFImporterImpl::getDataModelsSparse(std::vector<Model *> &models, 478 RDFImporterImpl::getDataModelsSparse(std::vector<ModelId> &models,
485 ProgressReporter *reporter) 479 ProgressReporter *reporter)
486 { 480 {
487 if (reporter) { 481 if (reporter) {
488 reporter->setMessage(RDFImporter::tr("Importing event data from RDF...")); 482 reporter->setMessage(RDFImporter::tr("Importing event data from RDF..."));
489 } 483 }
508 502
509 Nodes sigs = m_store->match 503 Nodes sigs = m_store->match
510 (Triple(Node(), expand("a"), expand("mo:Signal"))).subjects(); 504 (Triple(Node(), expand("a"), expand("mo:Signal"))).subjects();
511 505
512 // Map from timeline uri to event type to dimensionality to 506 // Map from timeline uri to event type to dimensionality to
513 // presence of duration to model ptr. Whee! 507 // presence of duration to model id. Whee!
514 std::map<QString, std::map<QString, std::map<int, std::map<bool, Model *> > > > 508 std::map<QString, std::map<QString, std::map<int, std::map<bool, ModelId> > > >
515 modelMap; 509 modelMap;
516 510
517 foreach (Node sig, sigs) { 511 foreach (Node sig, sigs) {
518 512
519 Node interval = m_store->complete(Triple(sig, expand("mo:time"), Node())); 513 Node interval = m_store->complete(Triple(sig, expand("mo:time"), Node()));
615 609
616 int dimensions = 1; 610 int dimensions = 1;
617 if (values.size() == 1) dimensions = 2; 611 if (values.size() == 1) dimensions = 2;
618 else if (values.size() > 1) dimensions = 3; 612 else if (values.size() > 1) dimensions = 3;
619 613
620 Model *model = nullptr; 614 ModelId modelId;
621 615
622 if (modelMap[timeline][type][dimensions].find(haveDuration) == 616 if (modelMap[timeline][type][dimensions].find(haveDuration) ==
623 modelMap[timeline][type][dimensions].end()) { 617 modelMap[timeline][type][dimensions].end()) {
624 618
625 /* 619 /*
626 SVDEBUG << "Creating new model: source = " << source << ", type = " << type << ", dimensions = " 620 SVDEBUG << "Creating new model: source = " << source << ", type = " << type << ", dimensions = "
627 << dimensions << ", haveDuration = " << haveDuration 621 << dimensions << ", haveDuration = " << haveDuration
628 << ", time = " << time << ", duration = " << duration 622 << ", time = " << time << ", duration = " << duration
629 << endl; 623 << endl;
630 */ 624 */
631 625
626 Model *model = nullptr;
627
632 if (!haveDuration) { 628 if (!haveDuration) {
633 629
634 if (dimensions == 1) { 630 if (dimensions == 1) {
635 if (text) { 631 if (text) {
636 model = new TextModel(m_sampleRate, 1, false); 632 model = new TextModel(m_sampleRate, 1, false);
666 662
667 model->setRDFTypeURI(type); 663 model->setRDFTypeURI(type);
668 664
669 if (m_audioModelMap.find(source) != m_audioModelMap.end()) { 665 if (m_audioModelMap.find(source) != m_audioModelMap.end()) {
670 cerr << "source model for " << model << " is " << m_audioModelMap[source] << endl; 666 cerr << "source model for " << model << " is " << m_audioModelMap[source] << endl;
671 model->setSourceModel(m_audioModelMap[source]->getId()); 667 model->setSourceModel(m_audioModelMap[source]);
672 } 668 }
673 669
674 QString title = m_store->complete 670 QString title = m_store->complete
675 (Triple(typ, expand("dc:title"), Node())).value; 671 (Triple(typ, expand("dc:title"), Node())).value;
676 if (title == "") { 672 if (title == "") {
678 title = type; 674 title = type;
679 title.replace(QRegExp("^.*[/#]"), ""); 675 title.replace(QRegExp("^.*[/#]"), "");
680 } 676 }
681 model->setObjectName(title); 677 model->setObjectName(title);
682 678
683 modelMap[timeline][type][dimensions][haveDuration] = model; 679 modelId = ModelById::add(std::shared_ptr<Model>(model));
684 models.push_back(model); 680 modelMap[timeline][type][dimensions][haveDuration] = modelId;
685 } 681 models.push_back(modelId);
686 682 }
687 model = modelMap[timeline][type][dimensions][haveDuration]; 683
688 684 modelId = modelMap[timeline][type][dimensions][haveDuration];
689 if (model) { 685
690 sv_frame_t ftime = RealTime::realTime2Frame(time, m_sampleRate); 686 if (!modelId.isNone()) {
691 sv_frame_t fduration = RealTime::realTime2Frame(duration, m_sampleRate); 687 sv_frame_t ftime =
692 fillModel(model, ftime, fduration, haveDuration, values, label); 688 RealTime::realTime2Frame(time, m_sampleRate);
689 sv_frame_t fduration =
690 RealTime::realTime2Frame(duration, m_sampleRate);
691 fillModel(modelId, ftime, fduration,
692 haveDuration, values, label);
693 } 693 }
694 } 694 }
695 } 695 }
696 } 696 }
697 } 697 }
698 698
699 void 699 void
700 RDFImporterImpl::fillModel(Model *model, 700 RDFImporterImpl::fillModel(ModelId modelId,
701 sv_frame_t ftime, 701 sv_frame_t ftime,
702 sv_frame_t fduration, 702 sv_frame_t fduration,
703 bool haveDuration, 703 bool haveDuration,
704 std::vector<float> &values, 704 std::vector<float> &values,
705 QString label) 705 QString label)
706 { 706 {
707 // SVDEBUG << "RDFImporterImpl::fillModel: adding point at frame " << ftime << endl; 707 // SVDEBUG << "RDFImporterImpl::fillModel: adding point at frame " << ftime << endl;
708 708
709 SparseOneDimensionalModel *sodm = 709 if (auto sodm = ModelById::getAs<SparseOneDimensionalModel>(modelId)) {
710 dynamic_cast<SparseOneDimensionalModel *>(model);
711 if (sodm) {
712 Event point(ftime, label); 710 Event point(ftime, label);
713 sodm->add(point); 711 sodm->add(point);
714 return; 712 return;
715 } 713 }
716 714
717 TextModel *tm = 715 if (auto tm = ModelById::getAs<TextModel>(modelId)) {
718 dynamic_cast<TextModel *>(model);
719 if (tm) {
720 Event e 716 Event e
721 (ftime, 717 (ftime,
722 values.empty() ? 0.5f : values[0] < 0.f ? 0.f : values[0] > 1.f ? 1.f : values[0], // I was young and feckless once too 718 values.empty() ? 0.5f : values[0] < 0.f ? 0.f : values[0] > 1.f ? 1.f : values[0], // I was young and feckless once too
723 label); 719 label);
724 tm->add(e); 720 tm->add(e);
725 return; 721 return;
726 } 722 }
727 723
728 SparseTimeValueModel *stvm = 724 if (auto stvm = ModelById::getAs<SparseTimeValueModel>(modelId)) {
729 dynamic_cast<SparseTimeValueModel *>(model);
730 if (stvm) {
731 Event e(ftime, values.empty() ? 0.f : values[0], label); 725 Event e(ftime, values.empty() ? 0.f : values[0], label);
732 stvm->add(e); 726 stvm->add(e);
733 return; 727 return;
734 } 728 }
735 729
736 NoteModel *nm = 730 if (auto nm = ModelById::getAs<NoteModel>(modelId)) {
737 dynamic_cast<NoteModel *>(model);
738 if (nm) {
739 if (haveDuration) { 731 if (haveDuration) {
740 float value = 0.f, level = 1.f; 732 float value = 0.f, level = 1.f;
741 if (!values.empty()) { 733 if (!values.empty()) {
742 value = values[0]; 734 value = values[0];
743 if (values.size() > 1) { 735 if (values.size() > 1) {
762 nm->add(e); 754 nm->add(e);
763 } 755 }
764 return; 756 return;
765 } 757 }
766 758
767 RegionModel *rm = 759 if (auto rm = ModelById::getAs<RegionModel>(modelId)) {
768 dynamic_cast<RegionModel *>(model);
769 if (rm) {
770 float value = 0.f; 760 float value = 0.f;
771 if (values.empty()) { 761 if (values.empty()) {
772 // no values? map each unique label to a distinct value 762 // no values? map each unique label to a distinct value
773 if (m_labelValueMap[model].find(label) == m_labelValueMap[model].end()) { 763 if (m_labelValueMap[modelId].find(label) == m_labelValueMap[modelId].end()) {
774 m_labelValueMap[model][label] = rm->getValueMaximum() + 1.f; 764 m_labelValueMap[modelId][label] = rm->getValueMaximum() + 1.f;
775 } 765 }
776 value = m_labelValueMap[model][label]; 766 value = m_labelValueMap[modelId][label];
777 } else { 767 } else {
778 value = values[0]; 768 value = values[0];
779 } 769 }
780 if (haveDuration) { 770 if (haveDuration) {
781 Event e(ftime, value, fduration, label); 771 Event e(ftime, value, fduration, label);