Chris@150: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@150: Chris@150: /* Chris@150: Sonic Visualiser Chris@150: An audio file viewer and annotation editor. Chris@150: Centre for Digital Music, Queen Mary, University of London. Chris@150: This file copyright 2006 Chris Cannam. Chris@150: Chris@150: This program is free software; you can redistribute it and/or Chris@150: modify it under the terms of the GNU General Public License as Chris@150: published by the Free Software Foundation; either version 2 of the Chris@150: License, or (at your option) any later version. See the file Chris@150: COPYING included with this distribution for more information. Chris@150: */ Chris@150: Chris@150: #include "Model.h" Chris@319: #include "AlignmentModel.h" Chris@150: Chris@150: #include Chris@150: Chris@150: #include Chris@150: Chris@150: Model::~Model() Chris@150: { Chris@1668: SVDEBUG << "Model::~Model(" << this << ")" << endl; Chris@150: Chris@319: if (!m_aboutToDelete) { Chris@1384: SVDEBUG << "NOTE: Model(" << this << ", \"" Chris@1384: << objectName() << "\", type uri <" Chris@1384: << m_typeUri << ">)::~Model(): Model deleted " Chris@1384: << "with no aboutToDelete notification" Chris@1384: << endl; Chris@319: } Chris@319: Chris@319: if (m_alignment) { Chris@319: m_alignment->aboutToDelete(); Chris@319: delete m_alignment; Chris@319: } Chris@150: } Chris@150: Chris@1500: int Chris@1500: Model::getNextId() Chris@1500: { Chris@1500: static int nextId = 0; Chris@1500: static QMutex mutex; Chris@1500: QMutexLocker locker(&mutex); Chris@1500: int i = nextId; Chris@1500: if (nextId == INT_MAX) { Chris@1500: nextId = INT_MIN; Chris@1500: } Chris@1500: ++nextId; Chris@1500: return i; Chris@1500: } Chris@1500: Chris@150: void Chris@319: Model::setSourceModel(Model *model) Chris@319: { Chris@319: if (m_sourceModel) { Chris@319: disconnect(m_sourceModel, SIGNAL(aboutToBeDeleted()), Chris@319: this, SLOT(sourceModelAboutToBeDeleted())); Chris@319: } Chris@319: Chris@319: m_sourceModel = model; Chris@319: Chris@319: if (m_sourceModel) { Chris@333: connect(m_sourceModel, SIGNAL(alignmentCompletionChanged()), Chris@333: this, SIGNAL(alignmentCompletionChanged())); Chris@319: connect(m_sourceModel, SIGNAL(aboutToBeDeleted()), Chris@319: this, SLOT(sourceModelAboutToBeDeleted())); Chris@319: } Chris@319: } Chris@319: Chris@319: void Chris@319: Model::aboutToDelete() Chris@319: { Chris@1668: SVDEBUG << "Model(" << this << ", \"" Chris@1668: << objectName() << "\", type name \"" Chris@1668: << getTypeName() << "\", type uri <" Chris@1668: << m_typeUri << ">)::aboutToDelete()" << endl; Chris@360: Chris@319: if (m_aboutToDelete) { Chris@1384: SVDEBUG << "WARNING: Model(" << this << ", \"" Chris@1384: << objectName() << "\", type uri <" Chris@1384: << m_typeUri << ">)::aboutToDelete: " Chris@1384: << "aboutToDelete called more than once for the same model" Chris@1384: << endl; Chris@319: } Chris@319: Chris@319: emit aboutToBeDeleted(); Chris@319: m_aboutToDelete = true; Chris@319: } Chris@319: Chris@319: void Chris@319: Model::sourceModelAboutToBeDeleted() Chris@319: { Chris@1582: m_sourceModel = nullptr; Chris@319: } Chris@319: Chris@319: void Chris@319: Model::setAlignment(AlignmentModel *alignment) Chris@319: { Chris@1668: SVDEBUG << "Model(" << this << "): accepting alignment model " Chris@1668: << alignment << endl; Chris@1668: Chris@319: if (m_alignment) { Chris@319: m_alignment->aboutToDelete(); Chris@319: delete m_alignment; Chris@319: } Chris@1018: Chris@319: m_alignment = alignment; Chris@1018: Chris@1018: if (m_alignment) { Chris@1018: connect(m_alignment, SIGNAL(completionChanged()), Chris@1018: this, SIGNAL(alignmentCompletionChanged())); Chris@1018: } Chris@319: } Chris@319: Chris@407: const AlignmentModel * Chris@407: Model::getAlignment() const Chris@407: { Chris@407: return m_alignment; Chris@407: } Chris@407: Chris@319: const Model * Chris@319: Model::getAlignmentReference() const Chris@319: { Chris@333: if (!m_alignment) { Chris@333: if (m_sourceModel) return m_sourceModel->getAlignmentReference(); Chris@1582: return nullptr; Chris@333: } Chris@319: return m_alignment->getReferenceModel(); Chris@319: } Chris@319: Chris@1038: sv_frame_t Chris@1038: Model::alignToReference(sv_frame_t frame) const Chris@319: { Chris@951: // cerr << "Model(" << this << ")::alignToReference(" << frame << ")" << endl; Chris@333: if (!m_alignment) { Chris@333: if (m_sourceModel) return m_sourceModel->alignToReference(frame); Chris@333: else return frame; Chris@333: } Chris@1038: sv_frame_t refFrame = m_alignment->toReference(frame); Chris@340: const Model *m = m_alignment->getReferenceModel(); Chris@340: if (m && refFrame > m->getEndFrame()) refFrame = m->getEndFrame(); Chris@951: // cerr << "have alignment, aligned is " << refFrame << endl; Chris@333: return refFrame; Chris@319: } Chris@319: Chris@1038: sv_frame_t Chris@1038: Model::alignFromReference(sv_frame_t refFrame) const Chris@319: { Chris@951: // cerr << "Model(" << this << ")::alignFromReference(" << refFrame << ")" << endl; Chris@333: if (!m_alignment) { Chris@333: if (m_sourceModel) return m_sourceModel->alignFromReference(refFrame); Chris@333: else return refFrame; Chris@333: } Chris@1038: sv_frame_t frame = m_alignment->fromReference(refFrame); Chris@340: if (frame > getEndFrame()) frame = getEndFrame(); Chris@951: // cerr << "have alignment, aligned is " << frame << endl; Chris@333: return frame; Chris@319: } Chris@319: Chris@319: int Chris@319: Model::getAlignmentCompletion() const Chris@319: { Chris@1561: // SVDEBUG << "Model::getAlignmentCompletion: m_alignment = " Chris@1561: // << m_alignment << endl; Chris@333: if (!m_alignment) { Chris@333: if (m_sourceModel) return m_sourceModel->getAlignmentCompletion(); Chris@333: else return 100; Chris@333: } Chris@319: int completion = 0; Chris@319: (void)m_alignment->isReady(&completion); Chris@1561: // SVDEBUG << " -> " << completion << endl; Chris@319: return completion; Chris@319: } Chris@319: Chris@333: QString Chris@333: Model::getTitle() const Chris@333: { Chris@333: if (m_sourceModel) return m_sourceModel->getTitle(); Chris@345: else return ""; Chris@333: } Chris@333: Chris@333: QString Chris@333: Model::getMaker() const Chris@333: { Chris@333: if (m_sourceModel) return m_sourceModel->getMaker(); Chris@345: else return ""; Chris@345: } Chris@345: Chris@345: QString Chris@345: Model::getLocation() const Chris@345: { Chris@345: if (m_sourceModel) return m_sourceModel->getLocation(); Chris@345: else return ""; Chris@333: } Chris@333: Chris@319: void Chris@150: Model::toXml(QTextStream &stream, QString indent, Chris@150: QString extraAttributes) const Chris@150: { Chris@150: stream << indent; Chris@150: stream << QString("\n") Chris@1677: .arg(getExportId()) Chris@1429: .arg(encodeEntities(objectName())) Chris@1429: .arg(getSampleRate()) Chris@1429: .arg(getStartFrame()) Chris@1429: .arg(getEndFrame()) Chris@1429: .arg(extraAttributes); Chris@150: } Chris@150: Chris@150: