| Chris@150 | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */ | 
| Chris@150 | 2 | 
| Chris@150 | 3 /* | 
| Chris@150 | 4     Sonic Visualiser | 
| Chris@150 | 5     An audio file viewer and annotation editor. | 
| Chris@150 | 6     Centre for Digital Music, Queen Mary, University of London. | 
| Chris@150 | 7     This file copyright 2006 Chris Cannam. | 
| Chris@150 | 8 | 
| Chris@150 | 9     This program is free software; you can redistribute it and/or | 
| Chris@150 | 10     modify it under the terms of the GNU General Public License as | 
| Chris@150 | 11     published by the Free Software Foundation; either version 2 of the | 
| Chris@150 | 12     License, or (at your option) any later version.  See the file | 
| Chris@150 | 13     COPYING included with this distribution for more information. | 
| Chris@150 | 14 */ | 
| Chris@150 | 15 | 
| Chris@150 | 16 #include "Model.h" | 
| Chris@319 | 17 #include "AlignmentModel.h" | 
| Chris@150 | 18 #include "base/PlayParameterRepository.h" | 
| Chris@150 | 19 | 
| Chris@150 | 20 #include <QTextStream> | 
| Chris@150 | 21 | 
| Chris@150 | 22 #include <iostream> | 
| Chris@150 | 23 | 
| Chris@150 | 24 const int Model::COMPLETION_UNKNOWN = -1; | 
| Chris@150 | 25 | 
| Chris@150 | 26 Model::~Model() | 
| Chris@150 | 27 { | 
| Chris@150 | 28 //    std::cerr << "Model::~Model(" << this << ")" << std::endl; | 
| Chris@150 | 29 | 
| Chris@319 | 30     if (!m_aboutToDelete) { | 
| Chris@319 | 31         std::cerr << "NOTE: Model::~Model(" << this << ", \"" | 
| Chris@319 | 32                   << objectName().toStdString() << "\"): Model deleted " | 
| Chris@319 | 33                   << "with no aboutToDelete notification" << std::endl; | 
| Chris@319 | 34     } | 
| Chris@319 | 35 | 
| Chris@319 | 36     if (m_alignment) { | 
| Chris@319 | 37         m_alignment->aboutToDelete(); | 
| Chris@319 | 38         delete m_alignment; | 
| Chris@319 | 39     } | 
| Chris@319 | 40 | 
| Chris@150 | 41     // Subclasses have to handle adding themselves to the repository, | 
| Chris@150 | 42     // if they want to be played.  We can't do it from here because | 
| Chris@150 | 43     // the repository would be unable to tell whether we were playable | 
| Chris@150 | 44     // or not (because dynamic_cast won't work from the base class ctor) | 
| Chris@150 | 45     PlayParameterRepository::getInstance()->removeModel(this); | 
| Chris@150 | 46 } | 
| Chris@150 | 47 | 
| Chris@150 | 48 void | 
| Chris@319 | 49 Model::setSourceModel(Model *model) | 
| Chris@319 | 50 { | 
| Chris@319 | 51     if (m_sourceModel) { | 
| Chris@319 | 52         disconnect(m_sourceModel, SIGNAL(aboutToBeDeleted()), | 
| Chris@319 | 53                    this, SLOT(sourceModelAboutToBeDeleted())); | 
| Chris@319 | 54     } | 
| Chris@319 | 55 | 
| Chris@319 | 56     m_sourceModel = model; | 
| Chris@319 | 57 | 
| Chris@319 | 58     if (m_sourceModel) { | 
| Chris@333 | 59         connect(m_sourceModel, SIGNAL(alignmentCompletionChanged()), | 
| Chris@333 | 60                 this, SIGNAL(alignmentCompletionChanged())); | 
| Chris@319 | 61         connect(m_sourceModel, SIGNAL(aboutToBeDeleted()), | 
| Chris@319 | 62                 this, SLOT(sourceModelAboutToBeDeleted())); | 
| Chris@319 | 63     } | 
| Chris@319 | 64 } | 
| Chris@319 | 65 | 
| Chris@319 | 66 void | 
| Chris@319 | 67 Model::aboutToDelete() | 
| Chris@319 | 68 { | 
| Chris@319 | 69     if (m_aboutToDelete) { | 
| Chris@319 | 70         std::cerr << "WARNING: Model(" << this << ", \"" | 
| Chris@319 | 71                   << objectName().toStdString() << "\")::aboutToDelete: " | 
| Chris@319 | 72                   << "aboutToDelete called more than once for the same model" | 
| Chris@319 | 73                   << std::endl; | 
| Chris@319 | 74     } | 
| Chris@319 | 75 | 
| Chris@319 | 76     emit aboutToBeDeleted(); | 
| Chris@319 | 77     m_aboutToDelete = true; | 
| Chris@319 | 78 } | 
| Chris@319 | 79 | 
| Chris@319 | 80 void | 
| Chris@319 | 81 Model::sourceModelAboutToBeDeleted() | 
| Chris@319 | 82 { | 
| Chris@319 | 83     m_sourceModel = 0; | 
| Chris@319 | 84 } | 
| Chris@319 | 85 | 
| Chris@319 | 86 void | 
| Chris@319 | 87 Model::setAlignment(AlignmentModel *alignment) | 
| Chris@319 | 88 { | 
| Chris@319 | 89     if (m_alignment) { | 
| Chris@319 | 90         m_alignment->aboutToDelete(); | 
| Chris@319 | 91         delete m_alignment; | 
| Chris@319 | 92     } | 
| Chris@319 | 93     m_alignment = alignment; | 
| Chris@319 | 94     connect(m_alignment, SIGNAL(completionChanged()), | 
| Chris@319 | 95             this, SIGNAL(alignmentCompletionChanged())); | 
| Chris@319 | 96 } | 
| Chris@319 | 97 | 
| Chris@319 | 98 const Model * | 
| Chris@319 | 99 Model::getAlignmentReference() const | 
| Chris@319 | 100 { | 
| Chris@333 | 101     if (!m_alignment) { | 
| Chris@333 | 102         if (m_sourceModel) return m_sourceModel->getAlignmentReference(); | 
| Chris@333 | 103         return this; | 
| Chris@333 | 104     } | 
| Chris@319 | 105     return m_alignment->getReferenceModel(); | 
| Chris@319 | 106 } | 
| Chris@319 | 107 | 
| Chris@319 | 108 size_t | 
| Chris@319 | 109 Model::alignToReference(size_t frame) const | 
| Chris@319 | 110 { | 
| Chris@333 | 111     if (!m_alignment) { | 
| Chris@333 | 112         if (m_sourceModel) return m_sourceModel->alignToReference(frame); | 
| Chris@333 | 113         else return frame; | 
| Chris@333 | 114     } | 
| Chris@333 | 115     size_t refFrame = m_alignment->toReference(frame); | 
| Chris@333 | 116     //!!! this should be totally wrong, but because alignToReference and | 
| Chris@333 | 117     // alignFromReference are the wrong way around, it's right... *sigh* | 
| Chris@333 | 118     if (refFrame > getEndFrame()) refFrame = getEndFrame(); | 
| Chris@333 | 119     return refFrame; | 
| Chris@319 | 120 } | 
| Chris@319 | 121 | 
| Chris@319 | 122 size_t | 
| Chris@319 | 123 Model::alignFromReference(size_t refFrame) const | 
| Chris@319 | 124 { | 
| Chris@333 | 125     if (!m_alignment) { | 
| Chris@333 | 126         if (m_sourceModel) return m_sourceModel->alignFromReference(refFrame); | 
| Chris@333 | 127         else return refFrame; | 
| Chris@333 | 128     } | 
| Chris@333 | 129     size_t frame = m_alignment->fromReference(refFrame); | 
| Chris@333 | 130     return frame; | 
| Chris@319 | 131 } | 
| Chris@319 | 132 | 
| Chris@319 | 133 int | 
| Chris@319 | 134 Model::getAlignmentCompletion() const | 
| Chris@319 | 135 { | 
| Chris@323 | 136 //    std::cerr << "Model::getAlignmentCompletion" << std::endl; | 
| Chris@333 | 137     if (!m_alignment) { | 
| Chris@333 | 138         if (m_sourceModel) return m_sourceModel->getAlignmentCompletion(); | 
| Chris@333 | 139         else return 100; | 
| Chris@333 | 140     } | 
| Chris@319 | 141     int completion = 0; | 
| Chris@319 | 142     (void)m_alignment->isReady(&completion); | 
| Chris@323 | 143 //    std::cerr << " -> " << completion << std::endl; | 
| Chris@319 | 144     return completion; | 
| Chris@319 | 145 } | 
| Chris@319 | 146 | 
| Chris@333 | 147 QString | 
| Chris@333 | 148 Model::getTitle() const | 
| Chris@333 | 149 { | 
| Chris@333 | 150     if (m_sourceModel) return m_sourceModel->getTitle(); | 
| Chris@333 | 151 } | 
| Chris@333 | 152 | 
| Chris@333 | 153 QString | 
| Chris@333 | 154 Model::getMaker() const | 
| Chris@333 | 155 { | 
| Chris@333 | 156     if (m_sourceModel) return m_sourceModel->getMaker(); | 
| Chris@333 | 157 } | 
| Chris@333 | 158 | 
| Chris@319 | 159 void | 
| Chris@150 | 160 Model::toXml(QTextStream &stream, QString indent, | 
| Chris@150 | 161              QString extraAttributes) const | 
| Chris@150 | 162 { | 
| Chris@150 | 163     stream << indent; | 
| Chris@150 | 164     stream << QString("<model id=\"%1\" name=\"%2\" sampleRate=\"%3\" start=\"%4\" end=\"%5\" %6/>\n") | 
| Chris@150 | 165 	.arg(getObjectExportId(this)) | 
| Chris@150 | 166 	.arg(encodeEntities(objectName())) | 
| Chris@150 | 167 	.arg(getSampleRate()) | 
| Chris@150 | 168 	.arg(getStartFrame()) | 
| Chris@150 | 169 	.arg(getEndFrame()) | 
| Chris@150 | 170 	.arg(extraAttributes); | 
| Chris@150 | 171 } | 
| Chris@150 | 172 | 
| Chris@150 | 173 |