Mercurial > hg > svapp
comparison framework/Document.cpp @ 297:1e61f0c26593 tonioni_multi_transform
Enable multi-transform stuff through to here
author | Chris Cannam |
---|---|
date | Mon, 02 Dec 2013 15:06:16 +0000 |
parents | 19282182e60d |
children | f72d58d1ccb0 |
comparison
equal
deleted
inserted
replaced
296:19282182e60d | 297:1e61f0c26593 |
---|---|
38 | 38 |
39 // For alignment: | 39 // For alignment: |
40 #include "data/model/AggregateWaveModel.h" | 40 #include "data/model/AggregateWaveModel.h" |
41 #include "data/model/SparseTimeValueModel.h" | 41 #include "data/model/SparseTimeValueModel.h" |
42 #include "data/model/AlignmentModel.h" | 42 #include "data/model/AlignmentModel.h" |
43 | |
44 using std::vector; | |
43 | 45 |
44 //#define DEBUG_DOCUMENT 1 | 46 //#define DEBUG_DOCUMENT 1 |
45 | 47 |
46 //!!! still need to handle command history, documentRestored/documentModified | 48 //!!! still need to handle command history, documentRestored/documentModified |
47 | 49 |
203 (TransformFactory::getInstance()-> | 205 (TransformFactory::getInstance()-> |
204 getTransformFriendlyName(transform))); | 206 getTransformFriendlyName(transform))); |
205 | 207 |
206 return newLayer; | 208 return newLayer; |
207 } | 209 } |
210 | |
208 Layer * | 211 Layer * |
209 Document::createDerivedLayer(const Transform &transform, | 212 Document::createDerivedLayer(const Transform &transform, |
210 const ModelTransformer::Input &input) | 213 const ModelTransformer::Input &input) |
211 { | 214 { |
215 Transforms transforms; | |
216 transforms.push_back(transform); | |
217 vector<Layer *> layers = createDerivedLayers(transforms, input); | |
218 if (layers.empty()) return 0; | |
219 else return layers[0]; | |
220 } | |
221 | |
222 vector<Layer *> | |
223 Document::createDerivedLayers(const Transforms &transforms, | |
224 const ModelTransformer::Input &input) | |
225 { | |
212 QString message; | 226 QString message; |
213 Model *newModel = addDerivedModel(transform, input, message); | 227 vector<Model *> newModels = addDerivedModels(transforms, input, message); |
214 if (!newModel) { | 228 |
215 emit modelGenerationFailed(transform.getIdentifier(), message); | 229 if (newModels.empty()) { |
216 return 0; | 230 //!!! This identifier may be wrong! |
231 emit modelGenerationFailed(transforms[0].getIdentifier(), message); | |
232 return vector<Layer *>(); | |
217 } else if (message != "") { | 233 } else if (message != "") { |
218 emit modelGenerationWarning(transform.getIdentifier(), message); | 234 //!!! This identifier may be wrong! |
219 } | 235 emit modelGenerationWarning(transforms[0].getIdentifier(), message); |
220 | 236 } |
221 LayerFactory::LayerTypeSet types = | 237 |
222 LayerFactory::getInstance()->getValidLayerTypes(newModel); | 238 vector<Layer *> layers; |
223 | 239 |
224 if (types.empty()) { | 240 for (int i = 0; i < (int)newModels.size(); ++i) { |
225 cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transform.getIdentifier() << endl; | 241 |
226 newModel->aboutToDelete(); | 242 Model *newModel = newModels[i]; |
227 emit modelAboutToBeDeleted(newModel); | 243 |
228 m_models.erase(newModel); | 244 LayerFactory::LayerTypeSet types = |
229 delete newModel; | 245 LayerFactory::getInstance()->getValidLayerTypes(newModel); |
230 return 0; | 246 |
231 } | 247 if (types.empty()) { |
232 | 248 cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transforms[i].getIdentifier() << endl; |
233 //!!! for now, just use the first suitable layer type | 249 //!!! inadequate cleanup: |
234 | 250 newModel->aboutToDelete(); |
235 Layer *newLayer = createLayer(*types.begin()); | 251 emit modelAboutToBeDeleted(newModel); |
236 setModel(newLayer, newModel); | 252 m_models.erase(newModel); |
237 | 253 delete newModel; |
238 //!!! We need to clone the model when adding the layer, so that it | 254 return vector<Layer *>(); |
239 //can be edited without affecting other layers that are based on | 255 } |
240 //the same model. Unfortunately we can't just clone it now, | 256 |
241 //because it probably hasn't been completed yet -- the transform | 257 //!!! for now, just use the first suitable layer type |
242 //runs in the background. Maybe the transform has to handle | 258 |
243 //cloning and cacheing models itself. | 259 Layer *newLayer = createLayer(*types.begin()); |
244 // | 260 setModel(newLayer, newModel); |
245 // Once we do clone models here, of course, we'll have to avoid | 261 |
246 // leaking them too. | 262 //!!! We need to clone the model when adding the layer, so that it |
247 // | 263 //can be edited without affecting other layers that are based on |
248 // We want the user to be able to add a model to a second layer | 264 //the same model. Unfortunately we can't just clone it now, |
249 // _while it's still being calculated in the first_ and have it | 265 //because it probably hasn't been completed yet -- the transform |
250 // work quickly. That means we need to put the same physical | 266 //runs in the background. Maybe the transform has to handle |
251 // model pointer in both layers, so they can't actually be cloned. | 267 //cloning and cacheing models itself. |
268 // | |
269 // Once we do clone models here, of course, we'll have to avoid | |
270 // leaking them too. | |
271 // | |
272 // We want the user to be able to add a model to a second layer | |
273 // _while it's still being calculated in the first_ and have it | |
274 // work quickly. That means we need to put the same physical | |
275 // model pointer in both layers, so they can't actually be cloned. | |
252 | 276 |
253 if (newLayer) { | 277 if (newLayer) { |
254 newLayer->setObjectName(getUniqueLayerName | 278 newLayer->setObjectName(getUniqueLayerName |
255 (TransformFactory::getInstance()-> | 279 (TransformFactory::getInstance()-> |
256 getTransformFriendlyName | 280 getTransformFriendlyName |
257 (transform.getIdentifier()))); | 281 (transforms[i].getIdentifier()))); |
258 } | 282 } |
259 | 283 |
260 emit layerAdded(newLayer); | 284 emit layerAdded(newLayer); |
261 return newLayer; | 285 layers.push_back(newLayer); |
262 } | 286 } |
263 | 287 |
264 Layer * | 288 return layers; |
265 Document::createDerivedLayer(const Transform &transform, | 289 } |
266 const ModelTransformer::Input &input, | |
267 const LayerFactory::LayerType type) | |
268 { | |
269 // !!! THIS IS TOTALLY REDUNDANT CODE, EXCEPT FOR THE type SETTING | |
270 | |
271 QString message; | |
272 Model *newModel = addDerivedModel(transform, input, message); | |
273 if (!newModel) { | |
274 emit modelGenerationFailed(transform.getIdentifier(), message); | |
275 return 0; | |
276 } else if (message != "") { | |
277 emit modelGenerationWarning(transform.getIdentifier(), message); | |
278 } | |
279 | |
280 LayerFactory::LayerTypeSet types = | |
281 LayerFactory::getInstance()->getValidLayerTypes(newModel); | |
282 | |
283 if (types.empty()) { | |
284 std::cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transform.getIdentifier() << std::endl; | |
285 newModel->aboutToDelete(); | |
286 emit modelAboutToBeDeleted(newModel); | |
287 m_models.erase(newModel); | |
288 delete newModel; | |
289 return 0; | |
290 } | |
291 | |
292 //!!! creating layer with the specified type | |
293 | |
294 Layer *newLayer = createLayer(type); | |
295 setModel(newLayer, newModel); | |
296 | |
297 //!!! We need to clone the model when adding the layer, so that it | |
298 //can be edited without affecting other layers that are based on | |
299 //the same model. Unfortunately we can't just clone it now, | |
300 //because it probably hasn't been completed yet -- the transform | |
301 //runs in the background. Maybe the transform has to handle | |
302 //cloning and cacheing models itself. | |
303 // | |
304 // Once we do clone models here, of course, we'll have to avoid | |
305 // leaking them too. | |
306 // | |
307 // We want the user to be able to add a model to a second layer | |
308 // _while it's still being calculated in the first_ and have it | |
309 // work quickly. That means we need to put the same physical | |
310 // model pointer in both layers, so they can't actually be cloned. | |
311 | |
312 if (newLayer) { | |
313 newLayer->setObjectName(getUniqueLayerName | |
314 (TransformFactory::getInstance()-> | |
315 getTransformFriendlyName | |
316 (transform.getIdentifier()))); | |
317 } | |
318 | |
319 emit layerAdded(newLayer); | |
320 return newLayer; | |
321 } | |
322 | |
323 | 290 |
324 void | 291 void |
325 Document::setMainModel(WaveFileModel *model) | 292 Document::setMainModel(WaveFileModel *model) |
326 { | 293 { |
327 Model *oldMainModel = m_mainModel; | 294 Model *oldMainModel = m_mainModel; |
563 Model * | 530 Model * |
564 Document::addDerivedModel(const Transform &transform, | 531 Document::addDerivedModel(const Transform &transform, |
565 const ModelTransformer::Input &input, | 532 const ModelTransformer::Input &input, |
566 QString &message) | 533 QString &message) |
567 { | 534 { |
568 Model *model = 0; | |
569 // model = (Model) new FlexiNoteModel(); | |
570 // return model; | |
571 | |
572 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { | 535 for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { |
573 if (i->second.transform == transform && | 536 if (i->second.transform == transform && |
574 i->second.source == input.getModel() && | 537 i->second.source == input.getModel() && |
575 i->second.channel == input.getChannel()) { | 538 i->second.channel == input.getChannel()) { |
576 std::cerr << "derived model taken from map " << std::endl; | 539 std::cerr << "derived model taken from map " << std::endl; |
577 return i->first; | 540 return i->first; |
578 } | 541 } |
579 } | 542 } |
580 | 543 |
581 model = ModelTransformerFactory::getInstance()->transform | 544 Transforms tt; |
582 (transform, input, message); | 545 tt.push_back(transform); |
583 | 546 vector<Model *> mm = addDerivedModels(tt, input, message); |
584 // The transform we actually used was presumably identical to the | 547 if (mm.empty()) return 0; |
585 // one asked for, except that the version of the plugin may | 548 else return mm[0]; |
586 // differ. It's possible that the returned message contains a | 549 } |
587 // warning about this; that doesn't concern us here, but we do | 550 |
588 // need to ensure that the transform we remember is correct for | 551 vector<Model *> |
589 // what was actually applied, with the current plugin version. | 552 Document::addDerivedModels(const Transforms &transforms, |
590 | 553 const ModelTransformer::Input &input, |
591 Transform applied = transform; | 554 QString &message) |
592 applied.setPluginVersion | 555 { |
593 (TransformFactory::getInstance()-> | 556 vector<Model *> mm = |
594 getDefaultTransformFor(transform.getIdentifier(), | 557 ModelTransformerFactory::getInstance()->transformMultiple |
595 lrintf(transform.getSampleRate())) | 558 (transforms, input, message); |
596 .getPluginVersion()); | 559 |
597 | 560 for (int j = 0; j < (int)mm.size(); ++j) { |
598 if (!model) { | 561 |
599 cerr << "WARNING: Document::addDerivedModel: no output model for transform " << transform.getIdentifier() << endl; | 562 Model *model = mm[j]; |
600 } else { | 563 |
601 addDerivedModel(applied, input, model); | 564 // The transform we actually used was presumably identical to |
602 } | 565 // the one asked for, except that the version of the plugin |
603 // std::cerr << "derived model name: " << model->getTypeName() << std::endl; | 566 // may differ. It's possible that the returned message |
567 // contains a warning about this; that doesn't concern us | |
568 // here, but we do need to ensure that the transform we | |
569 // remember is correct for what was actually applied, with the | |
570 // current plugin version. | |
571 | |
572 Transform applied = transforms[j]; | |
573 applied.setPluginVersion | |
574 (TransformFactory::getInstance()-> | |
575 getDefaultTransformFor(applied.getIdentifier(), | |
576 lrintf(applied.getSampleRate())) | |
577 .getPluginVersion()); | |
578 | |
579 if (!model) { | |
580 cerr << "WARNING: Document::addDerivedModel: no output model for transform " << applied.getIdentifier() << endl; | |
581 } else { | |
582 addDerivedModel(applied, input, model); | |
583 } | |
584 } | |
604 | 585 |
605 return model; | 586 return mm; |
606 } | 587 } |
607 | 588 |
608 void | 589 void |
609 Document::releaseModel(Model *model) // Will _not_ release main model! | 590 Document::releaseModel(Model *model) // Will _not_ release main model! |
610 { | 591 { |