annotate data/model/Path.h @ 1873:1d44fdc8196c csv-import-headers

Extend tests to include testing (at least some of) the actual data as well as the layout
author Chris Cannam
date Thu, 18 Jun 2020 13:42:48 +0100
parents 14bf9bf5ac28
children
rev   line source
Chris@407 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@407 2
Chris@407 3 /*
Chris@407 4 Sonic Visualiser
Chris@407 5 An audio file viewer and annotation editor.
Chris@407 6 Centre for Digital Music, Queen Mary, University of London.
Chris@407 7
Chris@407 8 This program is free software; you can redistribute it and/or
Chris@407 9 modify it under the terms of the GNU General Public License as
Chris@407 10 published by the Free Software Foundation; either version 2 of the
Chris@407 11 License, or (at your option) any later version. See the file
Chris@407 12 COPYING included with this distribution for more information.
Chris@407 13 */
Chris@407 14
Chris@1738 15 #ifndef SV_PATH_H
Chris@1738 16 #define SV_PATH_H
Chris@407 17
Chris@1662 18 #include "base/XmlExportable.h"
Chris@1662 19 #include "base/RealTime.h"
Chris@1738 20 #include "base/BaseTypes.h"
Chris@1662 21
Chris@407 22 #include <QStringList>
Chris@1662 23 #include <set>
Chris@407 24
Chris@407 25 struct PathPoint
Chris@407 26 {
Chris@1662 27 PathPoint(sv_frame_t _frame) :
Chris@1662 28 frame(_frame), mapframe(_frame) { }
Chris@1040 29 PathPoint(sv_frame_t _frame, sv_frame_t _mapframe) :
Chris@407 30 frame(_frame), mapframe(_mapframe) { }
Chris@407 31
Chris@1863 32 // "The path consists of a series of points, each with frame equal
Chris@1863 33 // to the frame on the source model (aligned model) and mapframe
Chris@1863 34 // equal to the frame on the target model (reference model). Both
Chris@1863 35 // should be monotonically increasing."
Chris@1863 36
Chris@1040 37 sv_frame_t frame;
Chris@1040 38 sv_frame_t mapframe;
Chris@407 39
Chris@407 40 void toXml(QTextStream &stream, QString indent = "",
Chris@407 41 QString extraAttributes = "") const {
Chris@407 42 stream << QString("%1<point frame=\"%2\" mapframe=\"%3\" %4/>\n")
Chris@407 43 .arg(indent).arg(frame).arg(mapframe).arg(extraAttributes);
Chris@407 44 }
Chris@407 45
Chris@1060 46 QString toDelimitedDataString(QString delimiter, DataExportOptions,
Chris@1040 47 sv_samplerate_t sampleRate) const {
Chris@407 48 QStringList list;
Chris@407 49 list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str();
Chris@407 50 list << QString("%1").arg(mapframe);
Chris@407 51 return list.join(delimiter);
Chris@407 52 }
Chris@407 53
Chris@1662 54 bool operator<(const PathPoint &p2) const {
Chris@1662 55 if (frame != p2.frame) return frame < p2.frame;
Chris@1662 56 return mapframe < p2.mapframe;
Chris@1662 57 }
Chris@407 58 };
Chris@407 59
Chris@1738 60 class Path : public XmlExportable
Chris@407 61 {
Chris@407 62 public:
Chris@1738 63 Path(sv_samplerate_t sampleRate, int resolution) :
Chris@1738 64 m_sampleRate(sampleRate),
Chris@1738 65 m_resolution(resolution) {
Chris@1738 66 }
Chris@1738 67 Path(const Path &) =default;
Chris@1738 68 Path &operator=(const Path &) =default;
Chris@407 69
Chris@1738 70 typedef std::set<PathPoint> Points;
Chris@1662 71
Chris@1738 72 sv_samplerate_t getSampleRate() const { return m_sampleRate; }
Chris@1738 73 int getResolution() const { return m_resolution; }
Chris@1662 74
Chris@1670 75 int getPointCount() const {
Chris@1670 76 return int(m_points.size());
Chris@1670 77 }
Chris@1738 78
Chris@1738 79 const Points &getPoints() const {
Chris@1662 80 return m_points;
Chris@1662 81 }
Chris@425 82
Chris@1662 83 void add(PathPoint p) {
Chris@1738 84 m_points.insert(p);
Chris@1662 85 }
Chris@1662 86
Chris@1662 87 void remove(PathPoint p) {
Chris@1738 88 m_points.erase(p);
Chris@1662 89 }
Chris@1662 90
Chris@1662 91 void clear() {
Chris@1738 92 m_points.clear();
Chris@1662 93 }
Chris@1662 94
Chris@1662 95 /**
Chris@1662 96 * XmlExportable methods.
Chris@1662 97 */
Chris@1662 98 void toXml(QTextStream &out,
Chris@1738 99 QString indent = "",
Chris@1738 100 QString extraAttributes = "") const override {
Chris@1677 101
Chris@1738 102 // For historical reasons we serialise a Path as a model,
Chris@1738 103 // although the class itself no longer is.
Chris@1741 104
Chris@1741 105 // We also write start and end frames - which our API no
Chris@1741 106 // longer exposes - just for backward compatibility
Chris@1741 107
Chris@1741 108 sv_frame_t start = 0;
Chris@1741 109 sv_frame_t end = 0;
Chris@1741 110 if (!m_points.empty()) {
Chris@1741 111 start = m_points.begin()->frame;
Chris@1741 112 end = m_points.rbegin()->frame + m_resolution;
Chris@1741 113 }
Chris@1738 114
Chris@1677 115 // Our dataset doesn't have its own export ID, we just use
Chris@1677 116 // ours. Actually any model could do that, since datasets
Chris@1738 117 // aren't in the same id-space as models (or paths) when
Chris@1738 118 // re-read
Chris@1662 119
Chris@1738 120 out << indent;
Chris@1738 121 out << QString("<model id=\"%1\" name=\"\" sampleRate=\"%2\" "
Chris@1741 122 "start=\"%3\" end=\"%4\" type=\"sparse\" "
Chris@1741 123 "dimensions=\"2\" resolution=\"%5\" "
Chris@1741 124 "notifyOnAdd=\"true\" dataset=\"%6\" "
Chris@1741 125 "subtype=\"path\" %7/>\n")
Chris@1738 126 .arg(getExportId())
Chris@1738 127 .arg(m_sampleRate)
Chris@1741 128 .arg(start)
Chris@1741 129 .arg(end)
Chris@1738 130 .arg(m_resolution)
Chris@1738 131 .arg(getExportId())
Chris@1738 132 .arg(extraAttributes);
Chris@1662 133
Chris@1675 134 out << indent << QString("<dataset id=\"%1\" dimensions=\"2\">\n")
Chris@1677 135 .arg(getExportId());
Chris@1662 136
Chris@1675 137 for (PathPoint p: m_points) {
Chris@1675 138 p.toXml(out, indent + " ", "");
Chris@1675 139 }
Chris@1675 140
Chris@1675 141 out << indent << "</dataset>\n";
Chris@1662 142 }
Chris@1679 143
Chris@1679 144 QString toDelimitedDataString(QString delimiter,
Chris@1679 145 DataExportOptions,
Chris@1679 146 sv_frame_t startFrame,
Chris@1738 147 sv_frame_t duration) const {
Chris@1679 148
Chris@1679 149 QString s;
Chris@1679 150 for (PathPoint p: m_points) {
Chris@1679 151 if (p.frame < startFrame) continue;
Chris@1679 152 if (p.frame >= startFrame + duration) break;
Chris@1679 153 s += QString("%1%2%3\n")
Chris@1679 154 .arg(p.frame)
Chris@1679 155 .arg(delimiter)
Chris@1679 156 .arg(p.mapframe);
Chris@1679 157 }
Chris@1679 158
Chris@1679 159 return s;
Chris@1679 160 }
Chris@1662 161
Chris@1662 162 protected:
Chris@1662 163 sv_samplerate_t m_sampleRate;
Chris@1662 164 int m_resolution;
Chris@1738 165 Points m_points;
Chris@407 166 };
Chris@407 167
Chris@407 168
Chris@407 169 #endif