EventSeries.h
Go to the documentation of this file.
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_EVENT_SERIES_H
16 #define SV_EVENT_SERIES_H
17 
18 #include "Event.h"
19 #include "XmlExportable.h"
20 
21 #include <set>
22 #include <string>
23 #include <vector>
24 #include <functional>
25 
26 #include <QMutex>
27 
28 //#define DEBUG_EVENT_SERIES 1
29 
49 class EventSeries : public XmlExportable
50 {
51 public:
53  ~EventSeries() =default;
54 
55  EventSeries(const EventSeries &);
56 
59 
60  bool operator==(const EventSeries &other) const;
61 
62  static EventSeries fromEvents(const EventVector &ee);
63 
64  void clear();
65  void add(const Event &e);
66  void remove(const Event &e);
67  bool contains(const Event &e) const;
68  bool isEmpty() const;
69  int count() const;
70 
75  sv_frame_t getStartFrame() const;
76 
81  sv_frame_t getEndFrame() const;
82 
101  sv_frame_t duration) const;
102 
111 
128  sv_frame_t duration,
129  int overspill = 0) const;
130 
138  sv_frame_t duration) const;
139 
144  return getEventsStartingWithin(frame, 1);
145  }
146 
150  EventVector getAllEvents() const;
151 
164  bool getEventPreceding(const Event &e, Event &preceding) const;
165 
178  bool getEventFollowing(const Event &e, Event &following) const;
179 
180  enum Direction {
183  };
184 
192  bool getNearestEventMatching(sv_frame_t startSearchAt,
193  std::function<bool(const Event &)> predicate,
194  Direction direction,
195  Event &found) const;
196 
201  Event getEventByIndex(int index) const;
202 
208  int getIndexForEvent(const Event &e) const;
209 
213  void toXml(QTextStream &out,
214  QString indent,
215  QString extraAttributes) const override;
216 
220  void toXml(QTextStream &out,
221  QString indent,
222  QString extraAttributes,
224 
229  QVector<QString>
232 
237  QVector<QVector<QString>>
239  sv_frame_t startFrame,
240  sv_frame_t duration,
241  sv_samplerate_t sampleRate,
242  sv_frame_t resolution,
243  Event fillEvent) const;
244 
245 private:
246  mutable QMutex m_mutex;
247 
248  EventSeries(const EventSeries &other, const QMutexLocker &);
249 
263  typedef std::vector<Event> Events;
264  Events m_events;
265 
281  typedef std::map<sv_frame_t, std::vector<Event>> FrameEventMap;
282  FrameEventMap m_seams;
283 
294 
302  void createSeam(sv_frame_t frame) {
303  auto itr = m_seams.lower_bound(frame);
304  if (itr == m_seams.end() || itr->first > frame) {
305  if (itr != m_seams.begin()) {
306  --itr;
307  }
308  }
309  if (itr == m_seams.end()) {
310  m_seams[frame] = {};
311  } else if (itr->first < frame) {
312  m_seams[frame] = itr->second;
313  } else if (itr->first > frame) { // itr must be begin()
314  m_seams[frame] = {};
315  }
316  }
317 
327  bool seamsEqual(const std::vector<Event> &s1,
328  const std::vector<Event> &s2) const {
329 
330  if (s1.size() != s2.size()) {
331  return false;
332  }
333 
334 #ifdef DEBUG_EVENT_SERIES
335  for (int i = 0; in_range_for(s1, i); ++i) {
336  for (int j = i + 1; in_range_for(s1, j); ++j) {
337  if (s1[i] == s1[j] || s2[i] == s2[j]) {
338  throw std::runtime_error
339  ("debug error: duplicate event in s1 or s2");
340  }
341  }
342  }
343 #endif
344 
345  std::set<Event> ee;
346  for (const auto &e: s1) {
347  ee.insert(e);
348  }
349  for (const auto &e: s2) {
350  if (ee.find(e) == ee.end()) {
351  return false;
352  }
353  }
354  return true;
355  }
356 
357 #ifdef DEBUG_EVENT_SERIES
358  void dumpEvents() const {
359  std::cerr << "EVENTS (" << m_events.size() << ") [" << std::endl;
360  for (const auto &i: m_events) {
361  std::cerr << " " << i.toXmlString();
362  }
363  std::cerr << "]" << std::endl;
364  }
365 
366  void dumpSeams() const {
367  std::cerr << "SEAMS (" << m_seams.size() << ") [" << std::endl;
368  for (const auto &s: m_seams) {
369  std::cerr << " " << s.first << " -> {" << std::endl;
370  for (const auto &p: s.second) {
371  std::cerr << p.toXmlString(" ");
372  }
373  std::cerr << " }" << std::endl;
374  }
375  std::cerr << "]" << std::endl;
376  }
377 #endif
378 };
379 
380 #endif
double sv_samplerate_t
Sample rate.
Definition: BaseTypes.h:51
bool contains(const Event &e) const
bool seamsEqual(const std::vector< Event > &s1, const std::vector< Event > &s2) const
Return true if the two seam map entries contain the same set of events.
Definition: EventSeries.h:327
int count() const
Definition: EventSeries.cpp:79
bool getEventFollowing(const Event &e, Event &following) const
If e is in the series and is not the final event in it, set following to the event immediate followin...
int64_t sv_frame_t
Frame index, the unit of our time axis.
Definition: BaseTypes.h:31
void add(const Event &e)
Definition: EventSeries.cpp:89
EventVector getEventsStartingAt(sv_frame_t frame) const
Retrieve all events starting at exactly the given frame.
Definition: EventSeries.h:143
Event getEventByIndex(int index) const
Return the event at the given numerical index in the series, where 0 = the first event and count()-1 ...
EventVector getAllEvents() const
Retrieve all events, in their natural order.
QMutex m_mutex
Definition: EventSeries.h:246
static EventSeries fromEvents(const EventVector &ee)
Definition: EventSeries.cpp:62
sv_frame_t getStartFrame() const
Return the frame of the first event in the series.
std::vector< Event > Events
This vector contains all events in the series, in the normal sort order.
Definition: EventSeries.h:263
QVector< QVector< QString > > toStringExportRows(DataExportOptions options, sv_frame_t startFrame, sv_frame_t duration, sv_samplerate_t sampleRate, sv_frame_t resolution, Event fillEvent) const
Emit events starting within the given range as string rows ready for conversion to an e...
QVector< QString > getStringExportHeaders(DataExportOptions options, Event::ExportNameOptions) const
Return a label for each column that would be written by toStringExportRows.
int getIndexForEvent(const Event &e) const
Return the index of the first event in the series that does not compare inferior to the given event...
EventSeries & operator=(const EventSeries &)
Definition: EventSeries.cpp:35
void toXml(QTextStream &out, QString indent, QString extraAttributes) const override
Emit to XML as a dataset element.
bool isEmpty() const
Definition: EventSeries.cpp:72
void createSeam(sv_frame_t frame)
Create a seam at the given frame, copying from the prior seam if there is one.
Definition: EventSeries.h:302
EventVector getEventsCovering(sv_frame_t frame) const
Retrieve all events that cover the given frame.
bool getEventPreceding(const Event &e, Event &preceding) const
If e is in the series and is not the first event in it, set preceding to the event immediate precedin...
EventVector getEventsSpanning(sv_frame_t frame, sv_frame_t duration) const
Retrieve all events any part of which falls within the range in frames defined by the given frame f a...
sv_frame_t m_finalDurationlessEventFrame
The frame of the last durationless event we have in the series.
Definition: EventSeries.h:293
sv_frame_t getEndFrame() const
Return the frame plus duration of the event in the series that ends last.
bool operator==(const EventSeries &other) const
Definition: EventSeries.cpp:55
Events m_events
Definition: EventSeries.h:264
bool getNearestEventMatching(sv_frame_t startSearchAt, std::function< bool(const Event &)> predicate, Direction direction, Event &found) const
Return the first event for which the given predicate returns true, searching events with start frames...
bool in_range_for(const C &container, T i)
Check whether an integer index is in range for a container, avoiding overflows and signed/unsigned co...
Definition: BaseTypes.h:37
EventVector getEventsWithin(sv_frame_t frame, sv_frame_t duration, int overspill=0) const
Retrieve all events falling wholly within the range in frames defined by the given frame f and durati...
An immutable(-ish) type used for point and event representation in sparse models, as well as for inte...
Definition: Event.h:55
FrameEventMap m_seams
Definition: EventSeries.h:282
Container storing a series of events, with or without durations, and supporting the ability to query ...
Definition: EventSeries.h:49
std::map< sv_frame_t, std::vector< Event > > FrameEventMap
The FrameEventMap maps from frame number to a set of events.
Definition: EventSeries.h:281
std::vector< Event > EventVector
Definition: Event.h:494
EventVector getEventsStartingWithin(sv_frame_t frame, sv_frame_t duration) const
Retrieve all events starting within the range in frames defined by the given frame f and duration d...
~EventSeries()=default
int DataExportOptions