summaryrefslogtreecommitdiff
path: root/libs/temporal/temporal
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2017-09-24 10:47:28 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2017-09-24 10:47:28 -0400
commitb62c305f200351b2cbae70de8327fa235ff515dc (patch)
tree10d724d8e6db552fbc66863a0500e0de4ee1ffef /libs/temporal/temporal
parent8890494ba31b007b1b138f5e7ebdb35f192a0cfd (diff)
change libtimecode to libtemporal, add Evoral::Beats, positional types and superclock headers
Diffstat (limited to 'libs/temporal/temporal')
-rw-r--r--libs/temporal/temporal/bbt_time.h142
-rw-r--r--libs/temporal/temporal/beats.h326
-rw-r--r--libs/temporal/temporal/superclock.h36
-rw-r--r--libs/temporal/temporal/time.h148
-rw-r--r--libs/temporal/temporal/types.h46
-rw-r--r--libs/temporal/temporal/visibility.h40
6 files changed, 738 insertions, 0 deletions
diff --git a/libs/temporal/temporal/bbt_time.h b/libs/temporal/temporal/bbt_time.h
new file mode 100644
index 0000000000..b42ccf741e
--- /dev/null
+++ b/libs/temporal/temporal/bbt_time.h
@@ -0,0 +1,142 @@
+/*
+ Copyright (C) 2002-2010 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This program 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __timecode_bbt_time_h__
+#define __timecode_bbt_time_h__
+
+#include <ostream>
+#include <stdint.h>
+#include <iomanip>
+#include <exception>
+
+#include "timecode/visibility.h"
+
+namespace Timecode {
+
+/** Bar, Beat, Tick Time (i.e. Tempo-Based Time) */
+struct LIBTIMECODE_API BBT_Time
+{
+ static const double ticks_per_beat;
+
+ /* note that it is illegal for BBT_Time to have bars==0 or
+ * beats==0. The "neutral" or "default" value is 1|1|0
+ */
+
+ int32_t bars;
+ int32_t beats;
+ int32_t ticks;
+
+ struct IllegalBBTTimeException : public std::exception {
+ virtual const char* what() const throw() { return "illegal BBT time (bars or beats were zero)"; }
+ };
+
+ BBT_Time () : bars (1), beats (1), ticks (0) {}
+ BBT_Time (int32_t ba, uint32_t be, uint32_t t) : bars (ba), beats (be), ticks (t) { if (!bars || !beats) { throw IllegalBBTTimeException(); } }
+
+ bool operator< (const BBT_Time& other) const {
+ return bars < other.bars ||
+ (bars == other.bars && beats < other.beats) ||
+ (bars == other.bars && beats == other.beats && ticks < other.ticks);
+ }
+
+ bool operator<= (const BBT_Time& other) const {
+ return bars < other.bars ||
+ (bars <= other.bars && beats <= other.beats) ||
+ (bars <= other.bars && beats <= other.beats && ticks <= other.ticks);
+ }
+
+ bool operator> (const BBT_Time& other) const {
+ return bars > other.bars ||
+ (bars == other.bars && beats > other.beats) ||
+ (bars == other.bars && beats == other.beats && ticks > other.ticks);
+ }
+
+ bool operator>= (const BBT_Time& other) const {
+ return bars > other.bars ||
+ (bars >= other.bars && beats >= other.beats) ||
+ (bars >= other.bars && beats >= other.beats && ticks >= other.ticks);
+ }
+
+ bool operator== (const BBT_Time& other) const {
+ return bars == other.bars && beats == other.beats && ticks == other.ticks;
+ }
+
+ bool operator!= (const BBT_Time& other) const {
+ return bars != other.bars || beats != other.beats || ticks != other.ticks;
+ }
+
+ /* it would be nice to provide operator+(BBT_Time const&) and
+ * operator-(BBT_Time const&) but this math requires knowledge of the
+ * meter (time signature) used to define 1 bar, and so cannot be
+ * carried out with only two BBT_Time values.
+ */
+
+ BBT_Time round_to_beat () const { return ticks >= (ticks_per_beat/2) ? BBT_Time (bars, beats+1, 0) : BBT_Time (bars, beats, 0); }
+ BBT_Time round_down_to_beat () const { return BBT_Time (bars, beats, 0); }
+ BBT_Time round_up_to_beat () const { return ticks ? BBT_Time (bars, beats+1, 0) : *this; }
+
+ /* cannot implement round_to_bar() without knowing meter (time
+ * signature) information.
+ */
+};
+
+struct LIBTIMECODE_API BBT_Offset
+{
+ int32_t bars;
+ int32_t beats;
+ int32_t ticks;
+
+ /* this is a variant for which bars==0 and/or beats==0 is legal. It
+ * represents an offset from a given BBT_Time and is used when doing
+ * add/subtract operations on a BBT_Time.
+ */
+
+ BBT_Offset () : bars (0), beats (0), ticks (0) {}
+ BBT_Offset (int32_t ba, uint32_t be, uint32_t t) : bars (ba), beats (be), ticks (t) {}
+ BBT_Offset (BBT_Time const & bbt) : bars (bbt.bars), beats (bbt.beats), ticks (bbt.ticks) {}
+ BBT_Offset (double beats);
+};
+
+}
+
+inline std::ostream&
+operator<< (std::ostream& o, const Timecode::BBT_Time& bbt)
+{
+ o << bbt.bars << '|' << bbt.beats << '|' << bbt.ticks;
+ return o;
+}
+
+inline std::ostream&
+operator<< (std::ostream& o, const Timecode::BBT_Offset& bbt)
+{
+ o << bbt.bars << '|' << bbt.beats << '|' << bbt.ticks;
+ return o;
+}
+
+inline std::ostream&
+print_padded (std::ostream& o, const Timecode::BBT_Time& bbt)
+{
+ o << std::setfill ('0') << std::right
+ << std::setw (3) << bbt.bars << "|"
+ << std::setw (2) << bbt.beats << "|"
+ << std::setw (4) << bbt.ticks;
+
+ return o;
+}
+
+#endif /* __timecode_bbt_time_h__ */
diff --git a/libs/temporal/temporal/beats.h b/libs/temporal/temporal/beats.h
new file mode 100644
index 0000000000..c85959260a
--- /dev/null
+++ b/libs/temporal/temporal/beats.h
@@ -0,0 +1,326 @@
+/* This file is part of Evoral.
+ * Copyright (C) 2008-2015 David Robillard <http://drobilla.net>
+ * Copyright (C) 2000-2008 Paul Davis
+ *
+ * Evoral 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.
+ *
+ * Evoral 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 EVORAL_BEATS_HPP
+#define EVORAL_BEATS_HPP
+
+#include <float.h>
+#include <math.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <iostream>
+#include <limits>
+
+#include "evoral/visibility.h"
+
+namespace Evoral {
+
+/** Musical time in beats. */
+class /*LIBEVORAL_API*/ Beats {
+public:
+ LIBEVORAL_API static const int32_t PPQN = 1920;
+
+ Beats() : _beats(0), _ticks(0) {}
+
+ /** Normalize so ticks is within PPQN. */
+ void normalize() {
+ // First, fix negative ticks with positive beats
+ if (_beats >= 0) {
+ while (_ticks < 0) {
+ --_beats;
+ _ticks += PPQN;
+ }
+ }
+
+ // Work with positive beats and ticks to normalize
+ const int32_t sign = _beats < 0 ? -1 : 1;
+ int32_t beats = abs(_beats);
+ int32_t ticks = abs(_ticks);
+
+ // Fix ticks greater than 1 beat
+ while (ticks >= PPQN) {
+ ++beats;
+ ticks -= PPQN;
+ }
+
+ // Set fields with appropriate sign
+ _beats = sign * beats;
+ _ticks = sign * ticks;
+ }
+
+ /** Create from a precise BT time. */
+ explicit Beats(int32_t b, int32_t t) : _beats(b), _ticks(t) {
+ normalize();
+ }
+
+ /** Create from a real number of beats. */
+ explicit Beats(double time) {
+ double whole;
+ const double frac = modf(time, &whole);
+
+ _beats = whole;
+ _ticks = frac * PPQN;
+ }
+
+ /** Create from an integer number of beats. */
+ static Beats beats(int32_t beats) {
+ return Beats(beats, 0);
+ }
+
+ /** Create from ticks at the standard PPQN. */
+ static Beats ticks(int32_t ticks) {
+ return Beats(0, ticks);
+ }
+
+ /** Create from ticks at a given rate.
+ *
+ * Note this can also be used to create from frames by setting ppqn to the
+ * number of samples per beat. Note the resulting Beats will, like all
+ * others, have the default PPQN, so this is a potentially lossy
+ * conversion.
+ */
+ static Beats ticks_at_rate(int64_t ticks, uint32_t ppqn) {
+ return Beats(ticks / ppqn, (ticks % ppqn) * PPQN / ppqn);
+ }
+
+ Beats& operator=(double time) {
+ double whole;
+ const double frac = modf(time, &whole);
+
+ _beats = whole;
+ _ticks = frac * PPQN;
+ return *this;
+ }
+
+ Beats& operator=(const Beats& other) {
+ _beats = other._beats;
+ _ticks = other._ticks;
+ return *this;
+ }
+
+ Beats round_to_beat() const {
+ return (_ticks >= (PPQN/2)) ? Beats (_beats + 1, 0) : Beats (_beats, 0);
+ }
+
+ Beats round_up_to_beat() const {
+ return (_ticks == 0) ? *this : Beats(_beats + 1, 0);
+ }
+
+ Beats round_down_to_beat() const {
+ return Beats(_beats, 0);
+ }
+
+ Beats snap_to(const Evoral::Beats& snap) const {
+ const double snap_time = snap.to_double();
+ return Beats(ceil(to_double() / snap_time) * snap_time);
+ }
+
+ inline bool operator==(const Beats& b) const {
+ return _beats == b._beats && _ticks == b._ticks;
+ }
+
+ inline bool operator==(double t) const {
+ /* Acceptable tolerance is 1 tick. */
+ return fabs(to_double() - t) <= (1.0 / PPQN);
+ }
+
+ inline bool operator==(int beats) const {
+ return _beats == beats;
+ }
+
+ inline bool operator!=(const Beats& b) const {
+ return !operator==(b);
+ }
+
+ inline bool operator<(const Beats& b) const {
+ return _beats < b._beats || (_beats == b._beats && _ticks < b._ticks);
+ }
+
+ inline bool operator<=(const Beats& b) const {
+ return _beats < b._beats || (_beats == b._beats && _ticks <= b._ticks);
+ }
+
+ inline bool operator>(const Beats& b) const {
+ return _beats > b._beats || (_beats == b._beats && _ticks > b._ticks);
+ }
+
+ inline bool operator>=(const Beats& b) const {
+ return _beats > b._beats || (_beats == b._beats && _ticks >= b._ticks);
+ }
+
+ inline bool operator<(double b) const {
+ /* Acceptable tolerance is 1 tick. */
+ const double time = to_double();
+ if (fabs(time - b) <= (1.0 / PPQN)) {
+ return false; /* Effectively identical. */
+ } else {
+ return time < b;
+ }
+ }
+
+ inline bool operator<=(double b) const {
+ return operator==(b) || operator<(b);
+ }
+
+ inline bool operator>(double b) const {
+ /* Acceptable tolerance is 1 tick. */
+ const double time = to_double();
+ if (fabs(time - b) <= (1.0 / PPQN)) {
+ return false; /* Effectively identical. */
+ } else {
+ return time > b;
+ }
+ }
+
+ inline bool operator>=(double b) const {
+ return operator==(b) || operator>(b);
+ }
+
+ Beats operator+(const Beats& b) const {
+ return Beats(_beats + b._beats, _ticks + b._ticks);
+ }
+
+ Beats operator-(const Beats& b) const {
+ return Beats(_beats - b._beats, _ticks - b._ticks);
+ }
+
+ Beats operator+(double d) const {
+ return Beats(to_double() + d);
+ }
+
+ Beats operator-(double d) const {
+ return Beats(to_double() - d);
+ }
+
+ Beats operator+(int b) const {
+ return Beats (_beats + b, _ticks);
+ }
+
+ Beats operator-(int b) const {
+ return Beats (_beats - b, _ticks);
+ }
+
+ Beats& operator+=(int b) {
+ _beats += b;
+ return *this;
+ }
+
+ Beats& operator-=(int b) {
+ _beats -= b;
+ return *this;
+ }
+
+ Beats operator-() const {
+ return Beats(-_beats, -_ticks);
+ }
+
+ template<typename Number>
+ Beats operator*(Number factor) const {
+ return Beats(_beats * factor, _ticks * factor);
+ }
+
+ template<typename Number>
+ Beats operator/(Number factor) const {
+ return ticks ((_beats * PPQN + _ticks) / factor);
+ }
+
+ Beats& operator+=(const Beats& b) {
+ _beats += b._beats;
+ _ticks += b._ticks;
+ normalize();
+ return *this;
+ }
+
+ Beats& operator-=(const Beats& b) {
+ _beats -= b._beats;
+ _ticks -= b._ticks;
+ normalize();
+ return *this;
+ }
+
+ double to_double() const { return (double)_beats + (_ticks / (double)PPQN); }
+ int64_t to_ticks() const { return (int64_t)_beats * PPQN + _ticks; }
+ int64_t to_ticks(uint32_t ppqn) const { return (int64_t)_beats * ppqn + (_ticks * ppqn / PPQN); }
+
+ int32_t get_beats() const { return _beats; }
+ int32_t get_ticks() const { return _ticks; }
+
+ bool operator!() const { return _beats == 0 && _ticks == 0; }
+
+ static Beats tick() { return Beats(0, 1); }
+
+private:
+ int32_t _beats;
+ int32_t _ticks;
+};
+
+/*
+ TIL, several horrible hours later, that sometimes the compiler looks in the
+ namespace of a type (Evoral::Beats in this case) for an operator, and
+ does *NOT* look in the global namespace.
+
+ C++ is proof that hell exists and we are living in it. In any case, move
+ these to the global namespace and PBD::Property's loopy
+ virtual-method-in-a-template will bite you.
+*/
+
+inline std::ostream&
+operator<<(std::ostream& os, const Beats& t)
+{
+ os << t.get_beats() << '.' << t.get_ticks();
+ return os;
+}
+
+inline std::istream&
+operator>>(std::istream& is, Beats& t)
+{
+ double beats;
+ is >> beats;
+ t = Beats(beats);
+ return is;
+}
+
+} // namespace Evoral
+
+namespace PBD {
+ namespace DEBUG {
+ LIBEVORAL_API extern uint64_t Beats;
+ }
+}
+
+namespace std {
+ template<>
+ struct numeric_limits<Evoral::Beats> {
+ static Evoral::Beats lowest() {
+ return Evoral::Beats(std::numeric_limits<int32_t>::min(),
+ std::numeric_limits<int32_t>::min());
+ }
+
+ /* We don't define min() since this has different behaviour for integral and floating point types,
+ but Beats is used as both. Better to avoid providing a min at all
+ than a confusing one. */
+
+ static Evoral::Beats max() {
+ return Evoral::Beats(std::numeric_limits<int32_t>::max(),
+ std::numeric_limits<int32_t>::max());
+ }
+ };
+}
+
+#endif // EVORAL_BEATS_HPP
diff --git a/libs/temporal/temporal/superclock.h b/libs/temporal/temporal/superclock.h
new file mode 100644
index 0000000000..469537d123
--- /dev/null
+++ b/libs/temporal/temporal/superclock.h
@@ -0,0 +1,36 @@
+/*
+ Copyright (C) 2017 Paul Davis
+
+ This program 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.
+
+ This program 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 more 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __ardour_superclock_h__
+#define __ardour_superclock_h__
+
+#include <stdint.h>
+
+namespace ARDOUR {
+
+typedef uint64_t superclock_t;
+
+static const superclock_t superclock_ticks_per_second = 508032000; // 2^10 * 3^4 * 5^3 * 7^2
+
+static inline superclock_t superclock_to_samples (superclock_t s, int sr) { return (s * sr) / superclock_ticks_per_second; }
+static inline superclock_t samples_to_superclock (int samples, int sr) { return (samples * superclock_ticks_per_second) / sr; }
+
+}
+
+#endif /* __ardour_superclock_h__ */
diff --git a/libs/temporal/temporal/time.h b/libs/temporal/temporal/time.h
new file mode 100644
index 0000000000..556b73b625
--- /dev/null
+++ b/libs/temporal/temporal/time.h
@@ -0,0 +1,148 @@
+/*
+ Copyright (C) 2006-2010 Paul Davis
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published
+ by the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 more 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.,
+ 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __timecode_time_h__
+#define __timecode_time_h__
+
+#include <cmath>
+#include <ostream>
+#include <inttypes.h>
+
+#include "timecode/visibility.h"
+
+namespace Timecode {
+
+enum Wrap {
+ NONE = 0,
+ FRAMES,
+ SECONDS,
+ MINUTES,
+ HOURS
+};
+
+enum TimecodeFormat {
+ timecode_23976,
+ timecode_24,
+ timecode_24976,
+ timecode_25,
+ timecode_2997,
+ timecode_2997drop,
+ timecode_2997000,
+ timecode_2997000drop,
+ timecode_30,
+ timecode_30drop,
+ timecode_5994,
+ timecode_60
+};
+
+struct LIBTIMECODE_API Time {
+ bool negative;
+ uint32_t hours;
+ uint32_t minutes;
+ uint32_t seconds;
+ uint32_t frames; ///< Timecode frames (not audio frames)
+ uint32_t subframes; ///< Typically unused
+ double rate; ///< Frame rate of this Time
+ static double default_rate; ///< Rate to use for default constructor
+ bool drop; ///< Whether this Time uses dropframe Timecode
+
+ Time (double a_rate = default_rate) {
+ negative = false;
+ hours = 0;
+ minutes = 0;
+ seconds = 0;
+ frames = 0;
+ subframes = 0;
+ rate = a_rate;
+ drop = (lrintf(100.f * (float)a_rate) == (long)2997);
+ }
+
+ bool operator== (const Time& other) const {
+ return negative == other.negative && hours == other.hours &&
+ minutes == other.minutes && seconds == other.seconds &&
+ frames == other.frames && subframes == other.subframes &&
+ rate == other.rate && drop == other.drop;
+ }
+
+ std::ostream& print (std::ostream& ostr) const {
+ if (negative) {
+ ostr << '-';
+ }
+ ostr << hours << ':' << minutes << ':' << seconds << ':'
+ << frames << '.' << subframes
+ << " @" << rate << (drop ? " drop" : " nondrop");
+ return ostr;
+ }
+
+};
+
+Wrap LIBTIMECODE_API increment (Time& timecode, uint32_t);
+Wrap LIBTIMECODE_API decrement (Time& timecode, uint32_t);
+Wrap LIBTIMECODE_API increment_subframes (Time& timecode, uint32_t);
+Wrap LIBTIMECODE_API decrement_subframes (Time& timecode, uint32_t);
+Wrap LIBTIMECODE_API increment_seconds (Time& timecode, uint32_t);
+Wrap LIBTIMECODE_API increment_minutes (Time& timecode, uint32_t);
+Wrap LIBTIMECODE_API increment_hours (Time& timecode, uint32_t);
+void LIBTIMECODE_API frames_floot (Time& timecode);
+void LIBTIMECODE_API seconds_floor (Time& timecode);
+void LIBTIMECODE_API minutes_floor (Time& timecode);
+void LIBTIMECODE_API hours_floor (Time& timecode);
+
+double LIBTIMECODE_API timecode_to_frames_per_second(TimecodeFormat const t);
+bool LIBTIMECODE_API timecode_has_drop_frames(TimecodeFormat const t);
+
+std::string LIBTIMECODE_API timecode_format_name (TimecodeFormat const t);
+
+std::string LIBTIMECODE_API timecode_format_time (Timecode::Time const timecode);
+
+std::string LIBTIMECODE_API timecode_format_sampletime (
+ int64_t sample,
+ double sample_sample_rate,
+ double timecode_frames_per_second, bool timecode_drop_frames
+ );
+
+bool LIBTIMECODE_API parse_timecode_format(std::string tc, Timecode::Time &TC);
+
+void LIBTIMECODE_API timecode_to_sample(
+ Timecode::Time& timecode, int64_t& sample,
+ bool use_offset, bool use_subframes,
+ /* Note - framerate info is taken from Timecode::Time& */
+ double sample_sample_rate /**< may include pull up/down */,
+ uint32_t subframes_per_frame /**< must not be 0 if use_subframes==true */,
+ /* optional offset - can be improved: function pointer to lazily query this*/
+ bool offset_is_negative, int64_t offset_samples
+ );
+
+void LIBTIMECODE_API sample_to_timecode (
+ int64_t sample, Timecode::Time& timecode,
+ bool use_offset, bool use_subframes,
+ /* framerate info */
+ double timecode_frames_per_second,
+ bool timecode_drop_frames,
+ double sample_sample_rate/**< can include pull up/down */,
+ uint32_t subframes_per_frame,
+ /* optional offset - can be improved: function pointer to lazily query this*/
+ bool offset_is_negative, int64_t offset_samples
+ );
+
+
+} // namespace Timecode
+
+extern LIBTIMECODE_API std::ostream& operator<< (std::ostream& ostr, const Timecode::Time& t);
+
+#endif // __timecode_time_h__
diff --git a/libs/temporal/temporal/types.h b/libs/temporal/temporal/types.h
new file mode 100644
index 0000000000..1d19245ec8
--- /dev/null
+++ b/libs/temporal/temporal/types.h
@@ -0,0 +1,46 @@
+/*
+ Copyright (C) 2017 Paul Davis
+
+ This program 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.
+
+ This program 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 more 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __libpbd_position_types_h__
+#define __libpbd_position_types_h__
+
+#include <stdint.h>
+
+namespace PBD {
+
+/* Any position measured in audio samples.
+ Assumed to be non-negative but not enforced.
+*/
+typedef int64_t samplepos_t;
+
+/* Any distance from a given samplepos_t.
+ Maybe positive or negative.
+*/
+typedef int64_t sampleoffset_t;
+
+/* Any count of audio samples.
+ Assumed to be positive but not enforced.
+*/
+typedef int64_t samplecnt_t;
+
+static const samplepos_t max_samplepos = INT64_MAX;
+static const samplecnt_t max_samplecnt = INT64_MAX;
+
+}
+
+#endif /* __libpbd_position_types_h__ */
diff --git a/libs/temporal/temporal/visibility.h b/libs/temporal/temporal/visibility.h
new file mode 100644
index 0000000000..8de8cb7ffa
--- /dev/null
+++ b/libs/temporal/temporal/visibility.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2014 Paul Davis
+
+ This program 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.
+
+ This program 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 more 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __libtimecode_visibility_h__
+#define __libtimecode_visibility_h__
+
+#if defined(COMPILER_MSVC)
+ #define LIBTIMECODE_DLL_IMPORT __declspec(dllimport)
+ #define LIBTIMECODE_DLL_EXPORT __declspec(dllexport)
+ #define LIBTIMECODE_DLL_LOCAL
+#else
+ #define LIBTIMECODE_DLL_IMPORT __attribute__ ((visibility ("default")))
+ #define LIBTIMECODE_DLL_EXPORT __attribute__ ((visibility ("default")))
+ #define LIBTIMECODE_DLL_LOCAL __attribute__ ((visibility ("hidden")))
+#endif
+
+#ifdef LIBTIMECODE_DLL_EXPORTS // defined if we are building the libtimecode DLL (instead of using it)
+ #define LIBTIMECODE_API LIBTIMECODE_DLL_EXPORT
+#else
+ #define LIBTIMECODE_API LIBTIMECODE_DLL_IMPORT
+#endif
+#define LIBTIMECODE_LOCAL LIBTIMECODE_DLL_LOCAL
+
+#endif /* __libtimecode_visibility_h__ */