summaryrefslogtreecommitdiffstats
path: root/raul/TimeSlice.h
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-02-21 02:30:09 +0000
committerDavid Robillard <d@drobilla.net>2007-02-21 02:30:09 +0000
commit2cef260f92785971d7d61489c2278ad7afae0dd7 (patch)
tree308369a7102750714685d4e2d2351ec94e53898c /raul/TimeSlice.h
parent58fa57acec95fc590fb2b53c512a5c300e6049a6 (diff)
downloadraul-2cef260f92785971d7d61489c2278ad7afae0dd7.tar.gz
raul-2cef260f92785971d7d61489c2278ad7afae0dd7.tar.bz2
raul-2cef260f92785971d7d61489c2278ad7afae0dd7.zip
Tempo based time in Machina (and related utilities added to Raul).
git-svn-id: http://svn.drobilla.net/lad/raul@324 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'raul/TimeSlice.h')
-rw-r--r--raul/TimeSlice.h160
1 files changed, 160 insertions, 0 deletions
diff --git a/raul/TimeSlice.h b/raul/TimeSlice.h
new file mode 100644
index 0000000..289233c
--- /dev/null
+++ b/raul/TimeSlice.h
@@ -0,0 +1,160 @@
+/* This file is part of Raul.
+ * Copyright (C) 2007 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_TIMESLICE_H
+#define RAUL_TIMESLICE_H
+
+#include <cassert>
+#include <boost/utility.hpp>
+
+namespace Raul {
+
+
+typedef uint32_t TickTime; ///< absolute time in ticks
+typedef uint32_t TickCount; ///< offset in ticks
+typedef double BeatTime;
+typedef double BeatCount;
+typedef double Seconds;
+
+
+/** A duration of time, with conversion between tick time and beat time.
+ *
+ * This is a slice along a single timeline (ie t=0 in ticks and t=0 in beats
+ * are equal). Relation to an external time base (e.g. Jack frame time) is
+ * represented by frame_offset (the idea is that this holds all the information
+ * necessary for passing to run() methods so they know the current state of
+ * things WRT time).
+ *
+ * This class handles conversion between two units of time: musical
+ * (beat) time, and real (tick) time. Real time is discrete, the smallest
+ * unit of time is the 'tick' (usually audio frames or MIDI ticks). Beat time
+ * is stored as a double (to be independent of any rates or timer precision).
+ *
+ * This caches as many values as possible to make calls less expensive, pass it
+ * around by reference, not value.
+ *
+ * \ingroup raul
+ */
+class TimeSlice : public boost::noncopyable {
+public:
+ TimeSlice(double tick_rate, double bpm)
+ : _tick_rate(tick_rate)
+ , _beat_rate(60.0/bpm)
+ , _start_ticks(0)
+ , _length_ticks(0)
+ , _start_beats(0)
+ , _length_beats(0)
+ , _offset_ticks(0)
+ {}
+
+
+ /** Set the start and length of the slice.
+ *
+ * Note that external offset is not affected by this, don't forget to reset
+ * the offset each cycle!
+ */
+ void set_window(TickTime start, TickCount length) {
+ _start_ticks = start;
+ _length_ticks = length;
+ update_beat_time();
+ }
+
+ void set_start(TickTime time) { _start_ticks = time; update_beat_time(); }
+
+ void set_length(TickCount length) { _length_ticks = length; update_beat_time(); }
+
+ bool contains(TickTime time) {
+ return (time >= start_ticks() && time < start_ticks() + length_ticks());
+ }
+
+ void set_tick_rate(double tick_rate) {
+ _tick_rate = tick_rate;
+ update_beat_time();
+ }
+
+ void set_bpm(double bpm) {
+ _beat_rate = 60.0/bpm;
+ update_beat_time();
+ }
+
+ inline Seconds beats_to_seconds(BeatTime beats) const {
+ return (beats * _beat_rate);
+ }
+
+ inline TickTime beats_to_ticks(BeatTime beats) const {
+ return static_cast<TickTime>(beats_to_seconds(beats) / _tick_rate);
+ }
+
+ inline Seconds ticks_to_seconds(TickTime ticks) const {
+ return (ticks * _tick_rate);
+ }
+
+ inline BeatTime ticks_to_beats(TickTime ticks) const {
+ return ticks_to_seconds(ticks) / _beat_rate;
+ }
+
+ /** Start of current sub-cycle in ticks */
+ inline TickTime start_ticks() const { return _start_ticks; }
+
+ /** Length of current sub-cycle in ticks */
+ inline TickCount length_ticks() const { return _length_ticks; }
+
+ /** Start of current sub-cycle in beats */
+ inline BeatTime start_beats() const { return _start_beats; }
+
+ /** Length of current sub-cycle in beats */
+ inline BeatCount length_beats() const { return _length_beats; }
+
+
+ // Real-time conversion
+/*
+ TickCount ticks_to_offset(TickTime time) {
+ assert(time >= _start_ticks);
+ TickCount ret = time - _start_ticks + _offset_ticks;
+ assert(ret < _offset_ticks + _length_ticks);
+ return ret;
+ }
+*/
+ /** Set the offset between real-time and timeslice-time. */
+ inline void set_offset(TickCount offset) { _offset_ticks = offset; }
+ /** Offset relative to external (e.g Jack) time */
+ inline TickCount offset_ticks() const { return _offset_ticks; }
+
+private:
+
+ inline void update_beat_time() {
+ _start_beats = ticks_to_beats(_start_ticks);
+ _length_beats = ticks_to_beats(_length_ticks);
+ }
+
+ // Rate/Tempo
+ double _tick_rate; ///< Tick rate in Hz (e.g. sample rate)
+ double _beat_rate; ///< Beat rate in Hz
+
+ // Current time
+ TickTime _start_ticks; ///< Current window start in ticks
+ TickCount _length_ticks; ///< Current window length in ticks
+ BeatTime _start_beats; ///< Current window start in beats
+ BeatCount _length_beats; ///< Current window length in beats
+
+ TickCount _offset_ticks; ///< Offset to global time (ie Jack sub-cycle offset)
+};
+
+
+} // namespace Raul
+
+#endif // RAUL_TIMESLICE_H