/* 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 #include #include #include "timecode/visibility.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_2997000, timecode_2997000drop, timecode_30, timecode_30drop, timecode_5994, timecode_60 }; struct LIBTIMECODE_API 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 double rate; ///< Frame rate of this Time static double default_rate; ///< Rate to use for default constructor bool drop; ///< Whether this Time uses dropframe Timecode Time (double a_rate = default_rate) { negative = false; hours = 0; minutes = 0; seconds = 0; frames = 0; subframes = 0; rate = a_rate; drop = (lrintf(100.f * (float)a_rate) == (long)2997); } 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 LIBTIMECODE_API increment (Time& timecode, uint32_t); Wrap LIBTIMECODE_API decrement (Time& timecode, uint32_t); Wrap LIBTIMECODE_API increment_subframes (Time& timecode, uint32_t); Wrap LIBTIMECODE_API decrement_subframes (Time& timecode, uint32_t); Wrap LIBTIMECODE_API increment_seconds (Time& timecode, uint32_t); Wrap LIBTIMECODE_API increment_minutes (Time& timecode, uint32_t); Wrap LIBTIMECODE_API increment_hours (Time& timecode, uint32_t); void LIBTIMECODE_API frames_floor (Time& timecode); void LIBTIMECODE_API seconds_floor (Time& timecode); void LIBTIMECODE_API minutes_floor (Time& timecode); void LIBTIMECODE_API hours_floor (Time& timecode); double LIBTIMECODE_API timecode_to_frames_per_second(TimecodeFormat const t); bool LIBTIMECODE_API timecode_has_drop_frames(TimecodeFormat const t); std::string LIBTIMECODE_API timecode_format_name (TimecodeFormat const t); std::string LIBTIMECODE_API timecode_format_time (Timecode::Time const timecode); std::string LIBTIMECODE_API timecode_format_sampletime ( int64_t sample, double sample_frame_rate, double timecode_frames_per_second, bool timecode_drop_frames ); bool LIBTIMECODE_API parse_timecode_format(std::string tc, Timecode::Time &TC); void LIBTIMECODE_API 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 */, uint32_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 LIBTIMECODE_API 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 */, uint32_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 extern LIBTIMECODE_API std::ostream& operator<< (std::ostream& ostr, const Timecode::Time& t); #endif // __timecode_time_h__