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