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"
23 #include "ardour/rc_configuration.h"
27 float Time::default_rate = 30.0;
30 /** Increment @a smpte by exactly one frame (keep subframes value).
32 * @return true if seconds wrap.
35 increment( Time& smpte, uint32_t subframes_per_frame )
40 if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) {
41 // We have a zero transition involving only subframes
42 smpte.subframes = subframes_per_frame - smpte.subframes;
43 smpte.negative = false;
47 smpte.negative = false;
48 wrap = decrement( smpte, subframes_per_frame );
49 if (!SMPTE_IS_ZERO( smpte )) {
50 smpte.negative = true;
55 switch ((int)ceil(smpte.rate)) {
57 if (smpte.frames == 23) {
63 if (smpte.frames == 24) {
70 if (smpte.frames == 29) {
71 if ( ((smpte.minutes + 1) % 10) && (smpte.seconds == 59) ) {
81 if (smpte.frames == 29) {
88 if (smpte.frames == 59) {
95 if (wrap == SECONDS) {
96 if (smpte.seconds == 59) {
99 if (smpte.minutes == 59) {
117 /** Decrement @a smpte by exactly one frame (keep subframes value)
119 * @return true if seconds wrap. */
121 decrement( Time& smpte, uint32_t subframes_per_frame )
126 if (smpte.negative || SMPTE_IS_ZERO(smpte)) {
127 smpte.negative = false;
128 wrap = increment( smpte, subframes_per_frame );
129 smpte.negative = true;
131 } else if (SMPTE_IS_AROUND_ZERO(smpte) && smpte.subframes) {
132 // We have a zero transition involving only subframes
133 smpte.subframes = subframes_per_frame - smpte.subframes;
134 smpte.negative = true;
138 switch ((int)ceil(smpte.rate)) {
140 if (smpte.frames == 0) {
146 if (smpte.frames == 0) {
153 if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
154 if (smpte.frames <= 2) {
158 } else if (smpte.frames == 0) {
164 if (smpte.frames == 0) {
171 if (smpte.frames == 0) {
178 if (wrap == SECONDS) {
179 if (smpte.seconds == 0) {
182 if (smpte.minutes == 0) {
197 if (SMPTE_IS_ZERO( smpte )) {
198 smpte.negative = false;
205 /** Go to lowest absolute subframe value in this frame (set to 0 :-) ) */
207 frames_floor( Time& smpte )
210 if (SMPTE_IS_ZERO(smpte)) {
211 smpte.negative = false;
216 /** Increment @a smpte by one subframe */
218 increment_subframes( Time& smpte, uint32_t subframes_per_frame )
222 if (smpte.negative) {
223 smpte.negative = false;
224 wrap = decrement_subframes( smpte, subframes_per_frame );
225 if (!SMPTE_IS_ZERO(smpte)) {
226 smpte.negative = true;
232 if (smpte.subframes >= subframes_per_frame) {
234 increment( smpte, subframes_per_frame );
241 /** Decrement @a smpte by one subframe */
243 decrement_subframes( Time& smpte, uint32_t subframes_per_frame )
247 if (smpte.negative) {
248 smpte.negative = false;
249 wrap = increment_subframes( smpte, subframes_per_frame );
250 smpte.negative = true;
254 if (smpte.subframes <= 0) {
256 if (SMPTE_IS_ZERO(smpte)) {
257 smpte.negative = true;
261 decrement( smpte, subframes_per_frame );
262 smpte.subframes = 79;
267 if (SMPTE_IS_ZERO(smpte)) {
268 smpte.negative = false;
275 /** Go to next whole second (frames == 0 or frames == 2) */
277 increment_seconds( Time& smpte, uint32_t subframes_per_frame )
282 frames_floor( smpte );
284 if (smpte.negative) {
285 // Wrap second if on second boundary
286 wrap = increment(smpte, subframes_per_frame);
287 // Go to lowest absolute frame value
288 seconds_floor( smpte );
289 if (SMPTE_IS_ZERO(smpte)) {
290 smpte.negative = false;
293 // Go to highest possible frame in this second
294 switch ((int)ceil(smpte.rate)) {
309 // Increment by one frame
310 wrap = increment( smpte, subframes_per_frame );
317 /** Go to lowest (absolute) frame value in this second
318 * Doesn't care about positive/negative */
320 seconds_floor( Time& smpte )
323 frames_floor( smpte );
325 // Go to lowest possible frame in this second
326 switch ((int)ceil(smpte.rate)) {
335 if ((smpte.minutes % 10) && (smpte.seconds == 0)) {
344 if (SMPTE_IS_ZERO(smpte)) {
345 smpte.negative = false;
350 /** Go to next whole minute (seconds == 0, frames == 0 or frames == 2) */
352 increment_minutes( Time& smpte, uint32_t subframes_per_frame )
357 frames_floor( smpte );
359 if (smpte.negative) {
360 // Wrap if on minute boundary
361 wrap = increment_seconds( smpte, subframes_per_frame );
362 // Go to lowest possible value in this minute
363 minutes_floor( smpte );
365 // Go to highest possible second
367 // Wrap minute by incrementing second
368 wrap = increment_seconds( smpte, subframes_per_frame );
375 /** Go to lowest absolute value in this minute */
377 minutes_floor( Time& smpte )
379 // Go to lowest possible second
381 // Go to lowest possible frame
382 seconds_floor( smpte );
384 if (SMPTE_IS_ZERO(smpte)) {
385 smpte.negative = false;
390 /** Go to next whole hour (minute = 0, second = 0, frame = 0) */
392 increment_hours( Time& smpte, uint32_t subframes_per_frame )
399 if (smpte.negative) {
400 // Wrap if on hour boundary
401 wrap = increment_minutes( smpte, subframes_per_frame );
402 // Go to lowest possible value in this hour
403 hours_floor( smpte );
406 wrap = increment_minutes( smpte, subframes_per_frame );
413 /** Go to lowest absolute value in this hour */
415 hours_floor( Time& smpte )
422 if (SMPTE_IS_ZERO(smpte)) {
423 smpte.negative = false;