Merge branch 'master' into cairocanvas
[ardour.git] / libs / timecode / timecode / 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 <ostream>
23 #include <inttypes.h>
24
25 #include "timecode/visibility.h"
26
27 namespace Timecode {
28
29 enum Wrap {
30         NONE = 0,
31         FRAMES,
32         SECONDS,
33         MINUTES,
34         HOURS
35 };
36
37 enum TimecodeFormat {
38         timecode_23976,
39         timecode_24,
40         timecode_24976,
41         timecode_25,
42         timecode_2997,
43         timecode_2997drop,
44         timecode_2997000,
45         timecode_2997000drop,
46         timecode_30,
47         timecode_30drop,
48         timecode_5994,
49         timecode_60
50 };
51
52 struct LIBTIMECODE_API Time {
53         bool          negative;
54         uint32_t      hours;
55         uint32_t      minutes;
56         uint32_t      seconds;
57         uint32_t      frames;        ///< Timecode frames (not audio samples)
58         uint32_t      subframes;     ///< Typically unused
59         double        rate;          ///< Frame rate of this Time
60         static double default_rate;  ///< Rate to use for default constructor
61         bool          drop;          ///< Whether this Time uses dropframe Timecode
62
63         Time (double a_rate = default_rate) {
64                 negative = false;
65                 hours = 0;
66                 minutes = 0;
67                 seconds = 0;
68                 frames = 0;
69                 subframes = 0;
70                 rate = a_rate;
71         }
72         
73         bool operator== (const Time& other) const {
74                 return negative == other.negative && hours == other.hours &&
75                        minutes == other.minutes && seconds == other.seconds &&
76                        frames == other.frames && subframes == other.subframes &&
77                        rate == other.rate && drop == other.drop;
78         }
79
80         std::ostream& print (std::ostream& ostr) const {
81                 if (negative) {
82                         ostr << '-';
83                 }
84                 ostr << hours << ':' << minutes << ':' << seconds << ':'
85                      << frames << '.' << subframes
86                      << " @" << rate << (drop ? " drop" : " nondrop");
87                 return ostr;
88         }
89
90 };
91
92 Wrap LIBTIMECODE_API increment (Time& timecode, uint32_t);
93 Wrap LIBTIMECODE_API decrement (Time& timecode, uint32_t);
94 Wrap LIBTIMECODE_API increment_subframes (Time& timecode, uint32_t);
95 Wrap LIBTIMECODE_API decrement_subframes (Time& timecode, uint32_t);
96 Wrap LIBTIMECODE_API increment_seconds (Time& timecode, uint32_t);
97 Wrap LIBTIMECODE_API increment_minutes (Time& timecode, uint32_t);
98 Wrap LIBTIMECODE_API increment_hours (Time& timecode, uint32_t);
99 void LIBTIMECODE_API frames_floor (Time& timecode);
100 void LIBTIMECODE_API seconds_floor (Time& timecode);
101 void LIBTIMECODE_API minutes_floor (Time& timecode);
102 void LIBTIMECODE_API hours_floor (Time& timecode);
103
104 double LIBTIMECODE_API timecode_to_frames_per_second(TimecodeFormat const t);
105 bool LIBTIMECODE_API timecode_has_drop_frames(TimecodeFormat const t);
106
107 std::string LIBTIMECODE_API timecode_format_name (TimecodeFormat const t);
108
109 std::string LIBTIMECODE_API timecode_format_time (Timecode::Time const timecode);
110
111 std::string LIBTIMECODE_API timecode_format_sampletime (
112                 int64_t sample,
113                 double sample_frame_rate,
114                 double timecode_frames_per_second, bool timecode_drop_frames
115                 );
116
117 bool LIBTIMECODE_API parse_timecode_format(std::string tc, Timecode::Time &TC);
118
119 void LIBTIMECODE_API timecode_to_sample(
120                 Timecode::Time& timecode, int64_t& sample,
121                 bool use_offset, bool use_subframes,
122     /* Note - framerate info is taken from Timecode::Time& */
123                 double sample_frame_rate /**< may include pull up/down */,
124                 uint32_t subframes_per_frame /**< must not be 0 if use_subframes==true */,
125     /* optional offset  - can be improved: function pointer to lazily query this*/
126                 bool offset_is_negative, int64_t offset_samples
127                 );
128
129 void LIBTIMECODE_API sample_to_timecode (
130                 int64_t sample, Timecode::Time& timecode,
131                 bool use_offset, bool use_subframes,
132     /* framerate info */
133                 double timecode_frames_per_second,
134                 bool   timecode_drop_frames,
135                 double sample_frame_rate/**< can include pull up/down */,
136                 uint32_t subframes_per_frame,
137     /* optional offset  - can be improved: function pointer to lazily query this*/
138                 bool offset_is_negative, int64_t offset_samples
139                 );
140
141
142 } // namespace Timecode
143
144 extern LIBTIMECODE_API std::ostream& operator<< (std::ostream& ostr, const Timecode::Time& t);
145
146 #endif  // __timecode_time_h__