Gaia
point.h
1 /*
2  * Copyright (C) 2006-2013 Music Technology Group - Universitat Pompeu Fabra
3  *
4  * This file is part of Gaia
5  *
6  * Gaia is free software: you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License as published by the Free
8  * Software Foundation (FSF), either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the Affero GNU General Public License
17  * version 3 along with this program. If not, see http://www.gnu.org/licenses/
18  */
19 
20 #ifndef GAIA_POINT_H
21 #define GAIA_POINT_H
22 
23 #include <QStringList>
24 #include <QTextStream>
25 #include <vector>
26 #include "types.h"
27 #include "pointlayout.h"
28 #include "descriptor.h"
29 #include "yamlcpp.h"
30 
31 
32 namespace gaia2 {
33 
34 
35 class UnscopedData {
36  public:
37  RealDescriptor freal;
39  StringDescriptor flabel;
41  EnumDescriptor fenumeration;
42  Array<EnumDescriptor> venumeration;
43 
44  UnscopedData() : freal(0, Real()), flabel(0, QString()), fenumeration(0, Enum()) {}
45 
46  bool operator==(const UnscopedData& rhs) const {
47  return (this->vreal == rhs.vreal)
48  && (this->vlabel == rhs.vlabel)
49  && (this->venumeration == rhs.venumeration)
50  && (this->freal == rhs.freal)
51  && (this->flabel == rhs.flabel)
52  && (this->fenumeration == rhs.fenumeration);
53  }
54 };
55 
56 class Scope {
57  public:
58  QString name;
59  Real start, end;
60  Scope() : name(""), start(0.0), end(0.0) {}
61 
62  bool operator==(const Scope& rhs) const {
63  return (this->name == rhs.name)
64  && (this->start == rhs.start)
65  && (this->end == rhs.end);
66  }
67 
68  friend QDataStream& operator<<(QDataStream& out, const Scope& scope);
69  friend QDataStream& operator>>(QDataStream& in, Scope& scope);
70 };
71 
72 class ScopedData {
73  public:
74  Scope scope;
75  UnscopedData data;
76 
77  bool operator==(const ScopedData& rhs) const {
78  return (this->scope == rhs.scope) && (this->data == rhs.data);
79  }
80 
81  bool operator!=(const ScopedData& rhs) const {
82  return !operator==(rhs);
83  }
84 };
85 
86 QDataStream& operator<<(QDataStream& out, const ScopedData& s);
87 QDataStream& operator>>(QDataStream& in, ScopedData& s);
88 
89 
90 // actual point representation is point.scope.name.idx
91 // (e.g.: p->_data[scope_idx].data.real[name_idx][index_in_desc]
92 // is it smarter to have it like point.name.scope.idx
93 // (e.g.: p->_data.real[name_idx][scope_idx][index_in_desc]
94 // the first one is smarter when we want to be able to easily compute distances
95 // between two segments, including all descriptors, the second one is better if
96 // we want to compute distances between 2 descriptors, the scope maybe
97 // differents (e.g.: compute the distance between 2 beat segmentations...)
98 //
99 // first solution also means that we may want to have a layout for each scope
100 // e.g.: global -> only including bpm, key, etc...
101 // segments -> centroid, zcr, etc...
102 
106 class Point {
107 
108  public:
109 
113  // NOTE: refrain from returning a const ref here, as it creates memory problems
114  // with (at least) swig
115  QString name() const { return _name; }
116 
120  void setName(const QString& name) { _name = name; }
121 
126  void load(const QString& filename,
127  const QStringList& select = QStringList() << "*",
128  const QStringList& exclude = QStringList());
129 
134  void loadFromString(const std::string& str,
135  const QStringList& select = QStringList() << "*",
136  const QStringList& exclude = QStringList());
137 
138 
142  void fromBase64(const std::string& data);
143 
147  void fromBase64(const QByteArray& data);
148 
152  std::string toBase64() const;
153 
154 
155  Point() : _data(1) {}
156  Point(const Point& rhs) : _name(rhs._name), _data(rhs._data), _layout(rhs._layout) {}
157  Point(const PointLayout& layout);
158  Point(const QString& name, const PointLayout& layout);
159  Point(const std::string& name, const PointLayout& layout);
160 
161  Point& operator=(const Point& rhs) {
162  _name = rhs._name;
163  _data = rhs._data;
164  _layout = rhs._layout;
165  return *this;
166  }
167 
168  ~Point();
169 
170  bool operator==(const Point& rhs) const;
171 
177  static Point* fromSingleSegment(const Point* point, int nsegment);
178 
190  void setSegment(int nsegment, const Point* point, int origsegment = 0);
191 
195  const PointLayout& layout() const { return _layout; }
196 
200  PointLayout& layout() { return _layout; }
201 
208  void setLayout(const PointLayout& layout, int nsegments = 0);
209 
215  void switchLayout(const PointLayout& layout);
216 
217  //------- data access methods -------------------------------------
218  const Array<ScopedData>& data() const { return _data; }
219  Array<ScopedData>& data() { return _data; }
220 
221  int numberSegments() const { return _data.size(); }
222 
223  RealDescriptor value(const QString& name) const;
224  RealDescriptor value(int nsegment, const QString& name) const;
225 
226  StringDescriptor label(const QString& name) const;
227  StringDescriptor label(int nsegment, const QString& name) const;
228 
229  void setValue(const QString& name, const RealDescriptor& value);
230  void setValue(int nsegment, const QString& name, const RealDescriptor& value);
231 
232  void setLabel(const QString& name, const StringDescriptor& label);
233  void setLabel(int nsegment, const QString& name, const StringDescriptor& label);
234 
235  const Array<RealDescriptor>& vrealData(int i=0) const { return _data[i].data.vreal; }
236  Array<RealDescriptor>& vrealData(int i=0) { return _data[i].data.vreal; }
237 
238  const Array<StringDescriptor>& vstringData(int i=0) const { return _data[i].data.vlabel; }
239  Array<StringDescriptor>& vstringData(int i=0) { return _data[i].data.vlabel; }
240 
241  const Array<EnumDescriptor>& venumData(int i=0) const { return _data[i].data.venumeration; }
242  Array<EnumDescriptor>& venumData(int i=0) { return _data[i].data.venumeration; }
243 
244  const RealDescriptor& frealData(int i=0) const { return _data[i].data.freal; }
245  RealDescriptor& frealData(int i=0) { return _data[i].data.freal; }
246 
247  const StringDescriptor& fstringData(int i=0) const { return _data[i].data.flabel; }
248  StringDescriptor& fstringData(int i=0) { return _data[i].data.flabel; }
249 
250  const EnumDescriptor& fenumData(int i=0) const { return _data[i].data.fenumeration; }
251  EnumDescriptor& fenumData(int i=0) { return _data[i].data.fenumeration; }
252 
253  const Scope& scope(int i=0) const { checkValidSegment(this, i); return _data[i].scope; }
254  Scope& scope(int i=0) { checkValidSegment(this, i); return _data[i].scope; }
255 
256  protected:
257  QString _name;
258 
259  Array<ScopedData> _data;
260 
261  // should we have a layout for each different scope?
262  // QMap<Scope, PointLayout*> _layouts;
263  // e.g.: global -> only including bpm, key, etc...
264  // segments -> centroid, zcr, etc...
265  PointLayout _layout;
266 
272  void setLayoutUnsafe(const PointLayout& layout) {
273  _layout = layout;
274  }
275 
280  void remapLayoutAndEnums(const PointLayout& layout);
281 
285  static void checkValidSegment(const Point* point, int segment);
286 
294  void applyLayout(int nsegments);
295 
296  void yamlNodeToLayout(const yaml::Node& root, PointLayout& layout,
297  const QString& parentName = "");
298 
299  void fillLayout(const yaml::Node& root, const PointLayout& layout,
300  UnscopedData& data, const QString& parentName = "");
301 
302  void load(yaml::Node& node,
303  const QStringList& select,
304  const QStringList& exclude);
305 
306  friend class DataSet; // mostly to be able to access setLayoutUnsafe
307 
308  friend QDataStream& operator<<(QDataStream& out, const Point& point);
309  friend QDataStream& operator>>(QDataStream& in, Point& point);
310 };
311 
312 
313 // some useful defines that will be used in lots of places
314 #define FORSEG(p) for (int nseg=0; nseg<(p).numberSegments(); nseg++)
315 
316 } // namespace gaia2
317 
318 #endif // GAIA_POINT_H
void setLayoutUnsafe(const PointLayout &layout)
WARNING: Use this function only if you know 100% what you&#39;re doing! This neither make sure the layout...
Definition: point.h:272
This class represents a dataset and all related information.
Definition: dataset.h:91
Definition: point.h:72
This class describes the layout of a point.
Definition: pointlayout.h:60
Definition: point.h:35
Main Gaia namespace, which contains all the library functions.
Definition: addfield.cpp:22
QString name() const
Returns the point name, which also acts as its unique identifier.
Definition: point.h:115
const PointLayout & layout() const
Returns the current layout of the point.
Definition: point.h:195
Definition: yamlcpp.h:77
PointLayout & layout()
Returns the current layout of the point.
Definition: point.h:200
void setName(const QString &name)
Sets the point name, which also acts as its unique identifier.
Definition: point.h:120
Definition: types.h:73
Definition: point.h:106
Definition: point.h:56