From 176cdecd03c9195d12396c0f04b5c375fb9af32e Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 13 Sep 2017 17:12:51 -0400 Subject: [PATCH] extend/fix/improve operator overloads and methods for Timecode::BBT_Time --- libs/timecode/src/bbt_time.cc | 6 ++- libs/timecode/timecode/bbt_time.h | 61 ++++++++++++++++++++++++++----- 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/libs/timecode/src/bbt_time.cc b/libs/timecode/src/bbt_time.cc index 826f0cd91f..8ee6d1a313 100644 --- a/libs/timecode/src/bbt_time.cc +++ b/libs/timecode/src/bbt_time.cc @@ -29,15 +29,17 @@ using namespace Timecode; 1/Nth divisions are integer numbers of ticks. 1920 has many factors, though going up to 3840 gets a couple more. + + This needs to match Evoral::Beats::PPQN */ const double BBT_Time::ticks_per_beat = 1920.0; -BBT_Time::BBT_Time (double dbeats) +BBT_Offset::BBT_Offset (double dbeats) { /* NOTE: this does not construct a BBT time in a canonical form, in that beats may be a very large number, and bars will - always be zero. + always be zero. Hence ... it's a BBT_Offset */ assert (dbeats >= 0); diff --git a/libs/timecode/timecode/bbt_time.h b/libs/timecode/timecode/bbt_time.h index b3ba3a6b57..b42ccf741e 100644 --- a/libs/timecode/timecode/bbt_time.h +++ b/libs/timecode/timecode/bbt_time.h @@ -22,26 +22,31 @@ #include #include #include +#include #include "timecode/visibility.h" namespace Timecode { /** Bar, Beat, Tick Time (i.e. Tempo-Based Time) */ -struct LIBTIMECODE_API BBT_Time { +struct LIBTIMECODE_API BBT_Time +{ static const double ticks_per_beat; - uint32_t bars; - uint32_t beats; - uint32_t ticks; + /* note that it is illegal for BBT_Time to have bars==0 or + * beats==0. The "neutral" or "default" value is 1|1|0 + */ - BBT_Time () - : bars (1), beats (1), ticks (0) {} + int32_t bars; + int32_t beats; + int32_t ticks; - BBT_Time (uint32_t ba, uint32_t be, uint32_t t) - : bars (ba), beats (be), ticks (t) {} + struct IllegalBBTTimeException : public std::exception { + virtual const char* what() const throw() { return "illegal BBT time (bars or beats were zero)"; } + }; - BBT_Time (double beats); + BBT_Time () : bars (1), beats (1), ticks (0) {} + BBT_Time (int32_t ba, uint32_t be, uint32_t t) : bars (ba), beats (be), ticks (t) { if (!bars || !beats) { throw IllegalBBTTimeException(); } } bool operator< (const BBT_Time& other) const { return bars < other.bars || @@ -74,6 +79,37 @@ struct LIBTIMECODE_API BBT_Time { bool operator!= (const BBT_Time& other) const { return bars != other.bars || beats != other.beats || ticks != other.ticks; } + + /* it would be nice to provide operator+(BBT_Time const&) and + * operator-(BBT_Time const&) but this math requires knowledge of the + * meter (time signature) used to define 1 bar, and so cannot be + * carried out with only two BBT_Time values. + */ + + BBT_Time round_to_beat () const { return ticks >= (ticks_per_beat/2) ? BBT_Time (bars, beats+1, 0) : BBT_Time (bars, beats, 0); } + BBT_Time round_down_to_beat () const { return BBT_Time (bars, beats, 0); } + BBT_Time round_up_to_beat () const { return ticks ? BBT_Time (bars, beats+1, 0) : *this; } + + /* cannot implement round_to_bar() without knowing meter (time + * signature) information. + */ +}; + +struct LIBTIMECODE_API BBT_Offset +{ + int32_t bars; + int32_t beats; + int32_t ticks; + + /* this is a variant for which bars==0 and/or beats==0 is legal. It + * represents an offset from a given BBT_Time and is used when doing + * add/subtract operations on a BBT_Time. + */ + + BBT_Offset () : bars (0), beats (0), ticks (0) {} + BBT_Offset (int32_t ba, uint32_t be, uint32_t t) : bars (ba), beats (be), ticks (t) {} + BBT_Offset (BBT_Time const & bbt) : bars (bbt.bars), beats (bbt.beats), ticks (bbt.ticks) {} + BBT_Offset (double beats); }; } @@ -85,6 +121,13 @@ operator<< (std::ostream& o, const Timecode::BBT_Time& bbt) return o; } +inline std::ostream& +operator<< (std::ostream& o, const Timecode::BBT_Offset& bbt) +{ + o << bbt.bars << '|' << bbt.beats << '|' << bbt.ticks; + return o; +} + inline std::ostream& print_padded (std::ostream& o, const Timecode::BBT_Time& bbt) { -- 2.30.2