2 Copyright (C) 2006 Paul Davis
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.
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
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.
19 #define SMPTE_IS_AROUND_ZERO( sm ) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours)
20 #define SMPTE_IS_ZERO( sm ) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours && !(sm.subframes))
22 #include <control_protocol/smpte.h>
26 FPS Time::default_rate = MTC_30_FPS;
29 /** Increment @a smpte by exactly one frame (keep subframes value).
31 * @return true if seconds wrap.
34 increment( Time& smpte )
39 if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) {
40 // We have a zero transition involving only subframes
41 smpte.subframes = 80 - smpte.subframes;
42 smpte.negative = false;
46 smpte.negative = false;
47 wrap = decrement( smpte );
48 if (!SMPTE_IS_ZERO( smpte )) {
49 smpte.negative = true;
56 if (smpte.frames == 23) {
62 if (smpte.frames == 24) {
68 if (smpte.frames == 29) {
69 if ( ((smpte.minutes + 1) % 10) && (smpte.seconds == 59) ) {
79 if (smpte.frames == 29) {
86 if (wrap == SECONDS) {
87 if (smpte.seconds == 59) {
90 if (smpte.minutes == 59) {
108 /** Decrement @a smpte by exactly one frame (keep subframes value)
110 * @return true if seconds wrap. */
112 decrement( Time& smpte )
117 if (smpte.negative || SMPTE_IS_ZERO(smpte)) {
118 smpte.negative = false;
119 wrap = increment( smpte );
120 smpte.negative = true;
122 } else if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) {
123 // We have a zero transition involving only subframes
124 smpte.subframes = 80 - smpte.subframes;
125 smpte.negative = true;
129 switch (smpte.rate) {
131 if (smpte.frames == 0) {
137 if (smpte.frames == 0) {
142 case MTC_30_FPS_DROP:
143 if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
144 if (smpte.frames <= 2) {
148 } else if (smpte.frames == 0) {
154 if (smpte.frames == 0) {
161 if (wrap == SECONDS) {
162 if (smpte.seconds == 0) {
165 if (smpte.minutes == 0) {
180 if (SMPTE_IS_ZERO( smpte )) {
181 smpte.negative = false;
188 /** Go to lowest absolute subframe value in this frame (set to 0 :-) ) */
190 frames_floor( Time& smpte )
193 if (SMPTE_IS_ZERO(smpte)) {
194 smpte.negative = false;
199 /** Increment @a smpte by one subframe */
201 increment_subframes( Time& smpte )
205 if (smpte.negative) {
206 smpte.negative = false;
207 wrap = decrement_subframes( smpte );
208 if (!SMPTE_IS_ZERO(smpte)) {
209 smpte.negative = true;
215 if (smpte.subframes >= 80) {
224 /** Decrement @a smpte by one subframe */
226 decrement_subframes( Time& smpte )
230 if (smpte.negative) {
231 smpte.negative = false;
232 wrap = increment_subframes( smpte );
233 smpte.negative = true;
237 if (smpte.subframes <= 0) {
239 if (SMPTE_IS_ZERO(smpte)) {
240 smpte.negative = true;
245 smpte.subframes = 79;
250 if (SMPTE_IS_ZERO(smpte)) {
251 smpte.negative = false;
258 /** Go to next whole second (frames == 0 or frames == 2) */
260 increment_seconds( Time& smpte )
265 frames_floor( smpte );
267 if (smpte.negative) {
268 // Wrap second if on second boundary
269 wrap = increment(smpte);
270 // Go to lowest absolute frame value
271 seconds_floor( smpte );
272 if (SMPTE_IS_ZERO(smpte)) {
273 smpte.negative = false;
276 // Go to highest possible frame in this second
277 switch (smpte.rate) {
284 case MTC_30_FPS_DROP:
290 // Increment by one frame
291 wrap = increment( smpte );
298 /** Go to lowest (absolute) frame value in this second
299 * Doesn't care about positive/negative */
301 seconds_floor( Time& smpte )
304 frames_floor( smpte );
306 // Go to lowest possible frame in this second
307 switch (smpte.rate) {
313 case MTC_30_FPS_DROP:
314 if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
322 if (SMPTE_IS_ZERO(smpte)) {
323 smpte.negative = false;
328 /** Go to next whole minute (seconds == 0, frames == 0 or frames == 2) */
330 increment_minutes( Time& smpte )
335 frames_floor( smpte );
337 if (smpte.negative) {
338 // Wrap if on minute boundary
339 wrap = increment_seconds( smpte );
340 // Go to lowest possible value in this minute
341 minutes_floor( smpte );
343 // Go to highest possible second
345 // Wrap minute by incrementing second
346 wrap = increment_seconds( smpte );
353 /** Go to lowest absolute value in this minute */
355 minutes_floor( Time& smpte )
357 // Go to lowest possible second
359 // Go to lowest possible frame
360 seconds_floor( smpte );
362 if (SMPTE_IS_ZERO(smpte)) {
363 smpte.negative = false;
368 /** Go to next whole hour (minute = 0, second = 0, frame = 0) */
370 increment_hours( Time& smpte )
377 if (smpte.negative) {
378 // Wrap if on hour boundary
379 wrap = increment_minutes( smpte );
380 // Go to lowest possible value in this hour
381 hours_floor( smpte );
384 wrap = increment_minutes( smpte );
391 /** Go to lowest absolute value in this hour */
393 hours_floor( Time& smpte )
400 if (SMPTE_IS_ZERO(smpte)) {
401 smpte.negative = false;