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