summaryrefslogtreecommitdiff
path: root/libs/timecode/timecode/time.h
blob: d9b3f01444b895102d51aba059e39a7a079f9905 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
	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 <ostream>
#include <inttypes.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_30,
	timecode_30drop,
	timecode_5994,
	timecode_60
};

struct Time {
	bool         negative;
	uint32_t     hours;
	uint32_t     minutes;
	uint32_t     seconds;
	uint32_t     frames;        ///< Timecode frames (not audio samples)
	uint32_t     subframes;     ///< Typically unused
	float        rate;          ///< Frame rate of this Time
	static float default_rate;  ///< Rate to use for default constructor
	bool         drop;          ///< Whether this Time uses dropframe Timecode

	Time (float a_rate = default_rate) {
		negative = false;
		hours = 0;
		minutes = 0;
		seconds = 0;
		frames = 0;
		subframes = 0;
		rate = a_rate;
	}
	
	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 increment (Time& timecode, uint32_t);
Wrap decrement (Time& timecode, uint32_t);
Wrap increment_subframes (Time& timecode, uint32_t);
Wrap decrement_subframes (Time& timecode, uint32_t);
Wrap increment_seconds (Time& timecode, uint32_t);
Wrap increment_minutes (Time& timecode, uint32_t);
Wrap increment_hours (Time& timecode, uint32_t);
void frames_floor (Time& timecode);
void seconds_floor (Time& timecode);
void minutes_floor (Time& timecode);
void hours_floor (Time& timecode);

float timecode_to_frames_per_second(TimecodeFormat const t);
bool timecode_has_drop_frames(TimecodeFormat const t);

std::string timecode_format_name (TimecodeFormat const t);

std::string timecode_format_time (Timecode::Time& timecode);

std::string timecode_format_sampletime (
		int64_t sample,
		double sample_frame_rate,
		double timecode_frames_per_second, bool timecode_drop_frames
		);

void
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_frame_rate /**< may include pull up/down */,
		int32_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 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_frame_rate/**< can include pull up/down */,
		int32_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

std::ostream& operator<< (std::ostream& ostr, const Timecode::Time& t);

#endif  // __timecode_time_h__