Mercurial > hg > easaier-soundaccess
comparison sv/document/SVFileReader.cpp @ 0:fc9323a41f5a
start base : Sonic Visualiser sv1-1.0rc1
author | lbajardsilogic |
---|---|
date | Fri, 11 May 2007 09:08:14 +0000 |
parents | |
children | 7bd5773d4372 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:fc9323a41f5a |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 This file copyright 2006 Chris Cannam and QMUL. | |
8 | |
9 This program is free software; you can redistribute it and/or | |
10 modify it under the terms of the GNU General Public License as | |
11 published by the Free Software Foundation; either version 2 of the | |
12 License, or (at your option) any later version. See the file | |
13 COPYING included with this distribution for more information. | |
14 */ | |
15 | |
16 #include "SVFileReader.h" | |
17 | |
18 #include "layer/Layer.h" | |
19 #include "view/View.h" | |
20 #include "base/PlayParameters.h" | |
21 #include "base/PlayParameterRepository.h" | |
22 | |
23 #include "data/fileio/AudioFileReaderFactory.h" | |
24 #include "data/fileio/FileFinder.h" | |
25 #include "data/fileio/RemoteFile.h" | |
26 | |
27 #include "data/model/WaveFileModel.h" | |
28 #include "data/model/EditableDenseThreeDimensionalModel.h" | |
29 #include "data/model/SparseOneDimensionalModel.h" | |
30 #include "data/model/SparseTimeValueModel.h" | |
31 #include "data/model/NoteModel.h" | |
32 #include "data/model/TextModel.h" | |
33 | |
34 #include "view/Pane.h" | |
35 | |
36 #include "Document.h" | |
37 | |
38 #include <QString> | |
39 #include <QMessageBox> | |
40 #include <QFileDialog> | |
41 | |
42 #include <iostream> | |
43 | |
44 SVFileReader::SVFileReader(Document *document, | |
45 SVFileReaderPaneCallback &callback, | |
46 QString location) : | |
47 m_document(document), | |
48 m_paneCallback(callback), | |
49 m_location(location), | |
50 m_currentPane(0), | |
51 m_currentDataset(0), | |
52 m_currentDerivedModel(0), | |
53 m_currentDerivedModelId(-1), | |
54 m_currentPlayParameters(0), | |
55 m_datasetSeparator(" "), | |
56 m_inRow(false), | |
57 m_rowNumber(0), | |
58 m_ok(false) | |
59 { | |
60 } | |
61 | |
62 void | |
63 SVFileReader::parse(const QString &xmlData) | |
64 { | |
65 QXmlInputSource inputSource; | |
66 inputSource.setData(xmlData); | |
67 parse(inputSource); | |
68 } | |
69 | |
70 void | |
71 SVFileReader::parse(QXmlInputSource &inputSource) | |
72 { | |
73 QXmlSimpleReader reader; | |
74 reader.setContentHandler(this); | |
75 reader.setErrorHandler(this); | |
76 m_ok = reader.parse(inputSource); | |
77 } | |
78 | |
79 bool | |
80 SVFileReader::isOK() | |
81 { | |
82 return m_ok; | |
83 } | |
84 | |
85 SVFileReader::~SVFileReader() | |
86 { | |
87 if (!m_awaitingDatasets.empty()) { | |
88 std::cerr << "WARNING: SV-XML: File ended with " | |
89 << m_awaitingDatasets.size() << " unfilled model dataset(s)" | |
90 << std::endl; | |
91 } | |
92 | |
93 std::set<Model *> unaddedModels; | |
94 | |
95 for (std::map<int, Model *>::iterator i = m_models.begin(); | |
96 i != m_models.end(); ++i) { | |
97 if (m_addedModels.find(i->second) == m_addedModels.end()) { | |
98 unaddedModels.insert(i->second); | |
99 } | |
100 } | |
101 | |
102 if (!unaddedModels.empty()) { | |
103 std::cerr << "WARNING: SV-XML: File contained " | |
104 << unaddedModels.size() << " unused models" | |
105 << std::endl; | |
106 while (!unaddedModels.empty()) { | |
107 delete *unaddedModels.begin(); | |
108 unaddedModels.erase(unaddedModels.begin()); | |
109 } | |
110 } | |
111 } | |
112 | |
113 bool | |
114 SVFileReader::startElement(const QString &, const QString &, | |
115 const QString &qName, | |
116 const QXmlAttributes &attributes) | |
117 { | |
118 QString name = qName.toLower(); | |
119 | |
120 bool ok = false; | |
121 | |
122 // Valid element names: | |
123 // | |
124 // sv | |
125 // data | |
126 // dataset | |
127 // display | |
128 // derivation | |
129 // playparameters | |
130 // layer | |
131 // model | |
132 // point | |
133 // row | |
134 // view | |
135 // window | |
136 | |
137 if (name == "sv") { | |
138 | |
139 // nothing needed | |
140 ok = true; | |
141 | |
142 } else if (name == "data") { | |
143 | |
144 // nothing needed | |
145 m_inData = true; | |
146 ok = true; | |
147 | |
148 } else if (name == "display") { | |
149 | |
150 // nothing needed | |
151 ok = true; | |
152 | |
153 } else if (name == "window") { | |
154 | |
155 ok = readWindow(attributes); | |
156 | |
157 } else if (name == "model") { | |
158 | |
159 ok = readModel(attributes); | |
160 | |
161 } else if (name == "dataset") { | |
162 | |
163 ok = readDatasetStart(attributes); | |
164 | |
165 } else if (name == "bin") { | |
166 | |
167 ok = addBinToDataset(attributes); | |
168 | |
169 } else if (name == "point") { | |
170 | |
171 ok = addPointToDataset(attributes); | |
172 | |
173 } else if (name == "row") { | |
174 | |
175 ok = addRowToDataset(attributes); | |
176 | |
177 } else if (name == "layer") { | |
178 | |
179 addUnaddedModels(); // all models must be specified before first layer | |
180 ok = readLayer(attributes); | |
181 | |
182 } else if (name == "view") { | |
183 | |
184 m_inView = true; | |
185 ok = readView(attributes); | |
186 | |
187 } else if (name == "derivation") { | |
188 | |
189 ok = readDerivation(attributes); | |
190 | |
191 } else if (name == "playparameters") { | |
192 | |
193 ok = readPlayParameters(attributes); | |
194 | |
195 } else if (name == "plugin") { | |
196 | |
197 ok = readPlugin(attributes); | |
198 | |
199 } else if (name == "selections") { | |
200 | |
201 m_inSelections = true; | |
202 ok = true; | |
203 | |
204 } else if (name == "selection") { | |
205 | |
206 ok = readSelection(attributes); | |
207 } | |
208 | |
209 if (!ok) { | |
210 std::cerr << "WARNING: SV-XML: Failed to completely process element \"" | |
211 << name.toLocal8Bit().data() << "\"" << std::endl; | |
212 } | |
213 | |
214 return true; | |
215 } | |
216 | |
217 bool | |
218 SVFileReader::characters(const QString &text) | |
219 { | |
220 bool ok = false; | |
221 | |
222 if (m_inRow) { | |
223 ok = readRowData(text); | |
224 if (!ok) { | |
225 std::cerr << "WARNING: SV-XML: Failed to read row data content for row " << m_rowNumber << std::endl; | |
226 } | |
227 } | |
228 | |
229 return true; | |
230 } | |
231 | |
232 bool | |
233 SVFileReader::endElement(const QString &, const QString &, | |
234 const QString &qName) | |
235 { | |
236 QString name = qName.toLower(); | |
237 | |
238 if (name == "dataset") { | |
239 | |
240 if (m_currentDataset) { | |
241 | |
242 bool foundInAwaiting = false; | |
243 | |
244 for (std::map<int, int>::iterator i = m_awaitingDatasets.begin(); | |
245 i != m_awaitingDatasets.end(); ++i) { | |
246 if (m_models[i->second] == m_currentDataset) { | |
247 m_awaitingDatasets.erase(i); | |
248 foundInAwaiting = true; | |
249 break; | |
250 } | |
251 } | |
252 | |
253 if (!foundInAwaiting) { | |
254 std::cerr << "WARNING: SV-XML: Dataset precedes model, or no model uses dataset" << std::endl; | |
255 } | |
256 } | |
257 | |
258 m_currentDataset = 0; | |
259 | |
260 } else if (name == "data") { | |
261 | |
262 addUnaddedModels(); | |
263 m_inData = false; | |
264 | |
265 } else if (name == "derivation") { | |
266 | |
267 if (!m_currentDerivedModel) { | |
268 if (m_currentDerivedModel < 0) { | |
269 std::cerr << "WARNING: SV-XML: Bad derivation output model id " | |
270 << m_currentDerivedModelId << std::endl; | |
271 } else if (m_models[m_currentDerivedModelId]) { | |
272 std::cerr << "WARNING: SV-XML: Derivation has existing model " | |
273 << m_currentDerivedModelId | |
274 << " as target, not regenerating" << std::endl; | |
275 } else { | |
276 m_currentDerivedModel = m_models[m_currentDerivedModelId] = | |
277 m_document->addDerivedModel(m_currentTransform, | |
278 m_currentTransformSource, | |
279 m_currentTransformContext, | |
280 m_currentTransformConfiguration); | |
281 } | |
282 } else { | |
283 m_document->addDerivedModel(m_currentTransform, | |
284 m_currentTransformSource, | |
285 m_currentTransformContext, | |
286 m_currentDerivedModel, | |
287 m_currentTransformConfiguration); | |
288 } | |
289 | |
290 m_addedModels.insert(m_currentDerivedModel); | |
291 m_currentDerivedModel = 0; | |
292 m_currentDerivedModelId = -1; | |
293 m_currentTransform = ""; | |
294 m_currentTransformConfiguration = ""; | |
295 | |
296 } else if (name == "row") { | |
297 m_inRow = false; | |
298 } else if (name == "view") { | |
299 m_inView = false; | |
300 } else if (name == "selections") { | |
301 m_inSelections = false; | |
302 } else if (name == "playparameters") { | |
303 m_currentPlayParameters = 0; | |
304 } | |
305 | |
306 return true; | |
307 } | |
308 | |
309 bool | |
310 SVFileReader::error(const QXmlParseException &exception) | |
311 { | |
312 m_errorString = | |
313 QString("ERROR: SV-XML: %1 at line %2, column %3") | |
314 .arg(exception.message()) | |
315 .arg(exception.lineNumber()) | |
316 .arg(exception.columnNumber()); | |
317 std::cerr << m_errorString.toLocal8Bit().data() << std::endl; | |
318 return QXmlDefaultHandler::error(exception); | |
319 } | |
320 | |
321 bool | |
322 SVFileReader::fatalError(const QXmlParseException &exception) | |
323 { | |
324 m_errorString = | |
325 QString("FATAL ERROR: SV-XML: %1 at line %2, column %3") | |
326 .arg(exception.message()) | |
327 .arg(exception.lineNumber()) | |
328 .arg(exception.columnNumber()); | |
329 std::cerr << m_errorString.toLocal8Bit().data() << std::endl; | |
330 return QXmlDefaultHandler::fatalError(exception); | |
331 } | |
332 | |
333 | |
334 #define READ_MANDATORY(TYPE, NAME, CONVERSION) \ | |
335 TYPE NAME = attributes.value(#NAME).trimmed().CONVERSION(&ok); \ | |
336 if (!ok) { \ | |
337 std::cerr << "WARNING: SV-XML: Missing or invalid mandatory " #TYPE " attribute \"" #NAME "\"" << std::endl; \ | |
338 return false; \ | |
339 } | |
340 | |
341 bool | |
342 SVFileReader::readWindow(const QXmlAttributes &attributes) | |
343 { | |
344 bool ok = false; | |
345 | |
346 READ_MANDATORY(int, width, toInt); | |
347 READ_MANDATORY(int, height, toInt); | |
348 | |
349 m_paneCallback.setWindowSize(width, height); | |
350 return true; | |
351 } | |
352 | |
353 void | |
354 SVFileReader::addUnaddedModels() | |
355 { | |
356 std::set<Model *> unaddedModels; | |
357 | |
358 for (std::map<int, Model *>::iterator i = m_models.begin(); | |
359 i != m_models.end(); ++i) { | |
360 if (m_addedModels.find(i->second) == m_addedModels.end()) { | |
361 unaddedModels.insert(i->second); | |
362 } | |
363 } | |
364 | |
365 for (std::set<Model *>::iterator i = unaddedModels.begin(); | |
366 i != unaddedModels.end(); ++i) { | |
367 m_document->addImportedModel(*i); | |
368 m_addedModels.insert(*i); | |
369 } | |
370 } | |
371 | |
372 bool | |
373 SVFileReader::readModel(const QXmlAttributes &attributes) | |
374 { | |
375 bool ok = false; | |
376 | |
377 READ_MANDATORY(int, id, toInt); | |
378 | |
379 if (m_models.find(id) != m_models.end()) { | |
380 std::cerr << "WARNING: SV-XML: Ignoring duplicate model id " << id | |
381 << std::endl; | |
382 return false; | |
383 } | |
384 | |
385 QString name = attributes.value("name"); | |
386 | |
387 READ_MANDATORY(int, sampleRate, toInt); | |
388 | |
389 QString type = attributes.value("type").trimmed(); | |
390 bool mainModel = (attributes.value("mainModel").trimmed() == "true"); | |
391 | |
392 if (type == "wavefile") { | |
393 | |
394 WaveFileModel *model = 0; | |
395 FileFinder *ff = FileFinder::getInstance(); | |
396 QString originalPath = attributes.value("file"); | |
397 QString path = ff->find(FileFinder::AudioFile, | |
398 originalPath, m_location); | |
399 QUrl url(path); | |
400 | |
401 if (RemoteFile::canHandleScheme(url)) { | |
402 | |
403 RemoteFile rf(url); | |
404 rf.wait(); | |
405 | |
406 if (rf.isOK()) { | |
407 | |
408 model = new WaveFileModel(rf.getLocalFilename(), path); | |
409 if (!model->isOK()) { | |
410 delete model; | |
411 model = 0; | |
412 //!!! and delete local file? | |
413 } | |
414 } | |
415 } else { | |
416 | |
417 model = new WaveFileModel(path); | |
418 if (!model->isOK()) { | |
419 delete model; | |
420 model = 0; | |
421 } | |
422 } | |
423 | |
424 if (!model) return false; | |
425 | |
426 m_models[id] = model; | |
427 if (mainModel) { | |
428 m_document->setMainModel(model); | |
429 m_addedModels.insert(model); | |
430 } | |
431 // Derived models will be added when their derivation | |
432 // is found. | |
433 | |
434 return true; | |
435 | |
436 } else if (type == "dense") { | |
437 | |
438 READ_MANDATORY(int, dimensions, toInt); | |
439 | |
440 // Currently the only dense model we support here is the dense | |
441 // 3d model. Dense time-value models are always file-backed | |
442 // waveform data, at this point, and they come in as wavefile | |
443 // models. | |
444 | |
445 if (dimensions == 3) { | |
446 | |
447 READ_MANDATORY(int, windowSize, toInt); | |
448 READ_MANDATORY(int, yBinCount, toInt); | |
449 | |
450 EditableDenseThreeDimensionalModel *model = | |
451 new EditableDenseThreeDimensionalModel | |
452 (sampleRate, windowSize, yBinCount); | |
453 | |
454 float minimum = attributes.value("minimum").trimmed().toFloat(&ok); | |
455 if (ok) model->setMinimumLevel(minimum); | |
456 | |
457 float maximum = attributes.value("maximum").trimmed().toFloat(&ok); | |
458 if (ok) model->setMaximumLevel(maximum); | |
459 | |
460 int dataset = attributes.value("dataset").trimmed().toInt(&ok); | |
461 if (ok) m_awaitingDatasets[dataset] = id; | |
462 | |
463 m_models[id] = model; | |
464 return true; | |
465 | |
466 } else { | |
467 | |
468 std::cerr << "WARNING: SV-XML: Unexpected dense model dimension (" | |
469 << dimensions << ")" << std::endl; | |
470 } | |
471 } else if (type == "sparse") { | |
472 | |
473 READ_MANDATORY(int, dimensions, toInt); | |
474 | |
475 if (dimensions == 1) { | |
476 | |
477 READ_MANDATORY(int, resolution, toInt); | |
478 | |
479 SparseOneDimensionalModel *model = new SparseOneDimensionalModel | |
480 (sampleRate, resolution); | |
481 m_models[id] = model; | |
482 | |
483 int dataset = attributes.value("dataset").trimmed().toInt(&ok); | |
484 if (ok) m_awaitingDatasets[dataset] = id; | |
485 | |
486 return true; | |
487 | |
488 } else if (dimensions == 2 || dimensions == 3) { | |
489 | |
490 READ_MANDATORY(int, resolution, toInt); | |
491 | |
492 float minimum = attributes.value("minimum").trimmed().toFloat(&ok); | |
493 float maximum = attributes.value("maximum").trimmed().toFloat(&ok); | |
494 float valueQuantization = | |
495 attributes.value("valueQuantization").trimmed().toFloat(&ok); | |
496 | |
497 bool notifyOnAdd = (attributes.value("notifyOnAdd") == "true"); | |
498 | |
499 QString units = attributes.value("units"); | |
500 | |
501 if (dimensions == 2) { | |
502 if (attributes.value("subtype") == "text") { | |
503 TextModel *model = new TextModel | |
504 (sampleRate, resolution, notifyOnAdd); | |
505 m_models[id] = model; | |
506 } else { | |
507 SparseTimeValueModel *model = new SparseTimeValueModel | |
508 (sampleRate, resolution, minimum, maximum, notifyOnAdd); | |
509 model->setScaleUnits(units); | |
510 m_models[id] = model; | |
511 } | |
512 } else { | |
513 NoteModel *model = new NoteModel | |
514 (sampleRate, resolution, minimum, maximum, notifyOnAdd); | |
515 model->setValueQuantization(valueQuantization); | |
516 model->setScaleUnits(units); | |
517 m_models[id] = model; | |
518 } | |
519 | |
520 int dataset = attributes.value("dataset").trimmed().toInt(&ok); | |
521 if (ok) m_awaitingDatasets[dataset] = id; | |
522 | |
523 return true; | |
524 | |
525 } else { | |
526 | |
527 std::cerr << "WARNING: SV-XML: Unexpected sparse model dimension (" | |
528 << dimensions << ")" << std::endl; | |
529 } | |
530 } else { | |
531 | |
532 std::cerr << "WARNING: SV-XML: Unexpected model type \"" | |
533 << type.toLocal8Bit().data() << "\" for model id " << id << std::endl; | |
534 } | |
535 | |
536 return false; | |
537 } | |
538 | |
539 bool | |
540 SVFileReader::readView(const QXmlAttributes &attributes) | |
541 { | |
542 QString type = attributes.value("type"); | |
543 m_currentPane = 0; | |
544 | |
545 if (type != "pane") { | |
546 std::cerr << "WARNING: SV-XML: Unexpected view type \"" | |
547 << type.toLocal8Bit().data() << "\"" << std::endl; | |
548 return false; | |
549 } | |
550 | |
551 m_currentPane = m_paneCallback.addPane(); | |
552 | |
553 if (!m_currentPane) { | |
554 std::cerr << "WARNING: SV-XML: Internal error: Failed to add pane!" | |
555 << std::endl; | |
556 return false; | |
557 } | |
558 | |
559 bool ok = false; | |
560 | |
561 View *view = m_currentPane; | |
562 | |
563 // The view properties first | |
564 | |
565 READ_MANDATORY(size_t, centre, toUInt); | |
566 READ_MANDATORY(size_t, zoom, toUInt); | |
567 READ_MANDATORY(int, followPan, toInt); | |
568 READ_MANDATORY(int, followZoom, toInt); | |
569 QString tracking = attributes.value("tracking"); | |
570 | |
571 // Specify the follow modes before we set the actual values | |
572 view->setFollowGlobalPan(followPan); | |
573 view->setFollowGlobalZoom(followZoom); | |
574 view->setPlaybackFollow(tracking == "scroll" ? PlaybackScrollContinuous : | |
575 tracking == "page" ? PlaybackScrollPage | |
576 : PlaybackIgnore); | |
577 | |
578 // Then set these values | |
579 view->setCentreFrame(centre); | |
580 view->setZoomLevel(zoom); | |
581 | |
582 // And pane properties | |
583 READ_MANDATORY(int, centreLineVisible, toInt); | |
584 m_currentPane->setCentreLineVisible(centreLineVisible); | |
585 | |
586 int height = attributes.value("height").toInt(&ok); | |
587 if (ok) { | |
588 m_currentPane->resize(m_currentPane->width(), height); | |
589 } | |
590 | |
591 return true; | |
592 } | |
593 | |
594 bool | |
595 SVFileReader::readLayer(const QXmlAttributes &attributes) | |
596 { | |
597 QString type = attributes.value("type"); | |
598 | |
599 int id; | |
600 bool ok = false; | |
601 id = attributes.value("id").trimmed().toInt(&ok); | |
602 | |
603 if (!ok) { | |
604 std::cerr << "WARNING: SV-XML: No layer id for layer of type \"" | |
605 << type.toLocal8Bit().data() | |
606 << "\"" << std::endl; | |
607 return false; | |
608 } | |
609 | |
610 Layer *layer = 0; | |
611 bool isNewLayer = false; | |
612 | |
613 // Layers are expected to be defined in layer elements in the data | |
614 // section, and referred to in layer elements in the view | |
615 // sections. So if we're in the data section, we expect this | |
616 // layer not to exist already; if we're in the view section, we | |
617 // expect it to exist. | |
618 | |
619 if (m_inData) { | |
620 | |
621 if (m_layers.find(id) != m_layers.end()) { | |
622 std::cerr << "WARNING: SV-XML: Ignoring duplicate layer id " << id | |
623 << " in data section" << std::endl; | |
624 return false; | |
625 } | |
626 | |
627 layer = m_layers[id] = m_document->createLayer | |
628 (LayerFactory::getInstance()->getLayerTypeForName(type)); | |
629 | |
630 if (layer) { | |
631 m_layers[id] = layer; | |
632 isNewLayer = true; | |
633 } | |
634 | |
635 } else { | |
636 | |
637 if (!m_currentPane) { | |
638 std::cerr << "WARNING: SV-XML: No current pane for layer " << id | |
639 << " in view section" << std::endl; | |
640 return false; | |
641 } | |
642 | |
643 if (m_layers.find(id) != m_layers.end()) { | |
644 | |
645 layer = m_layers[id]; | |
646 | |
647 } else { | |
648 std::cerr << "WARNING: SV-XML: Layer id " << id | |
649 << " in view section has not been defined -- defining it here" | |
650 << std::endl; | |
651 | |
652 layer = m_document->createLayer | |
653 (LayerFactory::getInstance()->getLayerTypeForName(type)); | |
654 | |
655 if (layer) { | |
656 m_layers[id] = layer; | |
657 isNewLayer = true; | |
658 } | |
659 } | |
660 } | |
661 | |
662 if (!layer) { | |
663 std::cerr << "WARNING: SV-XML: Failed to add layer of type \"" | |
664 << type.toLocal8Bit().data() | |
665 << "\"" << std::endl; | |
666 return false; | |
667 } | |
668 | |
669 if (isNewLayer) { | |
670 | |
671 QString name = attributes.value("name"); | |
672 layer->setObjectName(name); | |
673 | |
674 int modelId; | |
675 bool modelOk = false; | |
676 modelId = attributes.value("model").trimmed().toInt(&modelOk); | |
677 | |
678 if (modelOk) { | |
679 if (m_models.find(modelId) != m_models.end()) { | |
680 Model *model = m_models[modelId]; | |
681 m_document->setModel(layer, model); | |
682 } else { | |
683 std::cerr << "WARNING: SV-XML: Unknown model id " << modelId | |
684 << " in layer definition" << std::endl; | |
685 } | |
686 } | |
687 | |
688 layer->setProperties(attributes); | |
689 } | |
690 | |
691 if (!m_inData && m_currentPane) { | |
692 | |
693 QString visible = attributes.value("visible"); | |
694 bool dormant = (visible == "false"); | |
695 | |
696 // We need to do this both before and after adding the layer | |
697 // to the view -- we need it to be dormant if appropriate | |
698 // before it's actually added to the view so that any property | |
699 // box gets the right state when it's added, but the add layer | |
700 // command sets dormant to false because it assumes it may be | |
701 // restoring a previously dormant layer, so we need to set it | |
702 // again afterwards too. Hm | |
703 layer->setLayerDormant(m_currentPane, dormant); | |
704 | |
705 m_document->addLayerToView(m_currentPane, layer); | |
706 | |
707 layer->setLayerDormant(m_currentPane, dormant); | |
708 } | |
709 | |
710 return true; | |
711 } | |
712 | |
713 bool | |
714 SVFileReader::readDatasetStart(const QXmlAttributes &attributes) | |
715 { | |
716 bool ok = false; | |
717 | |
718 READ_MANDATORY(int, id, toInt); | |
719 READ_MANDATORY(int, dimensions, toInt); | |
720 | |
721 if (m_awaitingDatasets.find(id) == m_awaitingDatasets.end()) { | |
722 std::cerr << "WARNING: SV-XML: Unwanted dataset " << id << std::endl; | |
723 return false; | |
724 } | |
725 | |
726 int modelId = m_awaitingDatasets[id]; | |
727 | |
728 Model *model = 0; | |
729 if (m_models.find(modelId) != m_models.end()) { | |
730 model = m_models[modelId]; | |
731 } else { | |
732 std::cerr << "WARNING: SV-XML: Internal error: Unknown model " << modelId | |
733 << " expecting dataset " << id << std::endl; | |
734 return false; | |
735 } | |
736 | |
737 bool good = false; | |
738 | |
739 switch (dimensions) { | |
740 case 1: | |
741 if (dynamic_cast<SparseOneDimensionalModel *>(model)) good = true; | |
742 break; | |
743 | |
744 case 2: | |
745 if (dynamic_cast<SparseTimeValueModel *>(model)) good = true; | |
746 else if (dynamic_cast<TextModel *>(model)) good = true; | |
747 break; | |
748 | |
749 case 3: | |
750 if (dynamic_cast<NoteModel *>(model)) good = true; | |
751 else if (dynamic_cast<EditableDenseThreeDimensionalModel *>(model)) { | |
752 m_datasetSeparator = attributes.value("separator"); | |
753 good = true; | |
754 } | |
755 break; | |
756 } | |
757 | |
758 if (!good) { | |
759 std::cerr << "WARNING: SV-XML: Model id " << modelId << " has wrong number of dimensions for " << dimensions << "-D dataset " << id << std::endl; | |
760 m_currentDataset = 0; | |
761 return false; | |
762 } | |
763 | |
764 m_currentDataset = model; | |
765 return true; | |
766 } | |
767 | |
768 bool | |
769 SVFileReader::addPointToDataset(const QXmlAttributes &attributes) | |
770 { | |
771 bool ok = false; | |
772 | |
773 READ_MANDATORY(int, frame, toInt); | |
774 | |
775 SparseOneDimensionalModel *sodm = dynamic_cast<SparseOneDimensionalModel *> | |
776 (m_currentDataset); | |
777 | |
778 if (sodm) { | |
779 QString label = attributes.value("label"); | |
780 sodm->addPoint(SparseOneDimensionalModel::Point(frame, label)); | |
781 return true; | |
782 } | |
783 | |
784 SparseTimeValueModel *stvm = dynamic_cast<SparseTimeValueModel *> | |
785 (m_currentDataset); | |
786 | |
787 if (stvm) { | |
788 float value = 0.0; | |
789 value = attributes.value("value").trimmed().toFloat(&ok); | |
790 QString label = attributes.value("label"); | |
791 stvm->addPoint(SparseTimeValueModel::Point(frame, value, label)); | |
792 return ok; | |
793 } | |
794 | |
795 NoteModel *nm = dynamic_cast<NoteModel *>(m_currentDataset); | |
796 | |
797 if (nm) { | |
798 float value = 0.0; | |
799 value = attributes.value("value").trimmed().toFloat(&ok); | |
800 size_t duration = 0; | |
801 duration = attributes.value("duration").trimmed().toUInt(&ok); | |
802 QString label = attributes.value("label"); | |
803 nm->addPoint(NoteModel::Point(frame, value, duration, label)); | |
804 return ok; | |
805 } | |
806 | |
807 TextModel *tm = dynamic_cast<TextModel *>(m_currentDataset); | |
808 | |
809 if (tm) { | |
810 float height = 0.0; | |
811 height = attributes.value("height").trimmed().toFloat(&ok); | |
812 QString label = attributes.value("label"); | |
813 tm->addPoint(TextModel::Point(frame, height, label)); | |
814 return ok; | |
815 } | |
816 | |
817 std::cerr << "WARNING: SV-XML: Point element found in non-point dataset" << std::endl; | |
818 | |
819 return false; | |
820 } | |
821 | |
822 bool | |
823 SVFileReader::addBinToDataset(const QXmlAttributes &attributes) | |
824 { | |
825 EditableDenseThreeDimensionalModel *dtdm = | |
826 dynamic_cast<EditableDenseThreeDimensionalModel *> | |
827 (m_currentDataset); | |
828 | |
829 if (dtdm) { | |
830 | |
831 bool ok = false; | |
832 int n = attributes.value("number").trimmed().toInt(&ok); | |
833 if (!ok) { | |
834 std::cerr << "WARNING: SV-XML: Missing or invalid bin number" | |
835 << std::endl; | |
836 return false; | |
837 } | |
838 | |
839 QString name = attributes.value("name"); | |
840 | |
841 dtdm->setBinName(n, name); | |
842 return true; | |
843 } | |
844 | |
845 std::cerr << "WARNING: SV-XML: Bin definition found in incompatible dataset" << std::endl; | |
846 | |
847 return false; | |
848 } | |
849 | |
850 | |
851 bool | |
852 SVFileReader::addRowToDataset(const QXmlAttributes &attributes) | |
853 { | |
854 m_inRow = false; | |
855 | |
856 bool ok = false; | |
857 m_rowNumber = attributes.value("n").trimmed().toInt(&ok); | |
858 if (!ok) { | |
859 std::cerr << "WARNING: SV-XML: Missing or invalid row number" | |
860 << std::endl; | |
861 return false; | |
862 } | |
863 | |
864 m_inRow = true; | |
865 | |
866 // std::cerr << "SV-XML: In row " << m_rowNumber << std::endl; | |
867 | |
868 return true; | |
869 } | |
870 | |
871 bool | |
872 SVFileReader::readRowData(const QString &text) | |
873 { | |
874 EditableDenseThreeDimensionalModel *dtdm = | |
875 dynamic_cast<EditableDenseThreeDimensionalModel *> | |
876 (m_currentDataset); | |
877 | |
878 bool warned = false; | |
879 | |
880 if (dtdm) { | |
881 QStringList data = text.split(m_datasetSeparator); | |
882 | |
883 DenseThreeDimensionalModel::Column values; | |
884 | |
885 for (QStringList::iterator i = data.begin(); i != data.end(); ++i) { | |
886 | |
887 if (values.size() == dtdm->getHeight()) { | |
888 if (!warned) { | |
889 std::cerr << "WARNING: SV-XML: Too many y-bins in 3-D dataset row " | |
890 << m_rowNumber << std::endl; | |
891 warned = true; | |
892 } | |
893 } | |
894 | |
895 bool ok; | |
896 float value = i->toFloat(&ok); | |
897 if (!ok) { | |
898 std::cerr << "WARNING: SV-XML: Bad floating-point value " | |
899 << i->toLocal8Bit().data() | |
900 << " in row data" << std::endl; | |
901 } else { | |
902 values.push_back(value); | |
903 } | |
904 } | |
905 | |
906 dtdm->setColumn(m_rowNumber, values); | |
907 return true; | |
908 } | |
909 | |
910 std::cerr << "WARNING: SV-XML: Row data found in non-row dataset" << std::endl; | |
911 | |
912 return false; | |
913 } | |
914 | |
915 bool | |
916 SVFileReader::readDerivation(const QXmlAttributes &attributes) | |
917 { | |
918 int modelId = 0; | |
919 bool modelOk = false; | |
920 modelId = attributes.value("model").trimmed().toInt(&modelOk); | |
921 | |
922 if (!modelOk) { | |
923 std::cerr << "WARNING: SV-XML: No model id specified for derivation" << std::endl; | |
924 return false; | |
925 } | |
926 | |
927 QString transform = attributes.value("transform"); | |
928 | |
929 if (m_models.find(modelId) != m_models.end()) { | |
930 m_currentDerivedModel = m_models[modelId]; | |
931 } else { | |
932 // we'll regenerate the model when the derivation element ends | |
933 m_currentDerivedModel = 0; | |
934 } | |
935 | |
936 m_currentDerivedModelId = modelId; | |
937 | |
938 int sourceId = 0; | |
939 bool sourceOk = false; | |
940 sourceId = attributes.value("source").trimmed().toInt(&sourceOk); | |
941 | |
942 if (sourceOk && m_models[sourceId]) { | |
943 m_currentTransformSource = m_models[sourceId]; | |
944 } else { | |
945 m_currentTransformSource = m_document->getMainModel(); | |
946 } | |
947 | |
948 m_currentTransform = transform; | |
949 m_currentTransformConfiguration = ""; | |
950 | |
951 m_currentTransformContext = PluginTransform::ExecutionContext(); | |
952 | |
953 bool ok = false; | |
954 int channel = attributes.value("channel").trimmed().toInt(&ok); | |
955 if (ok) m_currentTransformContext.channel = channel; | |
956 | |
957 int domain = attributes.value("domain").trimmed().toInt(&ok); | |
958 if (ok) m_currentTransformContext.domain = Vamp::Plugin::InputDomain(domain); | |
959 | |
960 int stepSize = attributes.value("stepSize").trimmed().toInt(&ok); | |
961 if (ok) m_currentTransformContext.stepSize = stepSize; | |
962 | |
963 int blockSize = attributes.value("blockSize").trimmed().toInt(&ok); | |
964 if (ok) m_currentTransformContext.blockSize = blockSize; | |
965 | |
966 int windowType = attributes.value("windowType").trimmed().toInt(&ok); | |
967 if (ok) m_currentTransformContext.windowType = WindowType(windowType); | |
968 | |
969 return true; | |
970 } | |
971 | |
972 bool | |
973 SVFileReader::readPlayParameters(const QXmlAttributes &attributes) | |
974 { | |
975 m_currentPlayParameters = 0; | |
976 | |
977 int modelId = 0; | |
978 bool modelOk = false; | |
979 modelId = attributes.value("model").trimmed().toInt(&modelOk); | |
980 | |
981 if (!modelOk) { | |
982 std::cerr << "WARNING: SV-XML: No model id specified for play parameters" << std::endl; | |
983 return false; | |
984 } | |
985 | |
986 if (m_models.find(modelId) != m_models.end()) { | |
987 | |
988 bool ok = false; | |
989 | |
990 PlayParameters *parameters = PlayParameterRepository::getInstance()-> | |
991 getPlayParameters(m_models[modelId]); | |
992 | |
993 if (!parameters) { | |
994 std::cerr << "WARNING: SV-XML: Play parameters for model " | |
995 << modelId | |
996 << " not found - has model been added to document?" | |
997 << std::endl; | |
998 return false; | |
999 } | |
1000 | |
1001 bool muted = (attributes.value("mute").trimmed() == "true"); | |
1002 parameters->setPlayMuted(muted); | |
1003 | |
1004 float pan = attributes.value("pan").toFloat(&ok); | |
1005 if (ok) parameters->setPlayPan(pan); | |
1006 | |
1007 float gain = attributes.value("gain").toFloat(&ok); | |
1008 if (ok) parameters->setPlayGain(gain); | |
1009 | |
1010 QString pluginId = attributes.value("pluginId"); | |
1011 if (pluginId != "") parameters->setPlayPluginId(pluginId); | |
1012 | |
1013 m_currentPlayParameters = parameters; | |
1014 | |
1015 // std::cerr << "Current play parameters for model: " << m_models[modelId] << ": " << m_currentPlayParameters << std::endl; | |
1016 | |
1017 } else { | |
1018 | |
1019 std::cerr << "WARNING: SV-XML: Unknown model " << modelId | |
1020 << " for play parameters" << std::endl; | |
1021 return false; | |
1022 } | |
1023 | |
1024 return true; | |
1025 } | |
1026 | |
1027 bool | |
1028 SVFileReader::readPlugin(const QXmlAttributes &attributes) | |
1029 { | |
1030 if (m_currentDerivedModelId < 0 && !m_currentPlayParameters) { | |
1031 std::cerr << "WARNING: SV-XML: Plugin found outside derivation or play parameters" << std::endl; | |
1032 return false; | |
1033 } | |
1034 | |
1035 QString configurationXml = "<plugin"; | |
1036 | |
1037 for (int i = 0; i < attributes.length(); ++i) { | |
1038 configurationXml += QString(" %1=\"%2\"") | |
1039 .arg(attributes.qName(i)) | |
1040 .arg(XmlExportable::encodeEntities(attributes.value(i))); | |
1041 } | |
1042 | |
1043 configurationXml += "/>"; | |
1044 | |
1045 if (m_currentPlayParameters) { | |
1046 m_currentPlayParameters->setPlayPluginConfiguration(configurationXml); | |
1047 } else { | |
1048 m_currentTransformConfiguration += configurationXml; | |
1049 } | |
1050 | |
1051 return true; | |
1052 } | |
1053 | |
1054 bool | |
1055 SVFileReader::readSelection(const QXmlAttributes &attributes) | |
1056 { | |
1057 bool ok; | |
1058 | |
1059 READ_MANDATORY(int, start, toInt); | |
1060 READ_MANDATORY(int, end, toInt); | |
1061 | |
1062 m_paneCallback.addSelection(start, end); | |
1063 | |
1064 return true; | |
1065 } | |
1066 | |
1067 SVFileReaderPaneCallback::~SVFileReaderPaneCallback() | |
1068 { | |
1069 } | |
1070 |