556b73b62507583fc4199010a3e4279d2925510f
[ardour.git] / libs / temporal / temporal / time.h
1 /*
2         Copyright (C) 2006-2010 Paul Davis
3
4         This program is free software; you can redistribute it and/or modify it
5         under the terms of the GNU Lesser General Public License as published
6         by the Free Software Foundation; either version 2 of the License, or
7         (at your option) any later version.
8
9         This program is distributed in the hope that it will be useful, but WITHOUT
10         ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11         FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12         for more details.
13
14         You should have received a copy of the GNU General Public License along
15         with this program; if not, write to the Free Software Foundation, Inc.,
16         675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #ifndef __timecode_time_h__
20 #define __timecode_time_h__
21
22 #include <cmath>
23 #include <ostream>
24 #include <inttypes.h>
25
26 #include "timecode/visibility.h"
27
28 namespace Timecode {
29
30 enum Wrap {
31         NONE = 0,
32         FRAMES,
33         SECONDS,
34         MINUTES,
35         HOURS
36 };
37
38 enum TimecodeFormat {
39         timecode_23976,
40         timecode_24,
41         timecode_24976,
42         timecode_25,
43         timecode_2997,
44         timecode_2997drop,
45         timecode_2997000,
46         timecode_2997000drop,
47         timecode_30,
48         timecode_30drop,
49         timecode_5994,
50         timecode_60
51 };
52
53 struct LIBTIMECODE_API Time {
54         bool          negative;
55         uint32_t      hours;
56         uint32_t      minutes;
57         uint32_t      seconds;
58         uint32_t      frames;        ///< Timecode frames (not audio frames)
59         uint32_t      subframes;     ///< Typically unused
60         double        rate;          ///< Frame rate of this Time
61         static double default_rate;  ///< Rate to use for default constructor
62         bool          drop;          ///< Whether this Time uses dropframe Timecode
63
64         Time (double a_rate = default_rate) {
65                 negative = false;
66                 hours = 0;
67                 minutes = 0;
68                 seconds = 0;
69                 frames = 0;
70                 subframes = 0;
71                 rate = a_rate;
72                 drop = (lrintf(100.f * (float)a_rate) == (long)2997);
73         }
74
75         bool operator== (const Time& other) const {
76                 return negative == other.negative && hours == other.hours &&
77                        minutes == other.minutes && seconds == other.seconds &&
78                        frames == other.frames && subframes == other.subframes &&
79                        rate == other.rate && drop == other.drop;
80         }
81
82         std::ostream& print (std::ostream& ostr) const {
83                 if (negative) {
84                         ostr << '-';
85                 }
86                 ostr << hours << ':' << minutes << ':' << seconds << ':'
87                      << frames << '.' << subframes
88                      << " @" << rate << (drop ? " drop" : " nondrop");
89                 return ostr;
90         }
91
92 };
93
94 Wrap LIBTIMECODE_API increment (Time& timecode, uint32_t);
95 Wrap LIBTIMECODE_API decrement (Time& timecode, uint32_t);
96 Wrap LIBTIMECODE_API increment_subframes (Time& timecode, uint32_t);
97 Wrap LIBTIMECODE_API decrement_subframes (Time& timecode, uint32_t);
98 Wrap LIBTIMECODE_API increment_seconds (Time& timecode, uint32_t);
99 Wrap LIBTIMECODE_API increment_minutes (Time& timecode, uint32_t);
100 Wrap LIBTIMECODE_API increment_hours (Time& timecode, uint32_t);
101 void LIBTIMECODE_API frames_floot (Time& timecode);
102 void LIBTIMECODE_API seconds_floor (Time& timecode);
103 void LIBTIMECODE_API minutes_floor (Time& timecode);
104 void LIBTIMECODE_API hours_floor (Time& timecode);
105
106 double LIBTIMECODE_API timecode_to_frames_per_second(TimecodeFormat const t);
107 bool LIBTIMECODE_API timecode_has_drop_frames(TimecodeFormat const t);
108
109 std::string LIBTIMECODE_API timecode_format_name (TimecodeFormat const t);
110
111 std::string LIBTIMECODE_API timecode_format_time (Timecode::Time const timecode);
112
113 std::string LIBTIMECODE_API timecode_format_sampletime (
114                 int64_t sample,
115                 double sample_sample_rate,
116                 double timecode_frames_per_second, bool timecode_drop_frames
117                 );
118
119 bool LIBTIMECODE_API parse_timecode_format(std::string tc, Timecode::Time &TC);
120
121 void LIBTIMECODE_API timecode_to_sample(
122                 Timecode::Time& timecode, int64_t& sample,
123                 bool use_offset, bool use_subframes,
124     /* Note - framerate info is taken from Timecode::Time& */
125                 double sample_sample_rate /**< may include pull up/down */,
126                 uint32_t subframes_per_frame /**< must not be 0 if use_subframes==true */,
127     /* optional offset  - can be improved: function pointer to lazily query this*/
128                 bool offset_is_negative, int64_t offset_samples
129                 );
130
131 void LIBTIMECODE_API sample_to_timecode (
132                 int64_t sample, Timecode::Time& timecode,
133                 bool use_offset, bool use_subframes,
134     /* framerate info */
135                 double timecode_frames_per_second,
136                 bool   timecode_drop_frames,
137                 double sample_sample_rate/**< can include pull up/down */,
138                 uint32_t subframes_per_frame,
139     /* optional offset  - can be improved: function pointer to lazily query this*/
140                 bool offset_is_negative, int64_t offset_samples
141                 );
142
143
144 } // namespace Timecode
145
146 extern LIBTIMECODE_API std::ostream& operator<< (std::ostream& ostr, const Timecode::Time& t);
147
148 #endif  // __timecode_time_h__