comparison framework/Document.cpp @ 548:baa11365ebdd bqaudioio

Merge from branch bqresample
author Chris Cannam
date Wed, 07 Dec 2016 11:51:42 +0000
parents 36aa947ec962
children d122d3595a32
comparison
equal deleted inserted replaced
547:82d7e5cf7517 548:baa11365ebdd
12 License, or (at your option) any later version. See the file 12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information. 13 COPYING included with this distribution for more information.
14 */ 14 */
15 15
16 #include "Document.h" 16 #include "Document.h"
17
18 #include "Align.h"
17 19
18 #include "data/model/WaveFileModel.h" 20 #include "data/model/WaveFileModel.h"
19 #include "data/model/WritableWaveFileModel.h" 21 #include "data/model/WritableWaveFileModel.h"
20 #include "data/model/DenseThreeDimensionalModel.h" 22 #include "data/model/DenseThreeDimensionalModel.h"
21 #include "data/model/DenseTimeValueModel.h" 23 #include "data/model/DenseTimeValueModel.h"
34 #include <QTextStream> 36 #include <QTextStream>
35 #include <QSettings> 37 #include <QSettings>
36 #include <iostream> 38 #include <iostream>
37 #include <typeinfo> 39 #include <typeinfo>
38 40
39 // For alignment:
40 #include "data/model/AggregateWaveModel.h"
41 #include "data/model/SparseTimeValueModel.h"
42 #include "data/model/AlignmentModel.h" 41 #include "data/model/AlignmentModel.h"
42 #include "Align.h"
43 43
44 using std::vector; 44 using std::vector;
45 45
46 //#define DEBUG_DOCUMENT 1 46 //#define DEBUG_DOCUMENT 1
47 47
48 //!!! still need to handle command history, documentRestored/documentModified 48 //!!! still need to handle command history, documentRestored/documentModified
49 49
50 Document::Document() : 50 Document::Document() :
51 m_mainModel(0), 51 m_mainModel(0),
52 m_autoAlignment(false) 52 m_autoAlignment(false),
53 m_align(new Align())
53 { 54 {
54 connect(this, 55 connect(this,
55 SIGNAL(modelAboutToBeDeleted(Model *)), 56 SIGNAL(modelAboutToBeDeleted(Model *)),
56 ModelTransformerFactory::getInstance(), 57 ModelTransformerFactory::getInstance(),
57 SLOT(modelAboutToBeDeleted(Model *))); 58 SLOT(modelAboutToBeDeleted(Model *)));
58 59
59 connect(ModelTransformerFactory::getInstance(), 60 connect(ModelTransformerFactory::getInstance(),
60 SIGNAL(transformFailed(QString, QString)), 61 SIGNAL(transformFailed(QString, QString)),
61 this, 62 this,
62 SIGNAL(modelGenerationFailed(QString, QString))); 63 SIGNAL(modelGenerationFailed(QString, QString)));
64
65 connect(m_align, SIGNAL(alignmentComplete(AlignmentModel *)),
66 this, SIGNAL(alignmentComplete(AlignmentModel *)));
63 } 67 }
64 68
65 Document::~Document() 69 Document::~Document()
66 { 70 {
67 //!!! Document should really own the command history. atm we 71 //!!! Document should really own the command history. atm we
734 // contains a warning about this; that doesn't concern us 738 // contains a warning about this; that doesn't concern us
735 // here, but we do need to ensure that the transform we 739 // here, but we do need to ensure that the transform we
736 // remember is correct for what was actually applied, with the 740 // remember is correct for what was actually applied, with the
737 // current plugin version. 741 // current plugin version.
738 742
743 //!!! would be nice to short-circuit this -- the version is
744 //!!! static data, shouldn't have to construct a plugin for it
745 //!!! (which may be expensive in Piper-world)
746
739 Transform applied = transforms[j]; 747 Transform applied = transforms[j];
740 applied.setPluginVersion 748 applied.setPluginVersion
741 (TransformFactory::getInstance()-> 749 (TransformFactory::getInstance()->
742 getDefaultTransformFor(applied.getIdentifier(), 750 getDefaultTransformFor(applied.getIdentifier(),
743 applied.getSampleRate()) 751 applied.getSampleRate())
1036 { 1044 {
1037 if (model == m_mainModel) return true; 1045 if (model == m_mainModel) return true;
1038 return (m_models.find(const_cast<Model *>(model)) != m_models.end()); 1046 return (m_models.find(const_cast<Model *>(model)) != m_models.end());
1039 } 1047 }
1040 1048
1041 TransformId
1042 Document::getAlignmentTransformName()
1043 {
1044 QSettings settings;
1045 settings.beginGroup("Alignment");
1046 TransformId id =
1047 settings.value("transform-id",
1048 "vamp:match-vamp-plugin:match:path").toString();
1049 settings.endGroup();
1050 return id;
1051 }
1052
1053 bool 1049 bool
1054 Document::canAlign() 1050 Document::canAlign()
1055 { 1051 {
1056 TransformId id = getAlignmentTransformName(); 1052 return Align::canAlign();
1057 TransformFactory *factory = TransformFactory::getInstance();
1058 return factory->haveTransform(id);
1059 } 1053 }
1060 1054
1061 void 1055 void
1062 Document::alignModel(Model *model) 1056 Document::alignModel(Model *model)
1063 { 1057 {
1088 SVDEBUG << "Document::alignModel(" << model << "): is main model, setting appropriately" << endl; 1082 SVDEBUG << "Document::alignModel(" << model << "): is main model, setting appropriately" << endl;
1089 rm->setAlignment(new AlignmentModel(model, model, 0, 0)); 1083 rm->setAlignment(new AlignmentModel(model, model, 0, 0));
1090 return; 1084 return;
1091 } 1085 }
1092 1086
1093 // This involves creating three new models: 1087 if (!m_align->alignModel(m_mainModel, rm)) {
1094 1088 cerr << "Alignment failed: " << m_align->getError() << endl;
1095 // 1. an AggregateWaveModel to provide the mixdowns of the main 1089 emit alignmentFailed(m_align->getError());
1096 // model and the new model in its two channels, as input to the 1090 }
1097 // MATCH plugin
1098
1099 // 2. a SparseTimeValueModel, which is the model automatically
1100 // created by FeatureExtractionPluginTransformer when running the
1101 // MATCH plugin (thus containing the alignment path)
1102
1103 // 3. an AlignmentModel, which stores the path model and carries
1104 // out alignment lookups on it.
1105
1106 // The first two of these are provided as arguments to the
1107 // constructor for the third, which takes responsibility for
1108 // deleting them. The AlignmentModel, meanwhile, is passed to the
1109 // new model we are aligning, which also takes responsibility for
1110 // it. We should not have to delete any of these new models here.
1111
1112 AggregateWaveModel::ChannelSpecList components;
1113
1114 components.push_back(AggregateWaveModel::ModelChannelSpec
1115 (m_mainModel, -1));
1116
1117 components.push_back(AggregateWaveModel::ModelChannelSpec
1118 (rm, -1));
1119
1120 Model *aggregateModel = new AggregateWaveModel(components);
1121 ModelTransformer::Input aggregate(aggregateModel);
1122
1123 TransformId id = "vamp:match-vamp-plugin:match:path"; //!!! configure
1124
1125 TransformFactory *tf = TransformFactory::getInstance();
1126
1127 Transform transform = tf->getDefaultTransformFor
1128 (id, aggregateModel->getSampleRate());
1129
1130 transform.setStepSize(transform.getBlockSize()/2);
1131 transform.setParameter("serialise", 1);
1132
1133 SVDEBUG << "Document::alignModel: Alignment transform step size " << transform.getStepSize() << ", block size " << transform.getBlockSize() << endl;
1134
1135 ModelTransformerFactory *mtf = ModelTransformerFactory::getInstance();
1136
1137 QString message;
1138 Model *transformOutput = mtf->transform(transform, aggregate, message);
1139
1140 if (!transformOutput) {
1141 transform.setStepSize(0);
1142 transformOutput = mtf->transform(transform, aggregate, message);
1143 }
1144
1145 SparseTimeValueModel *path = dynamic_cast<SparseTimeValueModel *>
1146 (transformOutput);
1147
1148 if (!path) {
1149 cerr << "Document::alignModel: ERROR: Failed to create alignment path (no MATCH plugin?)" << endl;
1150 emit alignmentFailed(id, message);
1151 delete transformOutput;
1152 delete aggregateModel;
1153 return;
1154 }
1155
1156 path->setCompletion(0);
1157
1158 AlignmentModel *alignmentModel = new AlignmentModel
1159 (m_mainModel, model, aggregateModel, path);
1160
1161 rm->setAlignment(alignmentModel);
1162 } 1091 }
1163 1092
1164 void 1093 void
1165 Document::alignModels() 1094 Document::alignModels()
1166 { 1095 {