RAUL 0.8.0

- 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