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