00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef RAUL_TIME_SLICE_HPP
00019 #define RAUL_TIME_SLICE_HPP
00020
00021 #include <cassert>
00022 #include <cmath>
00023
00024 #include <boost/utility.hpp>
00025
00026 #include "raul/TimeStamp.hpp"
00027
00028 namespace Raul {
00029
00030
00031
00032
00051 class TimeSlice : public boost::noncopyable {
00052 public:
00053 TimeSlice(uint32_t rate, uint32_t ppqn, double bpm)
00054 : _tick_rate(rate)
00055 , _beat_rate(60.0/bpm)
00056 , _start_ticks(Raul::TimeUnit(Raul::TimeUnit::FRAMES, rate), 0, 0)
00057 , _length_ticks(TimeUnit(TimeUnit::FRAMES, rate), 0, 0)
00058 , _start_beats(TimeUnit(TimeUnit::BEATS, ppqn), 0, 0)
00059 , _length_beats(TimeUnit(TimeUnit::BEATS, ppqn), 0, 0)
00060 , _offset_ticks(TimeUnit(TimeUnit::FRAMES, rate), 0, 0)
00061 {}
00062
00068 void set_slice(TimeStamp start, TimeDuration length) {
00069 assert(start.unit() == ticks_unit());
00070 assert(length.unit() == ticks_unit());
00071 _start_ticks = start;
00072 _length_ticks = length;
00073 update_beat_time();
00074 }
00075
00076 void set_length(TimeDuration length) {
00077 assert(length.unit() == ticks_unit());
00078 _length_ticks = length;
00079 _length_beats = ticks_to_beats(_length_ticks);
00080 }
00081
00082 bool contains(TimeStamp time) const {
00083 return (time >= start_ticks() && time < start_ticks() + length_ticks());
00084 }
00085
00086 double tick_rate() const { return _tick_rate; }
00087 double beat_rate() const { return _beat_rate; }
00088 double bpm() const { return 60/_beat_rate; }
00089
00090 void set_tick_rate(double tick_rate) {
00091 _tick_rate = tick_rate;
00092 update_beat_time();
00093 }
00094
00095 void set_bpm(double bpm) {
00096 _beat_rate = 60.0/bpm;
00097 update_beat_time();
00098 }
00099
00100 inline TimeStamp beats_to_seconds(TimeStamp beats) const {
00101 return TimeStamp(real_unit(), beats.to_double() * 1/(double)_beat_rate);
00102 }
00103
00104 inline TimeStamp beats_to_ticks(TimeStamp beats) const {
00105 return TimeStamp(ticks_unit(), beats.to_double() * (double)_beat_rate * _tick_rate);
00106 }
00107
00108 inline TimeStamp ticks_to_seconds(TimeStamp ticks) const {
00109 return TimeStamp(real_unit(), ticks.ticks() * 1/(double)_tick_rate);
00110 }
00111
00112 inline TimeStamp ticks_to_beats(TimeStamp ticks) const {
00113 return TimeStamp(beats_unit(), ticks.ticks() * 1/(double)_tick_rate * _beat_rate);
00114 }
00115
00117 inline TimeStamp start_ticks() const { return _start_ticks; }
00118
00120 inline TimeDuration length_ticks() const { return _length_ticks; }
00121
00123 inline TimeStamp start_beats() const { return _start_beats; }
00124
00126 inline TimeDuration length_beats() const { return _length_beats; }
00127
00129 inline void set_offset(TimeDuration offset) { _offset_ticks = offset; }
00130
00132 inline TimeDuration offset_ticks() const { return _offset_ticks; }
00133
00134 inline TimeUnit beats_unit() const { return _start_beats.unit(); }
00135 inline TimeUnit ticks_unit() const { return _start_ticks.unit(); }
00136 inline TimeUnit real_unit() const { return TimeUnit(TimeUnit::SECONDS, 0); }
00137
00138 private:
00139 inline void update_beat_time() {
00140 _start_beats = ticks_to_beats(_start_ticks);
00141 _length_beats = ticks_to_beats(_length_ticks);
00142 }
00143
00144
00145 double _tick_rate;
00146 double _beat_rate;
00147
00148
00149 TimeStamp _start_ticks;
00150 TimeDuration _length_ticks;
00151 TimeStamp _start_beats;
00152 TimeDuration _length_beats;
00153
00154 TimeDuration _offset_ticks;
00155 };
00156
00157
00158 }
00159
00160 #endif // RAUL_TIME_SLICE_HPP