mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
extend/fix/improve operator overloads and methods for Timecode::BBT_Time
This commit is contained in:
parent
9ea43bd5ad
commit
176cdecd03
2 changed files with 56 additions and 11 deletions
|
|
@ -29,15 +29,17 @@ using namespace Timecode;
|
||||||
1/Nth divisions are integer numbers of ticks.
|
1/Nth divisions are integer numbers of ticks.
|
||||||
|
|
||||||
1920 has many factors, though going up to 3840 gets a couple more.
|
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;
|
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,
|
/* NOTE: this does not construct a BBT time in a canonical form,
|
||||||
in that beats may be a very large number, and bars will
|
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);
|
assert (dbeats >= 0);
|
||||||
|
|
|
||||||
|
|
@ -22,26 +22,31 @@
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
#include "timecode/visibility.h"
|
#include "timecode/visibility.h"
|
||||||
|
|
||||||
namespace Timecode {
|
namespace Timecode {
|
||||||
|
|
||||||
/** Bar, Beat, Tick Time (i.e. Tempo-Based Time) */
|
/** 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;
|
static const double ticks_per_beat;
|
||||||
|
|
||||||
uint32_t bars;
|
/* note that it is illegal for BBT_Time to have bars==0 or
|
||||||
uint32_t beats;
|
* beats==0. The "neutral" or "default" value is 1|1|0
|
||||||
uint32_t ticks;
|
*/
|
||||||
|
|
||||||
BBT_Time ()
|
int32_t bars;
|
||||||
: bars (1), beats (1), ticks (0) {}
|
int32_t beats;
|
||||||
|
int32_t ticks;
|
||||||
|
|
||||||
BBT_Time (uint32_t ba, uint32_t be, uint32_t t)
|
struct IllegalBBTTimeException : public std::exception {
|
||||||
: bars (ba), beats (be), ticks (t) {}
|
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 {
|
bool operator< (const BBT_Time& other) const {
|
||||||
return bars < other.bars ||
|
return bars < other.bars ||
|
||||||
|
|
@ -74,6 +79,37 @@ struct LIBTIMECODE_API BBT_Time {
|
||||||
bool operator!= (const BBT_Time& other) const {
|
bool operator!= (const BBT_Time& other) const {
|
||||||
return bars != other.bars || beats != other.beats || ticks != other.ticks;
|
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;
|
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&
|
inline std::ostream&
|
||||||
print_padded (std::ostream& o, const Timecode::BBT_Time& bbt)
|
print_padded (std::ostream& o, const Timecode::BBT_Time& bbt)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue