• Main Page
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

TimeStamp.hpp

00001 /* This file is part of Raul.
00002  * Copyright (C) 2008-2009 David Robillard <http://drobilla.net>
00003  *
00004  * Raul is free software; you can redistribute it and/or modify it under the
00005  * terms of the GNU General Public License as published by the Free Software
00006  * Foundation; either version 2 of the License, or (at your option) any later
00007  * version.
00008  *
00009  * Raul is distributed in the hope that it will be useful, but WITHOUT ANY
00010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for details.
00012  *
00013  * You should have received a copy of the GNU General Public License along
00014  * with this program; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00016  */
00017 
00018 #ifndef RAUL_TIME_STAMP_HPP
00019 #define RAUL_TIME_STAMP_HPP
00020 
00021 #include <limits>
00022 #include <stdint.h>
00023 #include <math.h>
00024 #include <cassert>
00025 #include <iostream>
00026 
00027 namespace Raul {
00028 
00029 
00033 class TimeUnit {
00034 public:
00035     enum Type {
00036         FRAMES,
00037         BEATS,
00038         SECONDS
00039     };
00040 
00044     inline TimeUnit(Type type, uint32_t ppt) {
00045         assert(type == SECONDS || ppt != 0);
00046         _type = type;
00047         _ppt = ppt;
00048     }
00049 
00050     static inline TimeUnit frames(uint32_t srate) { return TimeUnit(FRAMES, srate); }
00051     static inline TimeUnit beats(uint32_t ppqn)   { return TimeUnit(BEATS, ppqn); }
00052     static inline TimeUnit seconds()              { return TimeUnit(BEATS, std::numeric_limits<uint32_t>::max()); }
00053 
00054     inline Type     type() const { return _type; }
00055     inline uint32_t ppt()  const { return _ppt; }
00056 
00057     inline bool operator==(const TimeUnit& rhs) const {
00058         return (_type == rhs._type && _ppt == rhs._ppt);
00059     }
00060 
00061     inline bool operator!=(const TimeUnit& rhs) const {
00062         return (_type != rhs._type || _ppt != rhs._ppt);
00063     }
00064 
00065 private:
00066     Type     _type;
00067     uint32_t _ppt;
00068 };
00069 
00070 
00080 class TimeStamp {
00081 public:
00082     inline TimeStamp(TimeUnit unit, uint32_t ticks=0, uint32_t subticks=0)
00083         : _ticks(ticks)
00084         , _subticks(subticks)
00085         , _unit(unit)
00086     {}
00087 
00088     inline TimeStamp(TimeUnit unit, double dec)
00089         : _ticks(static_cast<uint32_t>(floor(dec)))
00090         , _subticks((dec - floor(dec)) * unit.ppt())
00091         , _unit(unit)
00092     {
00093         assert(dec >= 0);
00094         assert(dec <= std::numeric_limits<uint32_t>::max());
00095     }
00096 
00097     inline TimeUnit unit()     const { return _unit; }
00098     inline uint32_t ticks()    const { return _ticks; }
00099     inline uint32_t subticks() const { return _subticks; }
00100 
00101     inline double to_double() const {
00102         return _ticks + (_subticks / static_cast<double>(_unit.ppt()));
00103     }
00104 
00105     inline bool is_zero() const {
00106         return _ticks == 0 && _subticks == 0;
00107     }
00108 
00109     inline TimeStamp& operator=(const TimeStamp& rhs) {
00110         _ticks = rhs._ticks;
00111         _subticks = rhs._subticks;
00112         _unit = rhs._unit;
00113         return *this;
00114     }
00115 
00116     inline TimeStamp& operator=(uint32_t ticks) {
00117         _ticks = ticks;
00118         _subticks = 0;
00119         return *this;
00120     }
00121 
00122     inline bool operator==(const TimeStamp& rhs) const {
00123         return _ticks == rhs._ticks
00124             && _subticks == rhs._subticks
00125             && _unit == rhs._unit;
00126     }
00127 
00128     inline bool operator!=(const TimeStamp& rhs) const {
00129         return ! operator==(rhs);
00130     }
00131 
00132     inline bool operator<(const TimeStamp& rhs) const {
00133         assert(_unit == rhs._unit);
00134         return (_ticks < rhs._ticks
00135                 || (_ticks == rhs._ticks && _subticks < rhs._subticks));
00136     }
00137 
00138     inline bool operator>(const TimeStamp& rhs) const {
00139         assert(_unit == rhs._unit);
00140         return (_ticks > rhs._ticks
00141                 || (_ticks == rhs._ticks && _subticks > rhs._subticks));
00142     }
00143 
00144     inline bool operator<=(const TimeStamp& rhs) const {
00145         return (*this == rhs) || ((*this) < rhs);
00146     }
00147 
00148     inline bool operator>=(const TimeStamp& rhs) const {
00149         return (*this == rhs) || ((*this) > rhs);
00150     }
00151 
00152     inline TimeStamp& operator+=(const TimeStamp& rhs) {
00153         assert(_unit == rhs._unit);
00154         _ticks += rhs._ticks;
00155         if (_subticks + rhs._subticks <= _unit.ppt()) {
00156             _subticks += rhs._subticks;
00157         } else if (rhs._subticks > 0) {
00158             ++_ticks;
00159             _subticks = rhs._subticks + _subticks - _unit.ppt();
00160         }
00161         return *this;
00162     }
00163 
00164     inline TimeStamp& operator-=(const TimeStamp& rhs) {
00165         assert(_unit == rhs._unit);
00166         assert(rhs <= *this);
00167         _ticks -= rhs._ticks;
00168         if (_subticks >= rhs._subticks) {
00169             _subticks -= rhs._subticks;
00170         } else if (rhs._subticks > 0) {
00171             --_ticks;
00172             _subticks = _unit.ppt() - (rhs._subticks - _subticks);
00173         }
00174         return *this;
00175     }
00176 
00177     inline TimeStamp operator+(const TimeStamp& rhs) const {
00178         assert(_unit == rhs._unit);
00179         TimeStamp result = *this;
00180         result += rhs;
00181         return result;
00182     }
00183 
00184     inline TimeStamp operator-(const TimeStamp& rhs) const {
00185         assert(_unit == rhs._unit);
00186         TimeStamp result = *this;
00187         result -= rhs;
00188         return result;
00189     }
00190 
00191 private:
00192     uint32_t _ticks;
00193     uint32_t _subticks;
00194     TimeUnit _unit;
00195 };
00196 
00197 
00198 static inline std::ostream&
00199 operator<<(std::ostream& os, const TimeStamp& t)
00200 {
00201     os << t.ticks() << ":" << t.subticks();
00202     switch (t.unit().type()) {
00203     case TimeUnit::FRAMES:
00204         os << " frames";
00205         break;
00206     case TimeUnit::BEATS:
00207         os << " beats";
00208         break;
00209     case TimeUnit::SECONDS:
00210         os << " seconds";
00211         break;
00212     }
00213     return os;
00214 }
00215 
00216 
00217 class FrameStamp : public TimeStamp {
00218 public:
00219     inline FrameStamp(uint32_t rate, uint32_t ticks=0, uint32_t subticks=0)
00220         : TimeStamp(TimeUnit(TimeUnit::FRAMES, rate), ticks, subticks)
00221     {}
00222 };
00223 
00224 
00225 class BeatStamp : public TimeStamp {
00226 public:
00227     inline BeatStamp(uint32_t ppqn, uint32_t ticks=0, uint32_t subticks=0)
00228         : TimeStamp(TimeUnit(TimeUnit::BEATS, ppqn), ticks, subticks)
00229     {}
00230 };
00231 
00232 
00235 typedef TimeStamp TimeDuration;
00236 
00237 
00238 } // namespace Raul
00239 
00240 #endif // RAUL_TIME_STAMP_HPP

Generated on Tue Jan 11 2011 18:26:17 for RAUL by  doxygen 1.7.1