RAUL  0.8.0
TimeStamp.hpp
1 /* This file is part of Raul.
2  * Copyright (C) 2008-2009 David Robillard <http://drobilla.net>
3  *
4  * Raul is free software; you can redistribute it and/or modify it under the
5  * terms of the GNU General Public License as published by the Free Software
6  * Foundation; either version 2 of the License, or (at your option) any later
7  * version.
8  *
9  * Raul is distributed in the hope that it will be useful, but WITHOUT ANY
10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16  */
17 
18 #ifndef RAUL_TIME_STAMP_HPP
19 #define RAUL_TIME_STAMP_HPP
20 
21 #include <limits>
22 #include <stdint.h>
23 #include <math.h>
24 #include <cassert>
25 #include <iostream>
26 
27 namespace Raul {
28 
29 
33 class TimeUnit {
34 public:
35  enum Type {
36  FRAMES,
37  BEATS,
38  SECONDS
39  };
40 
44  inline TimeUnit(Type type, uint32_t ppt) {
45  assert(type == SECONDS || ppt != 0);
46  _type = type;
47  _ppt = ppt;
48  }
49 
50  static inline TimeUnit frames(uint32_t srate) { return TimeUnit(FRAMES, srate); }
51  static inline TimeUnit beats(uint32_t ppqn) { return TimeUnit(BEATS, ppqn); }
52  static inline TimeUnit seconds() { return TimeUnit(BEATS, std::numeric_limits<uint32_t>::max()); }
53 
54  inline Type type() const { return _type; }
55  inline uint32_t ppt() const { return _ppt; }
56 
57  inline bool operator==(const TimeUnit& rhs) const {
58  return (_type == rhs._type && _ppt == rhs._ppt);
59  }
60 
61  inline bool operator!=(const TimeUnit& rhs) const {
62  return (_type != rhs._type || _ppt != rhs._ppt);
63  }
64 
65 private:
66  Type _type;
67  uint32_t _ppt;
68 };
69 
70 
80 class TimeStamp {
81 public:
82  inline TimeStamp(TimeUnit unit, uint32_t ticks=0, uint32_t subticks=0)
83  : _ticks(ticks)
84  , _subticks(subticks)
85  , _unit(unit)
86  {}
87 
88  inline TimeStamp(TimeUnit unit, double dec)
89  : _ticks(static_cast<uint32_t>(floor(dec)))
90  , _subticks((dec - floor(dec)) * unit.ppt())
91  , _unit(unit)
92  {
93  assert(dec >= 0);
94  assert(dec <= std::numeric_limits<uint32_t>::max());
95  }
96 
97  inline TimeUnit unit() const { return _unit; }
98  inline uint32_t ticks() const { return _ticks; }
99  inline uint32_t subticks() const { return _subticks; }
100 
101  inline double to_double() const {
102  return _ticks + (_subticks / static_cast<double>(_unit.ppt()));
103  }
104 
105  inline bool is_zero() const {
106  return _ticks == 0 && _subticks == 0;
107  }
108 
109  inline TimeStamp& operator=(const TimeStamp& rhs) {
110  _ticks = rhs._ticks;
111  _subticks = rhs._subticks;
112  _unit = rhs._unit;
113  return *this;
114  }
115 
116  inline TimeStamp& operator=(uint32_t ticks) {
117  _ticks = ticks;
118  _subticks = 0;
119  return *this;
120  }
121 
122  inline bool operator==(const TimeStamp& rhs) const {
123  return _ticks == rhs._ticks
124  && _subticks == rhs._subticks
125  && _unit == rhs._unit;
126  }
127 
128  inline bool operator!=(const TimeStamp& rhs) const {
129  return ! operator==(rhs);
130  }
131 
132  inline bool operator<(const TimeStamp& rhs) const {
133  assert(_unit == rhs._unit);
134  return (_ticks < rhs._ticks
135  || (_ticks == rhs._ticks && _subticks < rhs._subticks));
136  }
137 
138  inline bool operator>(const TimeStamp& rhs) const {
139  assert(_unit == rhs._unit);
140  return (_ticks > rhs._ticks
141  || (_ticks == rhs._ticks && _subticks > rhs._subticks));
142  }
143 
144  inline bool operator<=(const TimeStamp& rhs) const {
145  return (*this == rhs) || ((*this) < rhs);
146  }
147 
148  inline bool operator>=(const TimeStamp& rhs) const {
149  return (*this == rhs) || ((*this) > rhs);
150  }
151 
152  inline TimeStamp& operator+=(const TimeStamp& rhs) {
153  assert(_unit == rhs._unit);
154  _ticks += rhs._ticks;
155  if (_subticks + rhs._subticks <= _unit.ppt()) {
156  _subticks += rhs._subticks;
157  } else if (rhs._subticks > 0) {
158  ++_ticks;
159  _subticks = rhs._subticks + _subticks - _unit.ppt();
160  }
161  return *this;
162  }
163 
164  inline TimeStamp& operator-=(const TimeStamp& rhs) {
165  assert(_unit == rhs._unit);
166  assert(rhs <= *this);
167  _ticks -= rhs._ticks;
168  if (_subticks >= rhs._subticks) {
169  _subticks -= rhs._subticks;
170  } else if (rhs._subticks > 0) {
171  --_ticks;
172  _subticks = _unit.ppt() - (rhs._subticks - _subticks);
173  }
174  return *this;
175  }
176 
177  inline TimeStamp operator+(const TimeStamp& rhs) const {
178  assert(_unit == rhs._unit);
179  TimeStamp result = *this;
180  result += rhs;
181  return result;
182  }
183 
184  inline TimeStamp operator-(const TimeStamp& rhs) const {
185  assert(_unit == rhs._unit);
186  TimeStamp result = *this;
187  result -= rhs;
188  return result;
189  }
190 
191 private:
192  uint32_t _ticks;
193  uint32_t _subticks;
194  TimeUnit _unit;
195 };
196 
197 
198 static inline std::ostream&
199 operator<<(std::ostream& os, const TimeStamp& t)
200 {
201  os << t.ticks() << ":" << t.subticks();
202  switch (t.unit().type()) {
203  case TimeUnit::FRAMES:
204  os << " frames";
205  break;
206  case TimeUnit::BEATS:
207  os << " beats";
208  break;
209  case TimeUnit::SECONDS:
210  os << " seconds";
211  break;
212  }
213  return os;
214 }
215 
216 
217 class FrameStamp : public TimeStamp {
218 public:
219  inline FrameStamp(uint32_t rate, uint32_t ticks=0, uint32_t subticks=0)
220  : TimeStamp(TimeUnit(TimeUnit::FRAMES, rate), ticks, subticks)
221  {}
222 };
223 
224 
225 class BeatStamp : public TimeStamp {
226 public:
227  inline BeatStamp(uint32_t ppqn, uint32_t ticks=0, uint32_t subticks=0)
228  : TimeStamp(TimeUnit(TimeUnit::BEATS, ppqn), ticks, subticks)
229  {}
230 };
231 
232 
235 typedef TimeStamp TimeDuration;
236 
237 
238 } // namespace Raul
239 
240 #endif // RAUL_TIME_STAMP_HPP
A type of time stamp.
Definition: TimeStamp.hpp:33
Definition: Array.hpp:26
A real-time time stamp (possible units: frame, absolute (s), or beat).
Definition: TimeStamp.hpp:80
TimeUnit(Type type, uint32_t ppt)
ppt (parts per tick) is the sample rate for FRAMES, PPQN for BEATS, and ignored for SECONDS...
Definition: TimeStamp.hpp:44