annotate data/model/Model.cpp @ 340:516819f2b97b

* Add Erase tool and mode * Add icons for Normalize buttons in property boxes, and for Show Peaks * Add support for velocity in notes -- not yet reflected in display or editable in the note edit dialog, but they are imported from MIDI, played, and exported * Begin work on making pastes align pasted times (subtler than I thought)
author Chris Cannam
date Fri, 23 Nov 2007 16:48:23 +0000
parents 1afaf98dbf11
children 700cd3350391
rev   line source
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@340 116 const Model *m = m_alignment->getReferenceModel();
Chris@340 117 if (m && refFrame > m->getEndFrame()) refFrame = m->getEndFrame();
Chris@333 118 return refFrame;
Chris@319 119 }
Chris@319 120
Chris@319 121 size_t
Chris@319 122 Model::alignFromReference(size_t refFrame) const
Chris@319 123 {
Chris@333 124 if (!m_alignment) {
Chris@333 125 if (m_sourceModel) return m_sourceModel->alignFromReference(refFrame);
Chris@333 126 else return refFrame;
Chris@333 127 }
Chris@333 128 size_t frame = m_alignment->fromReference(refFrame);
Chris@340 129 if (frame > getEndFrame()) frame = getEndFrame();
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