diff --git a/libs/temporal/tempo.cc b/libs/temporal/tempo.cc index 9ef3a4e662..7679c0260d 100644 --- a/libs/temporal/tempo.cc +++ b/libs/temporal/tempo.cc @@ -98,9 +98,6 @@ Tempo::Tempo (XMLNode const & node) _superclocks_per_note_type = double_npm_to_scpn (_npm); _end_superclocks_per_note_type = double_npm_to_scpn (_enpm); - _super_note_type_per_second = double_npm_to_snps (_npm); - _end_super_note_type_per_second = double_npm_to_snps (_enpm); - if (!node.get_property (X_("note-type"), _note_type)) { throw failed_constructor (); } @@ -121,14 +118,12 @@ Tempo::set_note_types_per_minute (double npm) { _npm = npm; _superclocks_per_note_type = double_npm_to_scpn (_npm); - _super_note_type_per_second = double_npm_to_snps (_npm); } void Tempo::set_end_npm (double npm) { _enpm = npm; - _end_super_note_type_per_second = double_npm_to_snps (_enpm); _end_superclocks_per_note_type = double_npm_to_scpn (_enpm); } @@ -165,8 +160,6 @@ Tempo::set_state (XMLNode const & node, int /*version*/) _superclocks_per_note_type = double_npm_to_scpn (_npm); _end_superclocks_per_note_type = double_npm_to_scpn (_enpm); - _super_note_type_per_second = double_npm_to_snps (_npm); - _end_super_note_type_per_second = double_npm_to_snps (_enpm); node.get_property (X_("note-type"), _note_type); @@ -589,14 +582,22 @@ TempoPoint::quarters_at_superclock (superclock_t sc) const const superclock_t whole_seconds = sc_delta / superclock_ticks_per_second(); const superclock_t remainder = sc_delta - (whole_seconds * superclock_ticks_per_second()); + /* big number to allow most (fractional) BPMs to be represented as an integer "super note type per second" + * + * It is not required that big_numerator equal superclock_ticks_per_second but since the values in both cases have similar + * desired properties (many, many factors), it doesn't hurt to use the same number. + */ + const superclock_t big_numerator = 508032000; // 2^10 * 3^4 * 5^3 * 7^2 + + uint64_t _super_note_type_per_second = (uint64_t) llround (_npm * big_numerator / 60); + const int64_t supernotes = ((_super_note_type_per_second) * whole_seconds) + muldiv_round (superclock_t (_super_note_type_per_second), remainder, superclock_ticks_per_second()); const int64_t superbeats = muldiv_round (supernotes, 4, (superclock_t) _note_type); /* convert superbeats to beats:ticks */ - int32_t b; - int32_t t; - - Tempo::superbeats_to_beats_ticks (superbeats, b, t); + int32_t b = superbeats / big_numerator; + int64_t remain = superbeats - (b * big_numerator); + int32_t t = PBD::muldiv_round (Temporal::ticks_per_beat, remain, big_numerator); DEBUG_TRACE (DEBUG::TemporalMap, string_compose ("%8 => \nsc %1 delta %9 = %2 secs rem = %3 rem snotes %4 sbeats = %5 => %6 : %7\n", sc, whole_seconds, remainder, supernotes, superbeats, b , t, *this, sc_delta)); @@ -3038,9 +3039,9 @@ std::ostream& std::operator<<(std::ostream& str, Tempo const & t) { if (t.ramped()) { - return str << t.note_types_per_minute() << " .. " << t.end_note_types_per_minute() << " 1/" << t.note_type() << " RAMPED notes per minute [ " << t.super_note_type_per_second() << " => " << t.end_super_note_type_per_second() << " sntpm ] (" << t.superclocks_per_note_type() << " sc-per-1/" << t.note_type() << ')'; + return str << t.note_types_per_minute() << " .. " << t.end_note_types_per_minute() << " 1/" << t.note_type() << " RAMPED notes per minute (" << t.superclocks_per_note_type() << " .. " << t.end_superclocks_per_note_type() << " sc-per-1/" << t.note_type() << ')'; } else { - return str << t.note_types_per_minute() << " 1/" << t.note_type() << " notes per minute [" << t.super_note_type_per_second() << " sntpm] (" << t.superclocks_per_note_type() << " sc-per-1/" << t.note_type() << ')'; + return str << t.note_types_per_minute() << " 1/" << t.note_type() << " notes per minute (" << t.superclocks_per_note_type() << " sc-per-1/" << t.note_type() << ')'; } } diff --git a/libs/temporal/temporal/tempo.h b/libs/temporal/temporal/tempo.h index d5802cd225..5d2a7a5918 100644 --- a/libs/temporal/temporal/tempo.h +++ b/libs/temporal/temporal/tempo.h @@ -161,14 +161,6 @@ class /*LIBTEMPORAL_API*/ Point : public point_hook, public MapOwned { */ class LIBTEMPORAL_API Tempo { - private: - /* beats per minute * big_numerator => rational number expressing (possibly fractional) bpm as superbeats-per-minute - * - * It is not required that big_numerator equal superclock_ticks_per_second but since the values in both cases have similar - * desired properties (many, many factors), it doesn't hurt to use the same number. - */ - static const superclock_t big_numerator = 508032000; // 2^10 * 3^4 * 5^3 * 7^2 - public: enum Type { Ramped, @@ -189,8 +181,6 @@ class LIBTEMPORAL_API Tempo { , _enpm (npm) , _superclocks_per_note_type (double_npm_to_scpn (npm)) , _end_superclocks_per_note_type (double_npm_to_scpn (npm)) - , _super_note_type_per_second (double_npm_to_snps (npm)) - , _end_super_note_type_per_second (double_npm_to_snps (npm)) , _note_type (note_type) , _locked_to_meter (false) , _continuing (false) @@ -201,8 +191,6 @@ class LIBTEMPORAL_API Tempo { , _enpm (npm) , _superclocks_per_note_type (double_npm_to_scpn (npm)) , _end_superclocks_per_note_type (double_npm_to_scpn (enpm)) - , _super_note_type_per_second (double_npm_to_snps (npm)) - , _end_super_note_type_per_second (double_npm_to_snps (enpm)) , _note_type (note_type) , _locked_to_meter (false) , _continuing (false) @@ -240,12 +228,6 @@ class LIBTEMPORAL_API Tempo { return end_superclocks_per_note_type (4); } - static void superbeats_to_beats_ticks (int64_t sb, int32_t& b, int32_t& t) { - b = sb / big_numerator; - int64_t remain = sb - (b * big_numerator); - t = PBD::muldiv_round (Temporal::ticks_per_beat, remain, big_numerator); - } - bool locked_to_meter () const { return _locked_to_meter; } void set_locked_to_meter (bool yn) { _locked_to_meter = yn; } @@ -274,21 +256,15 @@ class LIBTEMPORAL_API Tempo { _continuing != other._continuing; } - uint64_t super_note_type_per_second() const { return _super_note_type_per_second; } - uint64_t end_super_note_type_per_second() const { return _end_super_note_type_per_second; } - protected: double _npm; double _enpm; superclock_t _superclocks_per_note_type; superclock_t _end_superclocks_per_note_type; - uint64_t _super_note_type_per_second; - uint64_t _end_super_note_type_per_second; int8_t _note_type; bool _locked_to_meter; /* XXX name has unclear meaning with nutempo */ bool _continuing; - static inline uint64_t double_npm_to_snps (double npm) { return (uint64_t) llround (npm * big_numerator / 60); } static inline superclock_t double_npm_to_scpn (double npm) { return (superclock_t) llround ((60./npm) * superclock_ticks_per_second()); } protected: