Simband API
Simband API documentation, for accessing data from sensors and algorithms.
 All Classes Files Functions Variables Typedefs Enumerations Enumerator
vobio.hpp
Go to the documentation of this file.
1 #ifndef VOBIO_HPP
2 #define VOBIO_HPP
3 
4 #include "vobio.h"
5 
6 #include <functional>
7 #include <memory>
8 #include <memory.h>
9 #include <limits>
10 #include <vector>
11 #include <cmath>
12 #include <string>
13 
14 
22 namespace vobio {
23 
27 typedef std::shared_ptr<std::vector<float>> pack_t;
28 
35 inline void send(vobio_stream_id_h id, double ts, pack_t d)
36 {
37  vobio_send(id, ts, d->data(), d->size());
38 }
39 
46 inline void send(vobio_stream_id_h id, double ts, float value)
47 {
48  vobio_send(id, ts, &value, 1);
49 }
50 
51 class stream {
52 public:
53  stream() { }
54  stream(const stream&) = default;
55  stream(stream&&) = default;
56 
57  stream(vobio_stream_id_h stream) : m_stream(stream) { }
58  explicit stream(const std::string& type);
59  explicit stream(const std::string& type, int index) : stream (type + "." + std::to_string(index)) { }
60 
61  static stream fromKeyword(const std::string& keyword);
62  static std::vector<stream> getAllByType(const std::string& type);
63 
64  std::string keyword() const { return m_stream ? vobio_stream_keyword_get(m_stream) : ""; }
65  std::string type() const;
66  std::string description() const;
67  float sampleRate() const;
68  vobio_stream_category_e category() const;
69  std::string getEnumName(float v) const;
70  vobio::stream confidence() const { return overlay("confidence"); }
71  vobio::stream visual() const { return overlay("visual"); }
72  vobio::stream beats() const { return overlay("beats"); }
73  vobio::stream typical() const { return overlay("typical"); }
74  vobio::stream overlay(const char* o) const { return stream(type() + "/" + o); }
75 
76  operator vobio_stream_id_h() const { return m_stream; }
77  operator bool() const { return m_stream; }
78 
79  stream& operator=(const stream&) = default;
80  stream& operator=(vobio_stream_id_h s) { m_stream = s; return *this; }
81  bool operator==(const stream& o) const { return m_stream == o.m_stream; }
82  bool operator!=(const stream& o) const { return m_stream != o.m_stream; }
83 
84 private:
85  friend bool operator==(const stream& s1, vobio_stream_id_h s2);
86  vobio_stream_id_h m_stream = nullptr;
87 };
88 
89 inline bool operator==(const stream& s1, vobio_stream_id_h s2) { return s1.m_stream == s2; }
90 inline bool operator==(vobio_stream_id_h s1, const stream& s2) { return operator==(s2, s1); }
91 inline bool operator!=(const stream& s1, vobio_stream_id_h s2) { return !operator==(s1, s2); }
92 inline bool operator!=(vobio_stream_id_h s1, const stream& s2) { return !operator==(s2, s1); }
93 
94 inline std::vector<vobio_sample_s> get_samples(vobio_stream_id_h s, double from, double to)
95 {
96  vobio_sample_s* samples = nullptr;
97  std::vector<vobio_sample_s> v;
98  int count = 0;
99  vobio_get_samples(s, from, to, &samples, &count);
100  if (!count)
101  return v;
102 
103  v.resize(count);
104  std::copy(samples, samples + count, v.begin());
105  delete samples;
106  return v;
107 }
108 
113 class clock {
114 public:
115  clock(const clock&) = default;
116  clock(clock&&) = default;
117 
118  clock() { }
119  template<class ... Args> clock(Args ... args) { addStream(args...); }
120 
121  clock& operator=(const clock&) = default;
122  bool operator==(const clock& o) const { return m_clock == o.m_clock; }
123  bool operator!=(const clock& o) const { return m_clock != o.m_clock; }
124  operator bool() const { return bool(m_clock); }
125  operator vobio_clock_h() const { return m_clock->that; }
126 
127  template<class ... Args> void addStream(Args ... args) { ensure(); _addStream(args...); }
128  template<class ... Args> void removeStream(Args ... args) { ensure(); _removeStream(args...); }
129 
130  double now() const { double t = 0; vobio_get_current_time(m_clock->that, &t); return t; }
131 
136  void setGapResetThreshold(double seconds)
137  {
138  vobio_clock_set_gap_reset_threshold(m_clock->that, seconds);
139  }
140 
141 private:
142  struct Holder {
143  Holder(vobio_clock_h b) : that(b) { }
144  ~Holder() { vobio_clock_destroy(that); }
145  vobio_clock_h that;
146  };
147  std::shared_ptr<Holder> m_clock;
148 
149  void _addStream(vobio::stream s) { vobio_clock_add_stream(m_clock->that, s); }
150  void _addStream(const std::vector<vobio::stream>& streams) { for (const auto& s: streams) _addStream(s); }
151  template<class ... Args> void _addStream(vobio::stream s, Args ... args)
152  {
153  _addStream(s);
154  _addStream(args...);
155  }
156 
157  void _removeStream(vobio::stream s) { vobio_clock_remove_stream(m_clock->that, s); }
158  void _removeStream(const std::vector<vobio::stream>& streams) { for (const auto& s: streams) _removeStream(s); }
159  template<class ... Args> void _removeStream(vobio::stream s, Args ... args)
160  {
161  _removeStream(s);
162  _removeStream(args...);
163  }
164 
165  void ensure()
166  {
167  if (m_clock)
168  return;
169 
170  vobio_clock_h h;
172  m_clock = std::make_shared<Holder>(h);
173  }
174 
175 };
176 
180 class receiver {
181 public:
182  typedef std::function<void(double timestamp, const float* samples, int numSamples)> callback1;
183  typedef std::function<void(double timestamp, pack_t)> callback2;
184  typedef std::function<void(double timestamp, float value)> callback3;
185  typedef std::function<void(double timestamp)> callback4;
186  typedef std::function<void()> callback5;
187 
188  receiver() { }
189  receiver(const receiver&) = default;
190  receiver(receiver&&) = default;
191 
192  receiver(vobio_stream_id_h stream) : m_stream(stream) { }
193  receiver(const clock& c, vobio_stream_id_h stream) : m_clock(c), m_stream(stream) { }
194 
195  template<typename Callback>
196  receiver(vobio_stream_id_h stream, Callback cb) : receiver(stream) { setCallback(cb); }
197 
198  template<typename Callback>
199  receiver(const clock& c, vobio_stream_id_h stream, Callback cb) : receiver(c, stream) { setCallback(cb); }
200 
201  receiver& operator=(const receiver&) = default;
202  bool operator==(const receiver& o) const { return m_receiver == o.m_receiver; }
203  bool operator!=(const receiver& o) const { return m_receiver != o.m_receiver; }
204  operator bool() const { return m_stream; }
205 
206  void setCallback(callback1);
207  void setCallback(callback2);
208  void setCallback(callback3);
209  void setCallback(callback4);
210  void setCallback(callback5);
211  void resetCallback() { m_receiver.reset(); }
212 
213  vobio::stream stream() const { return m_stream; }
214 private:
215  struct Holder {
216  ~Holder();
217 
218  vobio_receiver_h receiver = nullptr;
219  callback1 cb;
220  vobio_clock_receiver_h id = nullptr;
221  };
222 
223  vobio::clock m_clock;
224  vobio::stream m_stream;
225  std::shared_ptr<Holder> m_receiver;
226 };
227 
231 class timer {
232 public:
233  timer() { }
234  timer(const timer&) = default;
235  timer(timer&&) = default;
236  timer(const vobio::clock& clock, std::function<void()> callback)
237  {
238  if (!clock || !callback)
239  return;
240 
241  auto holder = std::make_shared<Holder>();
242  auto cb = [] (void* d) { reinterpret_cast<Holder*>(d)->m_callback(); };
243  if (vobio_timer_create(clock, cb, holder.get(), &holder->that) != VOBIO_SUCCESS)
244  return;
245 
246  m_timer = holder;
247  m_timer->m_callback = callback;
248  m_timer->m_interval = -1;
249  }
250  timer(const vobio::clock& clock, double interval, std::function<void()> cb) : timer(clock, cb) { start(interval); }
251 
252  timer& operator=(const timer&) = default;
253  bool operator==(const timer& o) const { return m_timer == o.m_timer; }
254  bool operator!=(const timer& o) const { return m_timer != o.m_timer; }
255  operator bool() const { return bool(m_timer); }
256  operator vobio_timer_h() const { return m_timer->that; }
257 
258  void start(double interval)
259  {
260  if (m_timer && vobio_timer_start(m_timer->that, interval) == VOBIO_SUCCESS)
261  m_timer->m_interval = interval;
262  }
263 
264  void stop()
265  {
266  if (!m_timer)
267  return;
268  vobio_timer_stop(m_timer->that);
269  m_timer->m_interval = -1;
270  }
271 
272  double interval() const { return m_timer ? m_timer->m_interval : -1; }
273 
274 private:
275  struct Holder {
276  ~Holder() { vobio_timer_destroy(that); }
277  std::function<void()> m_callback;
278  vobio_timer_h that = nullptr;
279  double m_interval;
280  };
281 
282  std::shared_ptr<Holder> m_timer;
283 };
284 
288 class buffer {
289 public:
290  buffer() { }
291  buffer(vobio_stream_id_h stream, double interval);
292 
293  buffer(const buffer&) = default;
294  buffer(buffer&&) = default;
295  buffer& operator=(const buffer&) = default;
296  bool operator==(const buffer& o) const { return m_buffer == o.m_buffer; }
297  bool operator!=(const buffer& o) const { return m_buffer != o.m_buffer; }
298  operator bool() { return bool(m_buffer); }
299 
300  const vobio::stream stream() const { return m_buffer ? m_buffer->id : vobio::stream(); }
301  const float* data() const { return m_buffer ? m_buffer->data : nullptr; }
302  size_t size() const { return m_buffer ? m_buffer->size : 0; } // in samples
303  double startTime() const {
304  double ts = -1;
305  vobio_buffer_start_time_get(m_buffer->that, &ts);
306  return ts;
307  }
308 
309  void updateToAndReset(double time) { updateTo(time); reset(); }
310 
311  // iterators
312  const float* begin() const { return data(); }
313  const float* end() const { return data() + size(); }
314 
315 private:
316  struct Holder {
317  Holder(vobio_buffer_h b) : that(b) { }
318  ~Holder() { vobio_buffer_destroy(that); }
319  vobio_buffer_h that;
320  vobio::stream id;
321  float* data;
322  int size;
323  };
324  void initialize(vobio_buffer_h b, vobio_stream_id_h i);
325  std::shared_ptr<Holder> m_buffer;
326 
327  buffer(vobio_buffer_h b) { initialize(b, nullptr); }
328  void updateTo(double time) { vobio_buffer_update_to(m_buffer->that, time); }
329  void reset() { vobio_buffer_reset(m_buffer->that); }
330 };
331 
332 inline std::string stream::type() const
333 {
334  if (!m_stream)
335  return "";
336 
337  const char* result;
338  return vobio_stream_type_get(m_stream, &result) == VOBIO_SUCCESS ? result : "";
339 }
340 
341 inline std::string stream::description() const
342 {
343  if (!m_stream)
344  return "";
345 
346  char* result;
347  return vobio_stream_description_get(m_stream, &result) == VOBIO_SUCCESS ? result : "";
348 }
349 
350 inline float stream::sampleRate() const
351 {
352  if (!m_stream)
353  return NAN;
354 
355  float result;
356  return vobio_stream_sample_rate_get(m_stream, &result) == VOBIO_SUCCESS ? result : NAN;
357 }
358 
359 inline vobio_stream_category_e stream::category() const
360 {
361  if (!m_stream)
362  return VOBIO_STREAM_CATEGORY_UNKOWN;
363 
365  return vobio_stream_category_get(m_stream, &result) == VOBIO_SUCCESS ? result : VOBIO_STREAM_CATEGORY_UNKOWN;
366 }
367 
368 inline std::string stream::getEnumName(float v) const
369 {
370  if (!m_stream)
371  return "";
372 
373  char* result;
374  return vobio_stream_enum_value_name_get(m_stream, v, &result) == VOBIO_SUCCESS ? result : "";
375 }
376 
377 inline stream stream::fromKeyword(const std::string& keyword)
378 {
379  vobio_stream_id_h result;
380  return vobio_stream_get_from_keyword(keyword.c_str(), &result) == VOBIO_SUCCESS ? stream(result) : stream();
381 }
382 
383 inline std::vector<stream> stream::getAllByType(const std::string& type)
384 {
385  std::vector<stream> streams;
386  for (int i = 0; ; ++i) {
387  vobio::stream s(type + "." + std::to_string(i));
388  if (!s)
389  return streams;
390 
391  streams.push_back(std::move(s));
392  }
393 
394  return streams;
395 }
396 
397 inline stream::stream(const std::string& type)
398 {
399  if (vobio_stream_get_by_type(type.c_str(), &m_stream) != VOBIO_SUCCESS)
400  m_stream = nullptr;
401 }
402 
403 inline buffer::buffer(vobio_stream_id_h stream, double interval) {
404  vobio_buffer_h b;
405  if (vobio_buffer_create(stream, interval * 1000, &b) == VOBIO_SUCCESS)
406  initialize(b, stream);
407 }
408 
409 inline void buffer::initialize(vobio_buffer_h b, vobio_stream_id_h i)
410 {
411  m_buffer = std::make_shared<Holder>(b);
412  m_buffer->id = i;
413  vobio_buffer_get_data_pointer(m_buffer->that, &m_buffer->data);
414  vobio_buffer_get_sample_count(m_buffer->that, &m_buffer->size);
415 }
416 
417 inline receiver::Holder::~Holder() {
418  if (id)
420  else
421  vobio_receiver_destroy(receiver);
422 }
423 
424 inline void receiver::setCallback(callback1 cb)
425 {
426  if (!m_stream)
427  return;
428 
429  if (!cb) {
430  m_receiver.reset();
431  return;
432  }
433 
434  auto holder = std::make_shared<Holder>();
435  holder->cb = cb;
436 
437  auto exec = [] (double timestamp, const float* samples, int size, void* d) {
438  (*reinterpret_cast<callback1*>(d))(timestamp, samples, size);
439  };
440 
441  if (m_clock) {
442  if (vobio_clock_create_receiver(m_clock, m_stream, exec, &holder->cb, &holder->id) == VOBIO_SUCCESS)
443  m_receiver = holder;
444  return;
445  }
446 
447  if (vobio_receiver_create(m_stream, exec, &holder->cb, &holder->receiver) == VOBIO_SUCCESS)
448  m_receiver = holder;
449 }
450 
451 inline void receiver::setCallback(callback2 cb)
452 {
453  setCallback([cb] (double ts, const float* samples, int numSamples) {
454  auto data = std::make_shared<std::vector<float>>(numSamples);
455  memcpy(data->data(), samples, numSamples * sizeof(float));
456  cb(ts, data);
457  });
458 }
459 
460 inline void receiver::setCallback(callback3 cb)
461 {
462  setCallback([cb] (double ts, const float* samples, int numSamples) {
463  if (numSamples > 0)
464  cb(ts, *samples);
465  });
466 }
467 
468 inline void receiver::setCallback(callback4 cb)
469 {
470  setCallback([cb] (double ts, const float*, int) {
471  cb(ts);
472  });
473 }
474 
475 inline void receiver::setCallback(callback5 cb)
476 {
477  setCallback([cb] (double, const float*, int) {
478  cb();
479  });
480 }
481 
482 inline vobio_sample_s last_sample(vobio_stream_id_h stream, double time)
483 {
484  vobio_sample_s* s = nullptr;
485  int count = 1;
486  if (vobio_get_samples_to(stream, time, &s, &count) || !count)
487  return vobio_sample_s { 0, std::numeric_limits<float>::quiet_NaN() };
488  vobio_sample_s sample = s[0];
489  delete s;
490  return sample;
491 }
492 
493 inline float last_value(vobio_stream_id_h stream, double time)
494 {
495  return last_sample(stream, time).data;
496 }
497 }
498 
499 #endif // VOBIO_HPP
struct vobio_receiver_opaque * vobio_receiver_h
Handle for a receiver.
Definition: vobio.h:72
VOBIO_EXPORT int vobio_buffer_get_data_pointer(vobio_buffer_h buffer, float **data)
gets a pointer to the buffer data.
VOBIO_EXPORT int vobio_buffer_get_sample_count(vobio_buffer_h buffer, int *count)
gets a pointer to the buffer data.
VOBIO_EXPORT int vobio_clock_set_gap_reset_threshold(vobio_clock_h clock, double seconds)
Sets the number of seconds between clock ticks, above which the timers are reset. If the number is 0...
float data
Definition: vobio.h:86
VOBIO_EXPORT int vobio_get_samples(vobio_stream_id_h stream, double from, double to, vobio_sample_s **samples, int *count)
VOBIO_EXPORT int vobio_send(vobio_stream_id_h stream, double timestamp, const float *samples, int count)
Sends new samples to VOBIO.
Definition: vobio.h:32
VOBIO_EXPORT int vobio_stream_get_from_keyword(const char *keyword, vobio_stream_id_h *id)
Generates a stream ID based on a keyword previously created by vobio_stream_keyword_get().
A C++ wrapper for vobio_timer_h.
Definition: vobio.hpp:231
A class that wraps vobio_clock_h.
Definition: vobio.hpp:113
VOBIO_EXPORT int vobio_buffer_start_time_get(vobio_buffer_h buffer, double *timestamp)
Retrieves the start time for this buffer.
VOBIO_EXPORT int vobio_receiver_destroy(vobio_receiver_h receiver)
vobio_receiver_destroy
VOBIO_EXPORT int vobio_stream_enum_value_name_get(vobio_stream_id_h id, float value, char **name)
vobio_stream_get_enum_value_name
A C++ wrapper for vobio_buffer_h.
Definition: vobio.hpp:288
VOBIO_EXPORT int vobio_clock_remove_stream(vobio_clock_h clock, vobio_stream_id_h stream)
vobio_clock_remove_stream
VOBIO_EXPORT int vobio_stream_sample_rate_get(vobio_stream_id_h id, float *sampleRate)
Returns the sample rate (Hz) of the stream.
struct vobio_buffer_opaque * vobio_buffer_h
A handle that can be used to stream live data to a single buffer.
Definition: vobio.h:43
VOBIO_EXPORT int vobio_stream_description_get(vobio_stream_id_h id, char **description)
Gets the description of this stream.
VOBIO_EXPORT int vobio_stream_category_get(vobio_stream_id_h id, vobio_stream_category_e *category)
Returns the category of the stream.
VOBIO_EXPORT int vobio_timer_stop(vobio_timer_h timer)
Stops a running timer.
Definition: vobio.hpp:51
A sample represents a value at a point in time.
Definition: vobio.h:84
VOBIO_EXPORT int vobio_clock_create_receiver(vobio_clock_h clock, vobio_stream_id_h stream, vobio_receive_cb callback, void *userData, vobio_clock_receiver_h *receiver)
Sets a callback to be called for each new value generated for this stream. The stream need not to be ...
VOBIO_EXPORT int vobio_stream_get_by_type(const char *type, vobio_stream_id_h *id)
Returns the stream ID for this type.
VOBIO_EXPORT int vobio_clock_destroy_receiver(vobio_clock_receiver_h id)
Removes the receiver identified by id from the clock.
VOBIO_EXPORT int vobio_clock_destroy(vobio_clock_h clock)
vobio_clock_destroy
VOBIO_EXPORT int vobio_clock_add_stream(vobio_clock_h clock, vobio_stream_id_h stream)
vobio_clock_add_stream
struct vobio_clock_opaque * vobio_clock_h
A clock object that is defined on top of a set of streams.
Definition: vobio.h:50
void * vobio_stream_id_h
A handle identifying a unique stream.
Definition: vobio.h:79
VOBIO_EXPORT int vobio_buffer_reset(vobio_buffer_h buffer)
Resets the buffer so that the data is ordered correctly by timestamp.
VOBIO_EXPORT int vobio_timer_create(vobio_clock_h clock, vobio_timer_cb callback, void *userData, vobio_timer_h *timer)
vobio_timer_create
VOBIO_EXPORT int vobio_clock_create(vobio_clock_h *clock)
vobio_clock_create
VOBIO_EXPORT const char * vobio_stream_keyword_get(vobio_stream_id_h id)
Produces a string that can be used for debugging or persistency.
VOBIO_EXPORT int vobio_receiver_create(vobio_stream_id_h stream, vobio_receive_cb cb, void *userData, vobio_receiver_h *receiver)
vobio_receiver_create. Registers a callback that gets invoked when new data is generated for the give...
vobio_stream_category_e
A category classifies a stream.
Definition: vobio.h:96
VOBIO_EXPORT int vobio_timer_start(vobio_timer_h timer, double interval)
Start the timer notifications, with a given interval.
VOBIO_EXPORT int vobio_timer_destroy(vobio_timer_h timer)
Destroys an existing timer.
VOBIO_EXPORT int vobio_buffer_create(vobio_stream_id_h id, int milliseconds, vobio_buffer_h *buffer)
Creates a buffer object, allowing live-streaming of sample data.
VOBIO_EXPORT int vobio_get_current_time(vobio_clock_h clock, double *timestamp)
vobio_get_current_time
A class that wraps vobio_receiver_h.
Definition: vobio.hpp:180
struct vobio_timer_opaque * vobio_timer_h
Handle for a timer.
Definition: vobio.h:59
VOBIO_EXPORT int vobio_buffer_destroy(vobio_buffer_h buffer)
vobio_buffer_destroy
VOBIO_EXPORT int vobio_get_samples_to(vobio_stream_id_h stream, double to, vobio_sample_s **samples, int *count)
This file contains the public API for accessing VOBIO data.
VOBIO_EXPORT int vobio_stream_type_get(vobio_stream_id_h id, const char **type)
vobio_stream_type_get
struct vobio_clock_receiver_opaque * vobio_clock_receiver_h
Definition: vobio.h:64
void setGapResetThreshold(double seconds)
Sets the minimum gap between data points above which the timers of this clock are reset...
Definition: vobio.hpp:136
VOBIO_EXPORT int vobio_buffer_update_to(vobio_buffer_h buffer, double timestamp)
Updates the data in the buffer to end at the specified time.