1 /***********************************************************************
4 * DESCR: Handles all TimeCode functions.
5 ***********************************************************************/
10 status_t
us_to_timecode(bigtime_t micros
, int * hours
, int * minutes
, int * seconds
, int * frames
, const timecode_info
* code
)
17 // We have a valid timecode_info
19 case B_TIMECODE_DEFAULT
: // NTSC
20 case B_TIMECODE_30_DROP_2
: // NTSC
21 l_frames
= int32((((micros
% 1000000) * 29.97) / 1000000) + (micros
/ 1000000 * 29.97));
23 case B_TIMECODE_30_DROP_4
: // Brazil
24 l_frames
= int32((((micros
% 1000000) * 29.95) / 1000000) + (micros
/ 1000000 * 29.95));
27 l_frames
= (((micros
% 1000000) * code
->fps_div
) / 1000000) + (micros
/ 1000000 * code
->fps_div
);
31 // Convert us to frames
32 l_frames
= int32((((micros
% 1000000) * 29.97) / 1000000) + (micros
/ 1000000 * 29.97));
35 return frames_to_timecode(l_frames
, hours
, minutes
, seconds
, frames
, code
);
38 status_t
timecode_to_us(int hours
, int minutes
, int seconds
, int frames
, bigtime_t
* micros
, const timecode_info
* code
)
44 if (timecode_to_frames(hours
, minutes
, seconds
, frames
, &l_frames
, code
) == B_OK
) {
47 // We have a valid timecode_info
49 case B_TIMECODE_DEFAULT
: // NTSC
50 case B_TIMECODE_30_DROP_2
: // NTSC
51 *micros
= bigtime_t(l_frames
* ((1000000 / 29.97) + 0.5));
53 case B_TIMECODE_30_DROP_4
: // Brazil
54 *micros
= bigtime_t(l_frames
* ((1000000 / 29.95) + 0.5));
57 *micros
= l_frames
* 1000000 / code
->fps_div
;
62 *micros
= bigtime_t(l_frames
* ((1000000 / 29.97) + 0.5));
70 status_t
frames_to_timecode(int32 l_frames
, int * hours
, int * minutes
, int * seconds
, int * frames
, const timecode_info
* code
)
80 // We have a valid timecode_info so use it
81 fps_div
= code
->fps_div
;
83 if (code
->every_nth
> 0) {
84 // Handle Drop Frames format
86 total_mins
= l_frames
/ fps_div
/ 60;
88 // "every_nth" minute we gain "drop_frames" "except_nth" minute
89 extra_frames
= code
->drop_frames
*(total_mins
/code
->every_nth
) - code
->drop_frames
*(total_mins
/code
->except_nth
);
90 l_frames
+= extra_frames
;
92 total_mins
= l_frames
/ fps_div
/ 60;
93 extra_frames2
= code
->drop_frames
*(total_mins
/code
->every_nth
) - code
->drop_frames
*(total_mins
/code
->except_nth
);
95 // Gaining frames may mean that we gain more frames so we keep adjusting until no more to adjust
96 while (extra_frames
!= extra_frames2
) {
97 l_frames
+= extra_frames2
- extra_frames
;
98 extra_frames
= extra_frames2
;
100 total_mins
= l_frames
/ fps_div
/ 60;
101 extra_frames2
= code
->drop_frames
*(total_mins
/code
->every_nth
) - code
->drop_frames
*(total_mins
/code
->except_nth
);
104 // l_frames should now include all adjusted frames
107 // no timecode_info so set default NTSC :-(
108 fps_div
= 30; // NTSC Default
109 total_mins
= l_frames
/ fps_div
/ 60;
111 // "every_nth" minute we gain "drop_frames" "except_nth" minute
112 extra_frames
= 2*(total_mins
) - 2*(total_mins
/10);
113 l_frames
+= extra_frames
;
115 total_mins
= l_frames
/ fps_div
/ 60;
116 extra_frames2
= 2*(total_mins
) - 2*(total_mins
/10);
118 // Gaining frames may mean that we gain more frames so we keep adjusting until no more to adjust
119 while (extra_frames
!= extra_frames2
) {
120 l_frames
+= extra_frames2
- extra_frames
;
121 extra_frames
= extra_frames2
;
123 total_mins
= l_frames
/ fps_div
/ 60;
124 extra_frames2
= 2*(total_mins
) - 2*(total_mins
/10);
128 // convert frames to seconds leaving the remainder as frames
129 *seconds
= l_frames
/ fps_div
; // DIV
130 *frames
= l_frames
% fps_div
; // MOD
132 // Normalise to Hours Minutes Seconds Frames
133 *minutes
= *seconds
/ 60;
134 *seconds
= *seconds
% 60;
136 *hours
= *minutes
/ 60;
137 *minutes
= *minutes
% 60;
142 status_t
timecode_to_frames(int hours
, int minutes
, int seconds
, int frames
, int32
* l_frames
, const timecode_info
* code
)
151 // We have a valid timecode_info
152 fps_div
= code
->fps_div
;
154 total_mins
= (hours
* 60) + minutes
;
155 *l_frames
= (total_mins
* 60) + seconds
;
156 *l_frames
= (*l_frames
* fps_div
) + frames
;
158 // Adjust "every_nth" minute we lose "drop_frames" "except_nth" minute
159 if (code
->every_nth
> 0) {
160 extra_frames
= code
->drop_frames
*(total_mins
/code
->every_nth
) - code
->drop_frames
*(total_mins
/code
->except_nth
);
162 *l_frames
= *l_frames
- extra_frames
;
166 total_mins
= (hours
* 60) + minutes
;
167 *l_frames
= (total_mins
* 60) + seconds
;
168 *l_frames
= (*l_frames
* 30) + frames
;
170 // Adjust "every_nth" minute we lose "drop_frames" "except_nth" minute
171 extra_frames
= 2*(total_mins
) - 2*(total_mins
/10);
173 *l_frames
= *l_frames
- extra_frames
;
179 status_t
get_timecode_description(timecode_type type
, timecode_info
* out_timecode
)
183 out_timecode
->type
= type
;
184 strncpy(out_timecode
->format
,"%.2ih:%.2im:%.2is.%.2i",31);
185 out_timecode
->every_nth
= 0;
186 out_timecode
->except_nth
= 0;
190 strncpy(out_timecode
->name
,"100 FPS",31);
191 out_timecode
->fps_div
= 100;
193 case B_TIMECODE_75
: // CD
194 strncpy(out_timecode
->name
,"CD",31);
195 out_timecode
->fps_div
= 75;
197 case B_TIMECODE_30
: // MIDI
198 strncpy(out_timecode
->name
,"MIDI",31);
199 out_timecode
->fps_div
= 30;
201 case B_TIMECODE_30_DROP_2
: // NTSC
202 strncpy(out_timecode
->name
,"NTSC",31);
203 out_timecode
->fps_div
= 30; // This is supposed to be 29.97fps but can be simulated using the drop frame format below
204 out_timecode
->drop_frames
= 2; // Drop 2 frames
205 out_timecode
->every_nth
= 1; // every 1 minutes
206 out_timecode
->except_nth
= 10; // except every 10 minutes
208 case B_TIMECODE_30_DROP_4
: // Brazil
209 strncpy(out_timecode
->name
,"NTSC Brazil",31);
210 out_timecode
->fps_div
= 30;
211 out_timecode
->drop_frames
= 4; // Drop 4 frames
212 out_timecode
->every_nth
= 1; // every 1 minutes
213 out_timecode
->except_nth
= 10; // except every 10 minutes
215 case B_TIMECODE_25
: // PAL
216 strncpy(out_timecode
->name
,"PAL",31);
217 out_timecode
->fps_div
= 25;
219 case B_TIMECODE_24
: // Film
220 strncpy(out_timecode
->name
,"FILM",31);
221 out_timecode
->fps_div
= 24;
223 case B_TIMECODE_18
: // Super8
224 strncpy(out_timecode
->name
,"Super 8",31);
225 out_timecode
->fps_div
= 18;
228 strncpy(out_timecode
->name
,"NTSC",31);
229 out_timecode
->fps_div
= 30; // This is supposed to be 29.97fps but can be simulated using the drop frame format below
230 out_timecode
->drop_frames
= 2; // Drop 2 frames
231 out_timecode
->every_nth
= 1; // every 1 minutes
232 out_timecode
->except_nth
= 10; // except every 10 minutes
239 status_t
count_timecodes()
242 return 8; // Is this right?
245 /*************************************************************
247 *************************************************************/
250 BTimeCode::BTimeCode()
256 BTimeCode::BTimeCode(bigtime_t us
,
260 if (SetType(type
) == B_OK
) {
266 BTimeCode::BTimeCode(const BTimeCode
&clone
)
269 if (SetType(clone
.Type()) == B_OK
) {
270 SetData(clone
.Hours(),clone
.Minutes(),clone
.Seconds(),clone
.Frames());
275 BTimeCode::BTimeCode(int hours
,
282 if (SetType(type
) == B_OK
) {
283 SetData(hours
,minutes
,seconds
,frames
);
288 BTimeCode::~BTimeCode()
295 BTimeCode::SetData(int hours
,
309 BTimeCode::SetType(timecode_type type
)
313 return get_timecode_description(type
, &fInfo
);
318 BTimeCode::SetMicroseconds(bigtime_t us
)
322 us_to_timecode(us
, &fHours
, &fMinutes
, &fSeconds
, &fFrames
, &fInfo
);
327 BTimeCode::SetLinearFrames(int32 linear_frames
)
331 frames_to_timecode(linear_frames
, &fHours
, &fMinutes
, &fSeconds
, &fFrames
, &fInfo
);
336 BTimeCode::operator=(const BTimeCode
&clone
)
339 fHours
= clone
.Hours();
340 fMinutes
= clone
.Minutes();
341 fSeconds
= clone
.Seconds();
342 fFrames
= clone
.Frames();
343 SetType(clone
.Type());
350 BTimeCode::operator==(const BTimeCode
&other
) const
354 return ((this->LinearFrames()) == (other
.LinearFrames()));
359 BTimeCode::operator<(const BTimeCode
&other
) const
363 return ((this->LinearFrames()) < (other
.LinearFrames()));
368 BTimeCode::operator+=(const BTimeCode
&other
)
372 this->SetLinearFrames(this->LinearFrames() + other
.LinearFrames());
379 BTimeCode::operator-=(const BTimeCode
&other
)
383 this->SetLinearFrames(this->LinearFrames() - other
.LinearFrames());
390 BTimeCode::operator+(const BTimeCode
&other
) const
400 BTimeCode::operator-(const BTimeCode
&other
) const
410 BTimeCode::Hours() const
419 BTimeCode::Minutes() const
428 BTimeCode::Seconds() const
437 BTimeCode::Frames() const
446 BTimeCode::Type() const
455 BTimeCode::GetData(int *out_hours
,
459 timecode_type
*out_type
) const
463 *out_minutes
= fMinutes
;
464 *out_seconds
= fSeconds
;
465 *out_frames
= fFrames
;
466 *out_type
= fInfo
.type
;
471 BTimeCode::Microseconds() const
477 if (timecode_to_us(fHours
,fMinutes
,fSeconds
,fFrames
, &us
, &fInfo
) == B_OK
) {
486 BTimeCode::LinearFrames() const
492 if (timecode_to_frames(fHours
,fMinutes
,fSeconds
,fFrames
,&linear_frames
,&fInfo
) == B_OK
) {
493 return linear_frames
;
501 BTimeCode::GetString(char *str
) const
504 sprintf(str
,fInfo
.format
, fHours
, fMinutes
, fSeconds
, fFrames
);