From 6f095b91ce75d7aef43ba47976a4a3c9d8657b23 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 13 Feb 2023 17:04:13 -0700 Subject: [PATCH] tempo map: add data structure and methods for (fast?) lookup tables As of this commit, none of the data structures are used. --- libs/temporal/tempo.cc | 83 ++++++++++++++++++++++++++++++++++ libs/temporal/temporal/tempo.h | 29 ++++++++++++ 2 files changed, 112 insertions(+) diff --git a/libs/temporal/tempo.cc b/libs/temporal/tempo.cc index 0d0a3ed887..0df814cb45 100644 --- a/libs/temporal/tempo.cc +++ b/libs/temporal/tempo.cc @@ -3424,6 +3424,89 @@ TempoMap::write_copy() return _map_mgr.write_copy(); } +void +TempoMap::drop_lookup_table (){ + + superclock_beat_lookup_table.clear (); + beat_superclock_lookup_table.clear (); + beat_bbt_lookup_table.clear (); + superclock_bbt_lookup_table.clear (); +} + +Temporal::Beats +TempoMap::beat_lookup (superclock_t sc, bool& found) const +{ + LookupTable::const_iterator i = superclock_beat_lookup_table.find (sc); + if (i == superclock_beat_lookup_table.end()) { + found = false; + return Beats();; + } + found = true; + return Temporal::Beats::ticks (i->second); +} + +superclock_t +TempoMap::superclock_lookup (Temporal::Beats const & b, bool& found) const +{ + LookupTable::const_iterator i = beat_superclock_lookup_table.find (b.to_ticks()); + if (i == beat_superclock_lookup_table.end()) { + found = false; + return 0; + } + found = true; + return i->second; +} + +BBT_Time +TempoMap::bbt_lookup (Temporal::Beats const & b, bool& found) const +{ + LookupTable::const_iterator i = beat_bbt_lookup_table.find (b.to_ticks()); + if (i == beat_bbt_lookup_table.end()) { + found = false; + return BBT_Time (); + } + found = true; + return BBT_Time::from_integer (i->second); +} + +BBT_Time +TempoMap::bbt_lookup (superclock_t sc, bool& found) const +{ + LookupTable::const_iterator i = superclock_bbt_lookup_table.find (sc); + if (i == superclock_bbt_lookup_table.end()) { + found = false; + return BBT_Time (); + } + found = true; + return BBT_Time::from_integer (i->second); +} + +/* see tempo.h comments about why this is const */ +void +TempoMap::superclock_to_beat_store (superclock_t sc, Temporal::Beats const & b) const +{ + superclock_beat_lookup_table[sc] = b.to_ticks(); +} + +/* see tempo.h comments about why this is const */ +void +TempoMap::beat_to_superclock_store (Temporal::Beats const & b, superclock_t sc) const +{ + beat_superclock_lookup_table[b.to_ticks()] = sc; +} + +void +TempoMap::superclock_to_bbt_store (superclock_t sc, BBT_Time const & bbt) const +{ + superclock_bbt_lookup_table[sc] = bbt.as_integer (); +} + +void +TempoMap::beat_to_bbt_store (Temporal::Beats const & b, BBT_Time const & bbt) const +{ + beat_bbt_lookup_table[b.to_ticks()] = bbt.as_integer (); +} + int TempoMap::update (TempoMap::WritableSharedPtr m) { diff --git a/libs/temporal/temporal/tempo.h b/libs/temporal/temporal/tempo.h index cf73c8a9ba..3545839dea 100644 --- a/libs/temporal/temporal/tempo.h +++ b/libs/temporal/temporal/tempo.h @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -1086,6 +1087,34 @@ class /*LIBTEMPORAL_API*/ TempoMap : public PBD::StatefulDestructible int parse_tempo_state_3x (const XMLNode& node, LegacyTempoState& lts); int parse_meter_state_3x (const XMLNode& node, LegacyMeterState& lts); int set_state_3x (XMLNode const &); + + typedef std::unordered_map LookupTable; + + mutable LookupTable superclock_beat_lookup_table; + mutable LookupTable beat_superclock_lookup_table; + mutable LookupTable beat_bbt_lookup_table; + mutable LookupTable superclock_bbt_lookup_table; + + friend class TempoPoint; + friend class MeterPoint; + friend class TempoMetric; + Temporal::Beats beat_lookup (superclock_t, bool& found) const; + superclock_t superclock_lookup (Temporal::Beats const &, bool& found) const; + + Temporal::BBT_Time bbt_lookup (superclock_t, bool & found) const; + Temporal::BBT_Time bbt_lookup (Temporal::Beats const & b, bool & found) const; + + /* These are not really const, but the lookup tables are marked mutable + * to allow time domain conversions to store their results while being + * marked const (which is more semantically correct). + */ + + void superclock_to_beat_store (superclock_t, Temporal::Beats const &) const; + void beat_to_superclock_store (Temporal::Beats const &, superclock_t) const;; + void beat_to_bbt_store (Temporal::Beats const &, Temporal::BBT_Time const &) const;; + void superclock_to_bbt_store (superclock_t, Temporal::BBT_Time const &) const;; + + void drop_lookup_table (); }; class LIBTEMPORAL_API TempoCommand : public Command {