summaryrefslogtreecommitdiffstats
path: root/raul/TimeStamp.hpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2008-02-09 18:23:57 +0000
committerDavid Robillard <d@drobilla.net>2008-02-09 18:23:57 +0000
commit81f335330c209359ef1d2b3bdedc5c19790d2eba (patch)
tree2262742e60b1360ecd66bf1f5be57e4df2b53de3 /raul/TimeStamp.hpp
parent43dd122ffcdb6a0b40a56777245a870e411d439c (diff)
downloadraul-81f335330c209359ef1d2b3bdedc5c19790d2eba.tar.gz
raul-81f335330c209359ef1d2b3bdedc5c19790d2eba.tar.bz2
raul-81f335330c209359ef1d2b3bdedc5c19790d2eba.zip
Use Raul::TimeStamp (LV2 compatible typed 32:32 fixed timestamp) everywhere.
Fix initial size of Patchage messages window. Machina disabled for now (transitioning to generic timestamps). git-svn-id: http://svn.drobilla.net/lad/raul@1133 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'raul/TimeStamp.hpp')
-rw-r--r--raul/TimeStamp.hpp240
1 files changed, 240 insertions, 0 deletions
diff --git a/raul/TimeStamp.hpp b/raul/TimeStamp.hpp
new file mode 100644
index 0000000..6cbf807
--- /dev/null
+++ b/raul/TimeStamp.hpp
@@ -0,0 +1,240 @@
+/* This file is part of Raul.
+ * Copyright (C) 2008 Dave Robillard <http://drobilla.net>
+ *
+ * Raul is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Raul is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef RAUL_TIME_STAMP_HPP
+#define RAUL_TIME_STAMP_HPP
+
+#include <limits>
+#include <stdint.h>
+#include <math.h>
+#include <cassert>
+#include <iostream>
+
+namespace Raul {
+
+
+/** A type of time stamp
+ */
+class TimeUnit {
+public:
+ enum Type {
+ FRAMES,
+ BEATS,
+ SECONDS
+ };
+
+ /** @a ppt (parts per tick) is the sample rate for FRAMES,
+ * PPQN for BEATS, and ignored for SECONDS.
+ */
+ inline TimeUnit(Type type, uint32_t ppt) {
+ _type = type;
+ _ppt = ppt;
+ }
+
+ static inline TimeUnit frames(uint32_t srate) { return TimeUnit(FRAMES, srate); }
+ static inline TimeUnit beats(uint32_t ppqn) { return TimeUnit(BEATS, ppqn); }
+ static inline TimeUnit seconds() { return TimeUnit(BEATS, std::numeric_limits<uint32_t>::max()); }
+
+ inline Type type() const { return _type; }
+ inline uint32_t ppt() const { return _ppt; }
+
+ inline bool operator==(const TimeUnit& rhs) const {
+ return (_type == rhs._type && _ppt == rhs._ppt);
+ }
+
+ inline bool operator!=(const TimeUnit& rhs) const {
+ return (_type != rhs._type || _ppt != rhs._ppt);
+ }
+
+private:
+ Type _type;
+ uint32_t _ppt;
+};
+
+
+/** A real-time time stamp (possible units: frame, absolute (s), or beat).
+ *
+ * This is a uint32_t:uint32_t fixed point representation, capable of
+ * sub-sample accurate frame time, beat time (at any remotely sane
+ * tempo and sample rate), and absolute time. The absolute time (seconds)
+ * is compatible with standard OSC/NTP time stamps.
+ *
+ * \ingroup raul
+ */
+class TimeStamp {
+public:
+
+ inline TimeStamp(TimeUnit unit, uint32_t ticks=0, uint32_t subticks=0)
+ : _ticks(ticks)
+ , _subticks(subticks)
+ , _unit(unit)
+ {}
+
+ inline TimeStamp(TimeUnit unit, double dec)
+ : _ticks((uint32_t)floor(dec))
+ , _subticks((dec - floor(dec)) * unit.ppt())
+ , _unit(unit)
+ {
+ assert(dec >= 0);
+ assert(dec <= std::numeric_limits<uint32_t>::max());
+ }
+
+ inline TimeUnit unit() const { return _unit; }
+ inline uint32_t ticks() const { return _ticks; }
+ inline uint32_t subticks() const { return _subticks; }
+
+ inline double to_double() const {
+ return _ticks + (_subticks / (double)_unit.ppt());
+ }
+
+ inline bool is_zero() const {
+ return _ticks == 0 && _subticks == 0;
+ }
+
+ inline TimeStamp& operator=(const TimeStamp& rhs) {
+ assert(_unit == rhs._unit);
+ _ticks = rhs._ticks;
+ _subticks = rhs._subticks;
+ //_unit = rhs._unit;
+ return *this;
+ }
+
+ inline TimeStamp& operator=(uint32_t ticks) {
+ _ticks = ticks;
+ _subticks = 0;
+ return *this;
+ }
+
+ inline bool operator==(const TimeStamp& rhs) const {
+ return _ticks == rhs._ticks
+ && _subticks == rhs._subticks
+ && _unit == rhs._unit;
+ }
+
+ inline bool operator!=(const TimeStamp& rhs) const {
+ return ! operator==(rhs);
+ }
+
+ inline bool operator<(const TimeStamp& rhs) const {
+ assert(_unit == rhs._unit);
+ return (_ticks < rhs._ticks
+ || (_ticks == rhs._ticks && _subticks < rhs._subticks));
+ }
+
+ inline bool operator<=(const TimeStamp& rhs) const {
+ assert(_unit == rhs._unit);
+ return (_ticks <= rhs._ticks
+ || (_ticks == rhs._ticks && _subticks <= rhs._subticks));
+ }
+
+ inline bool operator>=(const TimeStamp& rhs) const {
+ return ! (rhs < *this);
+ }
+
+ inline bool operator>(const TimeStamp& rhs) const {
+ return ! (rhs <= *this);
+ }
+
+ inline TimeStamp& operator+=(const TimeStamp& rhs) {
+ assert(_unit == rhs._unit);
+ _ticks += rhs._ticks;
+ if (_subticks + rhs._subticks <= _unit.ppt()) {
+ _subticks += rhs._subticks;
+ } else if (rhs._subticks > 0) {
+ ++_ticks;
+ _subticks = rhs._subticks + _subticks - _unit.ppt();
+ }
+ return *this;
+ }
+
+ inline TimeStamp& operator-=(const TimeStamp& rhs) {
+ assert(_unit == rhs._unit);
+ assert(rhs <= *this);
+ _ticks -= rhs._ticks;
+ if (_subticks >= rhs._subticks) {
+ _subticks -= rhs._subticks;
+ } else if (rhs._subticks > 0) {
+ --_ticks;
+ _subticks = _unit.ppt() - (rhs._subticks - _subticks);
+ }
+ return *this;
+ }
+
+ inline TimeStamp operator+(const TimeStamp& rhs) const {
+ assert(_unit == rhs._unit);
+ TimeStamp result = *this;
+ result += rhs;
+ return result;
+ }
+
+ inline TimeStamp operator-(const TimeStamp& rhs) const {
+ assert(_unit == rhs._unit);
+ TimeStamp result = *this;
+ result -= rhs;
+ return result;
+ }
+
+private:
+ uint32_t _ticks;
+ uint32_t _subticks;
+ TimeUnit _unit;
+};
+
+
+static inline std::ostream&
+operator<<(std::ostream& os, const TimeStamp& t)
+{
+ os << t.ticks() << ":" << t.subticks();
+ switch (t.unit().type()) {
+ case TimeUnit::FRAMES:
+ os << " frames";
+ break;
+ case TimeUnit::BEATS:
+ os << " beats";
+ break;
+ case TimeUnit::SECONDS:
+ os << " seconds";
+ break;
+ }
+ return os;
+}
+
+
+class FrameStamp : public TimeStamp {
+public:
+ inline FrameStamp(uint32_t rate, uint32_t ticks=0, uint32_t subticks=0)
+ : TimeStamp(TimeUnit(TimeUnit::FRAMES, rate), ticks, subticks)
+ {}
+};
+
+
+class BeatStamp : public TimeStamp {
+public:
+ inline BeatStamp(uint32_t ppqn, uint32_t ticks=0, uint32_t subticks=0)
+ : TimeStamp(TimeUnit(TimeUnit::BEATS, ppqn), ticks, subticks)
+ {}
+};
+
+
+/** Same thing as TimeStamp really, but makes code clearer and enforces
+ * correct semantics via type safety */
+typedef TimeStamp TimeDuration;
+
+
+} // namespace Raul
+
+#endif // RAUL_TIME_STAMP_HPP