# HG changeset patch # User Chris Cannam # Date 1209483257 0 # Node ID 88ad0179904015edd47813061b231f56c28ee583 # Parent d095214ffbaf66f0922d4ffbaeeacea1dbcf2cc9 * Save alignments to session file. Needs much testing. diff -r d095214ffbaf -r 88ad01799040 data/data.pro --- a/data/data.pro Tue Apr 29 10:59:19 2008 +0000 +++ b/data/data.pro Tue Apr 29 15:34:17 2008 +0000 @@ -53,6 +53,7 @@ model/Labeller.h \ model/Model.h \ model/NoteModel.h \ + model/PathModel.h \ model/PowerOfSqrtTwoZoomConstraint.h \ model/PowerOfTwoZoomConstraint.h \ model/RangeSummarisableTimeValueModel.h \ diff -r d095214ffbaf -r 88ad01799040 data/model/AlignmentModel.cpp --- a/data/model/AlignmentModel.cpp Tue Apr 29 10:59:19 2008 +0000 +++ b/data/model/AlignmentModel.cpp Tue Apr 29 15:34:17 2008 +0000 @@ -42,17 +42,28 @@ connect(m_rawPath, SIGNAL(completionChanged()), this, SLOT(pathCompletionChanged())); + + constructPath(); + constructReversePath(); } - constructPath(); - constructReversePath(); + if (m_rawPath && m_rawPath->isReady()) { + pathCompletionChanged(); + } } AlignmentModel::~AlignmentModel() { + if (m_inputModel) m_inputModel->aboutToDelete(); delete m_inputModel; + + if (m_rawPath) m_rawPath->aboutToDelete(); delete m_rawPath; + + if (m_path) m_path->aboutToDelete(); delete m_path; + + if (m_reversePath) m_reversePath->aboutToDelete(); delete m_reversePath; } @@ -157,6 +168,7 @@ { if (m_pathComplete) { std::cerr << "AlignmentModel: deleting raw path model" << std::endl; + if (m_rawPath) m_rawPath->aboutToDelete(); delete m_rawPath; m_rawPath = 0; } @@ -192,7 +204,8 @@ constructPath(); constructReversePath(); - + + if (m_inputModel) m_inputModel->aboutToDelete(); delete m_inputModel; m_inputModel = 0; } @@ -237,6 +250,7 @@ AlignmentModel::constructReversePath() const { if (!m_reversePath) { +/*!!! if (!m_rawPath) { std::cerr << "ERROR: AlignmentModel::constructReversePath: " << "No raw path available" << std::endl; @@ -244,12 +258,23 @@ } m_reversePath = new PathModel (m_rawPath->getSampleRate(), m_rawPath->getResolution(), false); +*/ + if (!m_path) { + std::cerr << "ERROR: AlignmentModel::constructReversePath: " + << "No forward path available" << std::endl; + return; + } + m_reversePath = new PathModel + (m_path->getSampleRate(), m_path->getResolution(), false); } else { +/*!!! if (!m_rawPath) return; +*/ + if (!m_path) return; } m_reversePath->clear(); - +/*!!! SparseTimeValueModel::PointList points = m_rawPath->getPoints(); for (SparseTimeValueModel::PointList::const_iterator i = points.begin(); @@ -259,6 +284,16 @@ long rframe = lrintf(value * m_aligned->getSampleRate()); m_reversePath->addPoint(PathPoint(rframe, frame)); } +*/ + + PathModel::PointList points = m_path->getPoints(); + + for (PathModel::PointList::const_iterator i = points.begin(); + i != points.end(); ++i) { + long frame = i->frame; + long rframe = i->mapframe; + m_reversePath->addPoint(PathPoint(rframe, frame)); + } #ifdef DEBUG_ALIGNMENT_MODEL std::cerr << "AlignmentModel::constructReversePath: " << m_reversePath->getPointCount() << " points, at least " << (2 * m_reversePath->getPointCount() * (3 * sizeof(void *) + sizeof(int) + sizeof(PathPoint))) << " bytes" << std::endl; @@ -333,4 +368,34 @@ return resultFrame; } + +void +AlignmentModel::setPath(PathModel *path) +{ + if (m_path) m_path->aboutToDelete(); + delete m_path; + m_path = path; + constructReversePath(); +} +void +AlignmentModel::toXml(QTextStream &stream, + QString indent, + QString extraAttributes) const +{ + if (!m_path) { + std::cerr << "AlignmentModel::toXml: no path" << std::endl; + return; + } + + m_path->toXml(stream, indent, ""); + + Model::toXml(stream, indent, + QString("type=\"alignment\" reference=\"%1\" aligned=\"%2\" path=\"%3\" %4") + .arg(getObjectExportId(m_reference)) + .arg(getObjectExportId(m_aligned)) + .arg(getObjectExportId(m_path)) + .arg(extraAttributes)); +} + + diff -r d095214ffbaf -r 88ad01799040 data/model/AlignmentModel.h --- a/data/model/AlignmentModel.h Tue Apr 29 10:59:19 2008 +0000 +++ b/data/model/AlignmentModel.h Tue Apr 29 15:34:17 2008 +0000 @@ -17,7 +17,7 @@ #define _ALIGNMENT_MODEL_H_ #include "Model.h" -#include "SparseModel.h" +#include "PathModel.h" #include "base/RealTime.h" #include @@ -52,6 +52,12 @@ size_t toReference(size_t frame) const; size_t fromReference(size_t frame) const; + void setPath(PathModel *path); + + virtual void toXml(QTextStream &stream, + QString indent = "", + QString extraAttributes = "") const; + signals: void modelChanged(); void modelChanged(size_t startFrame, size_t endFrame); @@ -68,54 +74,6 @@ Model *m_inputModel; // I own this - struct PathPoint - { - PathPoint(long _frame) : frame(_frame), mapframe(_frame) { } - PathPoint(long _frame, long _mapframe) : - frame(_frame), mapframe(_mapframe) { } - - int getDimensions() const { return 2; } - - long frame; - long mapframe; - - QString getLabel() const { return ""; } - - void toXml(QTextStream &stream, QString indent = "", - QString extraAttributes = "") const { - stream << QString("%1\n") - .arg(indent).arg(frame).arg(mapframe).arg(extraAttributes); - } - - QString toDelimitedDataString(QString delimiter, - size_t sampleRate) const { - QStringList list; - list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str(); - list << QString("%1").arg(mapframe); - return list.join(delimiter); - } - - struct Comparator { - bool operator()(const PathPoint &p1, const PathPoint &p2) const { - if (p1.frame != p2.frame) return p1.frame < p2.frame; - return p1.mapframe < p2.mapframe; - } - }; - - struct OrderComparator { - bool operator()(const PathPoint &p1, const PathPoint &p2) const { - return p1.frame < p2.frame; - } - }; - }; - - class PathModel : public SparseModel - { - public: - PathModel(size_t sampleRate, size_t resolution, bool notify = true) : - SparseModel(sampleRate, resolution, notify) { } - }; - SparseTimeValueModel *m_rawPath; // I own this mutable PathModel *m_path; // I own this mutable PathModel *m_reversePath; // I own this diff -r d095214ffbaf -r 88ad01799040 data/model/Model.cpp --- a/data/model/Model.cpp Tue Apr 29 10:59:19 2008 +0000 +++ b/data/model/Model.cpp Tue Apr 29 15:34:17 2008 +0000 @@ -90,6 +90,12 @@ this, SIGNAL(alignmentCompletionChanged())); } +const AlignmentModel * +Model::getAlignment() const +{ + return m_alignment; +} + const Model * Model::getAlignmentReference() const { diff -r d095214ffbaf -r 88ad01799040 data/model/Model.h --- a/data/model/Model.h Tue Apr 29 10:59:19 2008 +0000 +++ b/data/model/Model.h Tue Apr 29 15:34:17 2008 +0000 @@ -160,6 +160,17 @@ virtual void setAlignment(AlignmentModel *alignment); /** + * Retrieve the alignment model for this model. This is not a + * generally useful function, as the alignment you really want may + * be performed by the source model instead. You should normally + * use getAlignmentReference, alignToReference and + * alignFromReference instead of this. The main intended + * application for this function is in streaming out alignments to + * the session file. + */ + virtual const AlignmentModel *getAlignment() const; + + /** * Return the reference model for the current alignment timeline, * if any. */ diff -r d095214ffbaf -r 88ad01799040 data/model/PathModel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/model/PathModel.h Tue Apr 29 15:34:17 2008 +0000 @@ -0,0 +1,86 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2007 QMUL. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef _PATH_MODEL_H_ +#define _PATH_MODEL_H_ + +#include "Model.h" +#include "SparseModel.h" +#include "base/RealTime.h" + +#include + + +struct PathPoint +{ + PathPoint(long _frame) : frame(_frame), mapframe(_frame) { } + PathPoint(long _frame, long _mapframe) : + frame(_frame), mapframe(_mapframe) { } + + int getDimensions() const { return 2; } + + long frame; + long mapframe; + + QString getLabel() const { return ""; } + + void toXml(QTextStream &stream, QString indent = "", + QString extraAttributes = "") const { + stream << QString("%1\n") + .arg(indent).arg(frame).arg(mapframe).arg(extraAttributes); + } + + QString toDelimitedDataString(QString delimiter, + size_t sampleRate) const { + QStringList list; + list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str(); + list << QString("%1").arg(mapframe); + return list.join(delimiter); + } + + struct Comparator { + bool operator()(const PathPoint &p1, const PathPoint &p2) const { + if (p1.frame != p2.frame) return p1.frame < p2.frame; + return p1.mapframe < p2.mapframe; + } + }; + + struct OrderComparator { + bool operator()(const PathPoint &p1, const PathPoint &p2) const { + return p1.frame < p2.frame; + } + }; +}; + +class PathModel : public SparseModel +{ +public: + PathModel(size_t sampleRate, size_t resolution, bool notify = true) : + SparseModel(sampleRate, resolution, notify) { } + + virtual void toXml(QTextStream &out, + QString indent = "", + QString extraAttributes = "") const + { + SparseModel::toXml + (out, + indent, + QString("%1 subtype=\"path\"") + .arg(extraAttributes)); + } +}; + + +#endif diff -r d095214ffbaf -r 88ad01799040 data/model/SparseModel.h --- a/data/model/SparseModel.h Tue Apr 29 10:59:19 2008 +0000 +++ b/data/model/SparseModel.h Tue Apr 29 15:34:17 2008 +0000 @@ -133,6 +133,8 @@ QString getTypeName() const { return tr("Sparse"); } + virtual QString getXmlOutputType() const { return "sparse"; } + virtual void toXml(QTextStream &out, QString indent = "", QString extraAttributes = "") const; @@ -554,10 +556,13 @@ std::cerr << "SparseModel::toXml: extraAttributes = \"" << extraAttributes.toStdString() << std::endl; + QString type = getXmlOutputType(); + Model::toXml (out, indent, - QString("type=\"sparse\" dimensions=\"%1\" resolution=\"%2\" notifyOnAdd=\"%3\" dataset=\"%4\" %5") + QString("type=\"%1\" dimensions=\"%2\" resolution=\"%3\" notifyOnAdd=\"%4\" dataset=\"%5\" %6") + .arg(type) .arg(PointType(0).getDimensions()) .arg(m_resolution) .arg(m_notifyOnAdd ? "true" : "false")