Clean up libtimecode, make license of bbt_time.h LGPL.

git-svn-id: svn://localhost/ardour2/branches/3.0@8272 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2010-12-14 19:07:50 +00:00
parent 4b861e6039
commit 9882fe9ab0
3 changed files with 142 additions and 143 deletions

View file

@ -1,23 +1,23 @@
/* /*
Copyright (C) 2006 Paul Davis Copyright (C) 2006-2010 Paul Davis
This program is free software; you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published by
by the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or (at your
(at your option) any later version. option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
for more details. License for more details.
You should have received a copy of the GNU General Public License along You should have received a copy of the GNU Lesser General Public License
with this program; if not, write to the Free Software Foundation, Inc., along with this program; if not, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#define Timecode_IS_AROUND_ZERO( sm ) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours) #define Timecode_IS_AROUND_ZERO(sm) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours)
#define Timecode_IS_ZERO( sm ) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours && !(sm.subframes)) #define Timecode_IS_ZERO(sm) (!(sm).frames && !(sm).seconds && !(sm).minutes && !(sm).hours && !(sm.subframes))
#include <math.h> #include <math.h>
@ -33,12 +33,12 @@ float Time::default_rate = 30.0;
* @return true if seconds wrap. * @return true if seconds wrap.
*/ */
Wrap Wrap
increment( Time& timecode, uint32_t subframes_per_frame ) increment (Time& timecode, uint32_t subframes_per_frame)
{ {
Wrap wrap = NONE; Wrap wrap = NONE;
if (timecode.negative) { if (timecode.negative) {
if (Timecode_IS_AROUND_ZERO(timecode) && timecode.subframes) { if (Timecode_IS_AROUND_ZERO (timecode) && timecode.subframes) {
// We have a zero transition involving only subframes // We have a zero transition involving only subframes
timecode.subframes = subframes_per_frame - timecode.subframes; timecode.subframes = subframes_per_frame - timecode.subframes;
timecode.negative = false; timecode.negative = false;
@ -46,14 +46,14 @@ increment( Time& timecode, uint32_t subframes_per_frame )
} }
timecode.negative = false; timecode.negative = false;
wrap = decrement( timecode, subframes_per_frame ); wrap = decrement (timecode, subframes_per_frame);
if (!Timecode_IS_ZERO( timecode )) { if (!Timecode_IS_ZERO (timecode)) {
timecode.negative = true; timecode.negative = true;
} }
return wrap; return wrap;
} }
switch ((int)ceil(timecode.rate)) { switch ((int)ceil (timecode.rate)) {
case 24: case 24:
if (timecode.frames == 23) { if (timecode.frames == 23) {
timecode.frames = 0; timecode.frames = 0;
@ -67,27 +67,27 @@ increment( Time& timecode, uint32_t subframes_per_frame )
} }
break; break;
case 30: case 30:
if (timecode.drop) { if (timecode.drop) {
if (timecode.frames == 29) { if (timecode.frames == 29) {
if ( ((timecode.minutes + 1) % 10) && (timecode.seconds == 59) ) { if (((timecode.minutes + 1) % 10) && (timecode.seconds == 59)) {
timecode.frames = 2; timecode.frames = 2;
} }
else { else {
timecode.frames = 0; timecode.frames = 0;
} }
wrap = SECONDS; wrap = SECONDS;
} }
} else { } else {
if (timecode.frames == 29) { if (timecode.frames == 29) {
timecode.frames = 0; timecode.frames = 0;
wrap = SECONDS; wrap = SECONDS;
} }
} }
break; break;
case 60: case 60:
if (timecode.frames == 59) { if (timecode.frames == 59) {
timecode.frames = 0; timecode.frames = 0;
wrap = SECONDS; wrap = SECONDS;
} }
break; break;
@ -119,24 +119,23 @@ increment( Time& timecode, uint32_t subframes_per_frame )
* Realtime safe. * Realtime safe.
* @return true if seconds wrap. */ * @return true if seconds wrap. */
Wrap Wrap
decrement( Time& timecode, uint32_t subframes_per_frame ) decrement (Time& timecode, uint32_t subframes_per_frame)
{ {
Wrap wrap = NONE; Wrap wrap = NONE;
if (timecode.negative || Timecode_IS_ZERO (timecode)) {
if (timecode.negative || Timecode_IS_ZERO(timecode)) {
timecode.negative = false; timecode.negative = false;
wrap = increment( timecode, subframes_per_frame ); wrap = increment (timecode, subframes_per_frame);
timecode.negative = true; timecode.negative = true;
return wrap; return wrap;
} else if (Timecode_IS_AROUND_ZERO(timecode) && timecode.subframes) { } else if (Timecode_IS_AROUND_ZERO (timecode) && timecode.subframes) {
// We have a zero transition involving only subframes // We have a zero transition involving only subframes
timecode.subframes = subframes_per_frame - timecode.subframes; timecode.subframes = subframes_per_frame - timecode.subframes;
timecode.negative = true; timecode.negative = true;
return SECONDS; return SECONDS;
} }
switch ((int)ceil(timecode.rate)) { switch ((int)ceil (timecode.rate)) {
case 24: case 24:
if (timecode.frames == 0) { if (timecode.frames == 0) {
timecode.frames = 23; timecode.frames = 23;
@ -150,27 +149,27 @@ decrement( Time& timecode, uint32_t subframes_per_frame )
} }
break; break;
case 30: case 30:
if (timecode.drop) { if (timecode.drop) {
if ((timecode.minutes % 10) && (timecode.seconds == 0)) { if ((timecode.minutes % 10) && (timecode.seconds == 0)) {
if (timecode.frames <= 2) { if (timecode.frames <= 2) {
timecode.frames = 29; timecode.frames = 29;
wrap = SECONDS; wrap = SECONDS;
} }
} else if (timecode.frames == 0) { } else if (timecode.frames == 0) {
timecode.frames = 29; timecode.frames = 29;
wrap = SECONDS; wrap = SECONDS;
} }
} else { } else {
if (timecode.frames == 0) { if (timecode.frames == 0) {
timecode.frames = 29; timecode.frames = 29;
wrap = SECONDS; wrap = SECONDS;
} }
} }
break; break;
case 60: case 60:
if (timecode.frames == 0) { if (timecode.frames == 0) {
timecode.frames = 59; timecode.frames = 59;
wrap = SECONDS; wrap = SECONDS;
} }
break; break;
@ -195,7 +194,7 @@ decrement( Time& timecode, uint32_t subframes_per_frame )
timecode.frames--; timecode.frames--;
} }
if (Timecode_IS_ZERO( timecode )) { if (Timecode_IS_ZERO (timecode)) {
timecode.negative = false; timecode.negative = false;
} }
@ -203,12 +202,12 @@ decrement( Time& timecode, uint32_t subframes_per_frame )
} }
/** Go to lowest absolute subframe value in this frame (set to 0 :-) ) */ /** Go to lowest absolute subframe value in this frame (set to 0 :-)) */
void void
frames_floor( Time& timecode ) frames_floor (Time& timecode)
{ {
timecode.subframes = 0; timecode.subframes = 0;
if (Timecode_IS_ZERO(timecode)) { if (Timecode_IS_ZERO (timecode)) {
timecode.negative = false; timecode.negative = false;
} }
} }
@ -216,14 +215,14 @@ frames_floor( Time& timecode )
/** Increment @a timecode by one subframe */ /** Increment @a timecode by one subframe */
Wrap Wrap
increment_subframes( Time& timecode, uint32_t subframes_per_frame ) increment_subframes (Time& timecode, uint32_t subframes_per_frame)
{ {
Wrap wrap = NONE; Wrap wrap = NONE;
if (timecode.negative) { if (timecode.negative) {
timecode.negative = false; timecode.negative = false;
wrap = decrement_subframes( timecode, subframes_per_frame ); wrap = decrement_subframes (timecode, subframes_per_frame);
if (!Timecode_IS_ZERO(timecode)) { if (!Timecode_IS_ZERO (timecode)) {
timecode.negative = true; timecode.negative = true;
} }
return wrap; return wrap;
@ -232,7 +231,7 @@ increment_subframes( Time& timecode, uint32_t subframes_per_frame )
timecode.subframes++; timecode.subframes++;
if (timecode.subframes >= subframes_per_frame) { if (timecode.subframes >= subframes_per_frame) {
timecode.subframes = 0; timecode.subframes = 0;
increment( timecode, subframes_per_frame ); increment (timecode, subframes_per_frame);
return FRAMES; return FRAMES;
} }
return NONE; return NONE;
@ -241,31 +240,31 @@ increment_subframes( Time& timecode, uint32_t subframes_per_frame )
/** Decrement @a timecode by one subframe */ /** Decrement @a timecode by one subframe */
Wrap Wrap
decrement_subframes( Time& timecode, uint32_t subframes_per_frame ) decrement_subframes (Time& timecode, uint32_t subframes_per_frame)
{ {
Wrap wrap = NONE; Wrap wrap = NONE;
if (timecode.negative) { if (timecode.negative) {
timecode.negative = false; timecode.negative = false;
wrap = increment_subframes( timecode, subframes_per_frame ); wrap = increment_subframes (timecode, subframes_per_frame);
timecode.negative = true; timecode.negative = true;
return wrap; return wrap;
} }
if (timecode.subframes <= 0) { if (timecode.subframes <= 0) {
timecode.subframes = 0; timecode.subframes = 0;
if (Timecode_IS_ZERO(timecode)) { if (Timecode_IS_ZERO (timecode)) {
timecode.negative = true; timecode.negative = true;
timecode.subframes = 1; timecode.subframes = 1;
return FRAMES; return FRAMES;
} else { } else {
decrement( timecode, subframes_per_frame ); decrement (timecode, subframes_per_frame);
timecode.subframes = 79; timecode.subframes = 79;
return FRAMES; return FRAMES;
} }
} else { } else {
timecode.subframes--; timecode.subframes--;
if (Timecode_IS_ZERO(timecode)) { if (Timecode_IS_ZERO (timecode)) {
timecode.negative = false; timecode.negative = false;
} }
return NONE; return NONE;
@ -275,24 +274,24 @@ decrement_subframes( Time& timecode, uint32_t subframes_per_frame )
/** Go to next whole second (frames == 0 or frames == 2) */ /** Go to next whole second (frames == 0 or frames == 2) */
Wrap Wrap
increment_seconds( Time& timecode, uint32_t subframes_per_frame ) increment_seconds (Time& timecode, uint32_t subframes_per_frame)
{ {
Wrap wrap = NONE; Wrap wrap = NONE;
// Clear subframes // Clear subframes
frames_floor( timecode ); frames_floor (timecode);
if (timecode.negative) { if (timecode.negative) {
// Wrap second if on second boundary // Wrap second if on second boundary
wrap = increment(timecode, subframes_per_frame); wrap = increment (timecode, subframes_per_frame);
// Go to lowest absolute frame value // Go to lowest absolute frame value
seconds_floor( timecode ); seconds_floor (timecode);
if (Timecode_IS_ZERO(timecode)) { if (Timecode_IS_ZERO (timecode)) {
timecode.negative = false; timecode.negative = false;
} }
} else { } else {
// Go to highest possible frame in this second // Go to highest possible frame in this second
switch ((int)ceil(timecode.rate)) { switch ((int)ceil (timecode.rate)) {
case 24: case 24:
timecode.frames = 23; timecode.frames = 23;
break; break;
@ -308,7 +307,7 @@ increment_seconds( Time& timecode, uint32_t subframes_per_frame )
} }
// Increment by one frame // Increment by one frame
wrap = increment( timecode, subframes_per_frame ); wrap = increment (timecode, subframes_per_frame);
} }
return wrap; return wrap;
@ -318,31 +317,30 @@ increment_seconds( Time& timecode, uint32_t subframes_per_frame )
/** Go to lowest (absolute) frame value in this second /** Go to lowest (absolute) frame value in this second
* Doesn't care about positive/negative */ * Doesn't care about positive/negative */
void void
seconds_floor( Time& timecode ) seconds_floor (Time& timecode)
{ {
// Clear subframes // Clear subframes
frames_floor( timecode ); frames_floor (timecode);
// Go to lowest possible frame in this second // Go to lowest possible frame in this second
switch ((int)ceil(timecode.rate)) { switch ((int)ceil (timecode.rate)) {
case 24: case 24:
case 25: case 25:
case 30: case 30:
case 60: case 60:
if (!(timecode.drop)) { if (!(timecode.drop)) {
timecode.frames = 0; timecode.frames = 0;
} else { } else {
if ((timecode.minutes % 10) && (timecode.seconds == 0)) {
if ((timecode.minutes % 10) && (timecode.seconds == 0)) { timecode.frames = 2;
timecode.frames = 2;
} else { } else {
timecode.frames = 0; timecode.frames = 0;
} }
} }
break; break;
} }
if (Timecode_IS_ZERO(timecode)) { if (Timecode_IS_ZERO (timecode)) {
timecode.negative = false; timecode.negative = false;
} }
} }
@ -350,23 +348,23 @@ seconds_floor( Time& timecode )
/** Go to next whole minute (seconds == 0, frames == 0 or frames == 2) */ /** Go to next whole minute (seconds == 0, frames == 0 or frames == 2) */
Wrap Wrap
increment_minutes( Time& timecode, uint32_t subframes_per_frame ) increment_minutes (Time& timecode, uint32_t subframes_per_frame)
{ {
Wrap wrap = NONE; Wrap wrap = NONE;
// Clear subframes // Clear subframes
frames_floor( timecode ); frames_floor (timecode);
if (timecode.negative) { if (timecode.negative) {
// Wrap if on minute boundary // Wrap if on minute boundary
wrap = increment_seconds( timecode, subframes_per_frame ); wrap = increment_seconds (timecode, subframes_per_frame);
// Go to lowest possible value in this minute // Go to lowest possible value in this minute
minutes_floor( timecode ); minutes_floor (timecode);
} else { } else {
// Go to highest possible second // Go to highest possible second
timecode.seconds = 59; timecode.seconds = 59;
// Wrap minute by incrementing second // Wrap minute by incrementing second
wrap = increment_seconds( timecode, subframes_per_frame ); wrap = increment_seconds (timecode, subframes_per_frame);
} }
return wrap; return wrap;
@ -375,14 +373,14 @@ increment_minutes( Time& timecode, uint32_t subframes_per_frame )
/** Go to lowest absolute value in this minute */ /** Go to lowest absolute value in this minute */
void void
minutes_floor( Time& timecode ) minutes_floor (Time& timecode)
{ {
// Go to lowest possible second // Go to lowest possible second
timecode.seconds = 0; timecode.seconds = 0;
// Go to lowest possible frame // Go to lowest possible frame
seconds_floor( timecode ); seconds_floor (timecode);
if (Timecode_IS_ZERO(timecode)) { if (Timecode_IS_ZERO (timecode)) {
timecode.negative = false; timecode.negative = false;
} }
} }
@ -390,21 +388,21 @@ minutes_floor( Time& timecode )
/** Go to next whole hour (minute = 0, second = 0, frame = 0) */ /** Go to next whole hour (minute = 0, second = 0, frame = 0) */
Wrap Wrap
increment_hours( Time& timecode, uint32_t subframes_per_frame ) increment_hours (Time& timecode, uint32_t subframes_per_frame)
{ {
Wrap wrap = NONE; Wrap wrap = NONE;
// Clear subframes // Clear subframes
frames_floor(timecode); frames_floor (timecode);
if (timecode.negative) { if (timecode.negative) {
// Wrap if on hour boundary // Wrap if on hour boundary
wrap = increment_minutes( timecode, subframes_per_frame ); wrap = increment_minutes (timecode, subframes_per_frame);
// Go to lowest possible value in this hour // Go to lowest possible value in this hour
hours_floor( timecode ); hours_floor(timecode);
} else { } else {
timecode.minutes = 59; timecode.minutes = 59;
wrap = increment_minutes( timecode, subframes_per_frame ); wrap = increment_minutes (timecode, subframes_per_frame);
} }
return wrap; return wrap;
@ -413,14 +411,14 @@ increment_hours( Time& timecode, uint32_t subframes_per_frame )
/** Go to lowest absolute value in this hour */ /** Go to lowest absolute value in this hour */
void void
hours_floor( Time& timecode ) hours_floor(Time& timecode)
{ {
timecode.minutes = 0; timecode.minutes = 0;
timecode.seconds = 0; timecode.seconds = 0;
timecode.frames = 0; timecode.frames = 0;
timecode.subframes = 0; timecode.subframes = 0;
if (Timecode_IS_ZERO(timecode)) { if (Timecode_IS_ZERO (timecode)) {
timecode.negative = false; timecode.negative = false;
} }
} }

View file

@ -1,20 +1,19 @@
/* /*
Copyright (C) 2002-2009 Paul Davis Copyright (C) 2002-2010 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU 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.
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 Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser 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_bbt_time_h__ #ifndef __timecode_bbt_time_h__

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2006 Paul Davis Copyright (C) 2006-2010 Paul Davis
This program is free software; you can redistribute it and/or modify it 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 under the terms of the GNU Lesser General Public License as published
@ -16,8 +16,8 @@
675 Mass Ave, Cambridge, MA 02139, USA. 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef __ardour_timecode_h__ #ifndef __timecode_time_h__
#define __ardour_timecode_h__ #define __timecode_time_h__
#include <ostream> #include <ostream>
#include <inttypes.h> #include <inttypes.h>
@ -33,17 +33,17 @@ enum Wrap {
}; };
struct Time { struct Time {
bool negative; bool negative;
uint32_t hours; uint32_t hours;
uint32_t minutes; uint32_t minutes;
uint32_t seconds; uint32_t seconds;
uint32_t frames; ///< Timecode frames (not audio samples) uint32_t frames; ///< Timecode frames (not audio samples)
uint32_t subframes; ///< Typically unused uint32_t subframes; ///< Typically unused
float rate; ///< Frame rate of this Time float rate; ///< Frame rate of this Time
static float default_rate;///< Rate to use for default constructor static float default_rate; ///< Rate to use for default constructor
bool drop; ///< Whether this Time uses dropframe Timecode bool drop; ///< Whether this Time uses dropframe Timecode
Time(float a_rate = default_rate) { Time (float a_rate = default_rate) {
negative = false; negative = false;
hours = 0; hours = 0;
minutes = 0; minutes = 0;
@ -53,30 +53,32 @@ struct Time {
rate = a_rate; rate = a_rate;
} }
std::ostream& print (std::ostream& ostr) const { std::ostream& print (std::ostream& ostr) const {
if (negative) { if (negative) {
ostr << '-'; ostr << '-';
} }
ostr << hours << ':' << minutes << ':' << seconds << ':' << frames << '.' << subframes << " @" << rate << (drop ? " drop" : " nondrop"); ostr << hours << ':' << minutes << ':' << seconds << ':'
<< frames << '.' << subframes
<< " @" << rate << (drop ? " drop" : " nondrop");
return ostr; return ostr;
} }
}; };
Wrap increment( Time& timecode, uint32_t ); Wrap increment (Time& timecode, uint32_t);
Wrap decrement( Time& timecode, uint32_t ); Wrap decrement (Time& timecode, uint32_t);
Wrap increment_subframes( Time& timecode, uint32_t ); Wrap increment_subframes (Time& timecode, uint32_t);
Wrap decrement_subframes( Time& timecode, uint32_t ); Wrap decrement_subframes (Time& timecode, uint32_t);
Wrap increment_seconds( Time& timecode, uint32_t ); Wrap increment_seconds (Time& timecode, uint32_t);
Wrap increment_minutes( Time& timecode, uint32_t ); Wrap increment_minutes (Time& timecode, uint32_t);
Wrap increment_hours( Time& timecode, uint32_t ); Wrap increment_hours (Time& timecode, uint32_t);
void frames_floor( Time& timecode ); void frames_floor (Time& timecode);
void seconds_floor( Time& timecode ); void seconds_floor (Time& timecode);
void minutes_floor( Time& timecode ); void minutes_floor (Time& timecode);
void hours_floor( Time& timecode ); void hours_floor (Time& timecode);
} // namespace Timecode } // namespace Timecode
std::ostream& operator<<(std::ostream& ostr, const Timecode::Time& t); std::ostream& operator<< (std::ostream& ostr, const Timecode::Time& t);
#endif // __ardour_timecode_h__ #endif // __timecode_time_h__