From 5204a24291f074c9f297822d52873c80ce600bd2 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sun, 27 Oct 2024 14:52:29 -0600 Subject: [PATCH] add a new type for AnytTime (BBT_Offset) and make it serializable --- libs/ardour/ardour/types.h | 16 ++++++- libs/ardour/ardour/types_convert.h | 26 +++++++++++ libs/ardour/globals.cc | 70 ++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 2 deletions(-) diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 05ce3cd7be..80169edc13 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -304,6 +304,7 @@ class AnyTime { enum Type { Timecode, BBT, + BBT_Offset, Samples, Seconds }; @@ -311,14 +312,21 @@ class AnyTime { Type type; Timecode::Time timecode; - Temporal::BBT_Time bbt; + union { + Temporal::BBT_Time bbt; + Temporal::BBT_Offset bbt_offset; + }; union { samplecnt_t samples; double seconds; }; - AnyTime() { type = Samples; samples = 0; } + AnyTime () : type (Samples), samples (0) {} + AnyTime (Temporal::BBT_Offset bt) : type (BBT_Offset), bbt_offset (bt) {} + AnyTime (std::string const &); + + std::string str() const; bool operator== (AnyTime const & other) const { if (type != other.type) { return false; } @@ -328,6 +336,8 @@ class AnyTime { return timecode == other.timecode; case BBT: return bbt == other.bbt; + case BBT_Offset: + return bbt_offset == other.bbt_offset; case Samples: return samples == other.samples; case Seconds: @@ -344,6 +354,8 @@ class AnyTime { timecode.seconds != 0 || timecode.frames != 0; case BBT: return bbt.bars != 0 || bbt.beats != 0 || bbt.ticks != 0; + case BBT_Offset: + return bbt_offset.bars != 0 || bbt_offset.beats != 0 || bbt_offset.ticks != 0; case Samples: return samples != 0; case Seconds: diff --git a/libs/ardour/ardour/types_convert.h b/libs/ardour/ardour/types_convert.h index 19b8484589..75f69c199f 100644 --- a/libs/ardour/ardour/types_convert.h +++ b/libs/ardour/ardour/types_convert.h @@ -94,6 +94,32 @@ DEFINE_ENUM_CONVERT(ARDOUR::CueBehavior) DEFINE_ENUM_CONVERT(MusicalMode::Type) +template <> +inline bool to_string (ARDOUR::AnyTime const & at, std::string & str) +{ + str = at.str(); + return true; +} + +template <> +inline bool string_to (std::string const & str, ARDOUR::AnyTime & at) +{ + at = ARDOUR::AnyTime (str); + return true; +} + +template <> +inline std::string to_string (ARDOUR::AnyTime at) +{ + return at.str(); +} + +template <> +inline ARDOUR::AnyTime string_to (std::string const & str) +{ + return ARDOUR::AnyTime (str); +} + template <> inline std::string to_string (ARDOUR::timepos_t val) { diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 8a7c88f7ad..4c0abd5720 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -34,6 +34,8 @@ #include // Needed so that libraptor (included in lrdf) won't complain #include +#include + #include #include #include @@ -84,6 +86,7 @@ #include "pbd/cpus.h" #include "pbd/enumwriter.h" #include "pbd/error.h" +#include "pbd/failed_constructor.h" #include "pbd/file_utils.h" #include "pbd/fpu.h" #include "pbd/id.h" @@ -1074,3 +1077,70 @@ ARDOUR::reset_performance_meters (Session *session) AudioEngine::instance()->current_backend()->dsp_stats[n].queue_reset (); } } + +ARDOUR::AnyTime::AnyTime (std::string const & str) +{ + char c; + std::stringstream ss; + + ss << str; + ss >> c; + + switch (c) { + case 't': + type = Timecode; + if (!Timecode::parse_timecode_format (str.substr (1), timecode)) { + throw failed_constructor (); + } + break; + case 'b': + type = BBT; + ss >> bbt; + break; + case 'B': + type = BBT_Offset; + ss >> bbt_offset; + break; + case 's': + type = Samples; + ss >> samples; + break; + case 'S': + type = Seconds; + ss >> seconds; + break; + default: + throw failed_constructor(); + } +} + +std::string +ARDOUR::AnyTime::str() const +{ + std::stringstream ss; + switch (type) { + case Timecode: + ss << 't'; + ss << timecode; + break; + case BBT: + ss << 'b'; + ss << bbt; + break; + case BBT_Offset: + ss << 'B'; + ss << bbt_offset; + break; + case Samples: + ss << 's'; + ss << samples; + break; + case Seconds: + ss << 'S'; + ss << seconds; + break; + } + + return ss.str (); +} +