sort-of-a-solution for local TempoMap context in EditingContext

This commit is contained in:
Paul Davis 2025-08-10 20:25:53 -06:00
parent 5c8c7c7814
commit 2312187070
6 changed files with 50 additions and 61 deletions

View file

@ -1516,7 +1516,6 @@ CueEditor::metric_get_bbt (std::vector<ArdourCanvas::Ruler::Mark>& marks, sample
tmap.reset (new Temporal::TempoMap (Temporal::Tempo (120, 4), Temporal::Meter (4, 4))); tmap.reset (new Temporal::TempoMap (Temporal::Tempo (120, 4), Temporal::Meter (4, 4)));
} }
EditingContext::TempoMapScope tms (*this, tmap);
Temporal::TempoMapPoints::const_iterator i; Temporal::TempoMapPoints::const_iterator i;
char buf[64]; char buf[64];

View file

@ -32,3 +32,4 @@ PBD::DebugBits PBD::DEBUG::GUITiming = PBD::new_debug_bit ("guitiming");
PBD::DebugBits PBD::DEBUG::EngineControl = PBD::new_debug_bit ("enginecontrol"); PBD::DebugBits PBD::DEBUG::EngineControl = PBD::new_debug_bit ("enginecontrol");
PBD::DebugBits PBD::DEBUG::GuiStartup = PBD::new_debug_bit ("guistartup"); PBD::DebugBits PBD::DEBUG::GuiStartup = PBD::new_debug_bit ("guistartup");
PBD::DebugBits PBD::DEBUG::TrackDrag = PBD::new_debug_bit ("trackdrag"); PBD::DebugBits PBD::DEBUG::TrackDrag = PBD::new_debug_bit ("trackdrag");
PBD::DebugBits PBD::DEBUG::ScopedTempoMap = PBD::new_debug_bit ("scopedtempomap");

View file

@ -33,6 +33,7 @@ namespace PBD {
extern DebugBits EngineControl; extern DebugBits EngineControl;
extern DebugBits GuiStartup; extern DebugBits GuiStartup;
extern DebugBits TrackDrag; extern DebugBits TrackDrag;
extern DebugBits ScopedTempoMap;
} }
} }

View file

@ -37,6 +37,7 @@
#include "ardour_ui.h" #include "ardour_ui.h"
#include "automation_line.h" #include "automation_line.h"
#include "control_point.h" #include "control_point.h"
#include "debug.h"
#include "edit_note_dialog.h" #include "edit_note_dialog.h"
#include "editing_context.h" #include "editing_context.h"
#include "editing_convert.h" #include "editing_convert.h"
@ -153,6 +154,7 @@ EditingContext::EditingContext (std::string const & name)
, time_line_group (nullptr) , time_line_group (nullptr)
, temporary_zoom_focus_change (false) , temporary_zoom_focus_change (false)
, _dragging_playhead (false) , _dragging_playhead (false)
, local_tempo_map_depth (0)
{ {
using namespace Gtk::Menu_Helpers; using namespace Gtk::Menu_Helpers;
@ -1752,16 +1754,41 @@ EditingContext::snap_relative_time_to_relative_time (timepos_t const & origin, t
} }
void void
EditingContext::start_local_tempo_map (std::shared_ptr<TempoMap> map) EditingContext::start_local_tempo_map (std::shared_ptr<Temporal::TempoMap> map)
{ {
_local_tempo_map = map; _local_tempo_map = map;
local_tempo_map_in ();
DEBUG_TRACE (DEBUG::ScopedTempoMap, string_compose ("%1: starting local tempo scope\n", editor_name()));
} }
void void
EditingContext::end_local_tempo_map () EditingContext::end_local_tempo_map ()
{ {
DEBUG_TRACE (DEBUG::ScopedTempoMap, string_compose ("%1: ending local tempo scope\n", editor_name()));
local_tempo_map_depth = 1;
local_tempo_map_out ();
}
void
EditingContext::local_tempo_map_in () const
{
if (local_tempo_map_depth++ == 0 ) {
DEBUG_TRACE (DEBUG::ScopedTempoMap, string_compose ("%1: in to local tempo %2\n", editor_name(), local_tempo_map_depth));
if (_local_tempo_map) {
Temporal::TempoMap::set (_local_tempo_map);
_local_tempo_map.reset (); _local_tempo_map.reset ();
Temporal::TempoMap::fetch (); }
}
}
void
EditingContext::local_tempo_map_out () const
{
DEBUG_TRACE (DEBUG::ScopedTempoMap, string_compose ("%1: out to local tempo %2\n", editor_name(), local_tempo_map_depth));
if (local_tempo_map_depth && --local_tempo_map_depth == 0) {
DEBUG_TRACE (DEBUG::ScopedTempoMap, string_compose ("%1: done with local tempo, depth now %2\n", editor_name(), local_tempo_map_depth));
Temporal::TempoMap::fetch (); /* get current global map into thread-local pointer */
}
} }
bool bool

View file

@ -87,19 +87,6 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
Temporal::TimeDomain time_domain () const; Temporal::TimeDomain time_domain () const;
struct TempoMapScope {
TempoMapScope (EditingContext& context, std::shared_ptr<Temporal::TempoMap> map)
: ec (context)
{
ec.start_local_tempo_map (map);
ec.ensure_local_tempo_scope ();
}
~TempoMapScope () {
ec.end_local_tempo_map ();
}
EditingContext& ec;
};
DragManager* drags () const { DragManager* drags () const {
return _drags; return _drags;
} }
@ -665,9 +652,10 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
QuantizeDialog* quantize_dialog; QuantizeDialog* quantize_dialog;
friend struct TempoMapScope; friend struct TempoMapScope;
void set_local_tempo_map (std::shared_ptr<Temporal::TempoMap>);
void start_local_tempo_map (std::shared_ptr<Temporal::TempoMap>); void start_local_tempo_map (std::shared_ptr<Temporal::TempoMap>);
void end_local_tempo_map (); void end_local_tempo_map ();
void local_tempo_map_in () const;
void local_tempo_map_out () const;
virtual bool button_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) = 0; virtual bool button_press_handler (ArdourCanvas::Item*, GdkEvent*, ItemType) = 0;
virtual bool button_press_handler_1 (ArdourCanvas::Item*, GdkEvent*, ItemType) = 0; virtual bool button_press_handler_1 (ArdourCanvas::Item*, GdkEvent*, ItemType) = 0;
@ -834,12 +822,20 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider,
bool _dragging_playhead; bool _dragging_playhead;
mutable std::shared_ptr<Temporal::TempoMap> _local_tempo_map; mutable std::shared_ptr<Temporal::TempoMap> _local_tempo_map;
void ensure_local_tempo_scope () const { mutable std::shared_ptr<Temporal::TempoMap> _pre_local_tempo_map;
if (_local_tempo_map) { mutable uint64_t local_tempo_map_depth;
Temporal::TempoMap::set (_local_tempo_map);
struct TempoMapScope {
TempoMapScope (EditingContext const & context)
: ec (context)
{
ec.local_tempo_map_in ();
} }
~TempoMapScope () {
ec.local_tempo_map_out ();
} }
EditingContext const & ec;
};
}; };
#define EC_LOCAL_TEMPO_SCOPE ensure_local_tempo_scope () #define EC_LOCAL_TEMPO_SCOPE TempoMapScope __tms (*this);
#define EC_GIVEN_LOCAL_TEMPO_SCOPE(ec) ec.ensure_local_tempo_scope ()

View file

@ -1481,8 +1481,6 @@ Pianoroll::set_track (std::shared_ptr<ARDOUR::Track> track)
void void
Pianoroll::set_region (std::shared_ptr<ARDOUR::Region> region) Pianoroll::set_region (std::shared_ptr<ARDOUR::Region> region)
{ {
EC_LOCAL_TEMPO_SCOPE;
CueEditor::set_region (region); CueEditor::set_region (region);
if (_visible_pending_region) { if (_visible_pending_region) {
@ -1505,42 +1503,9 @@ Pianoroll::set_region (std::shared_ptr<ARDOUR::Region> region)
r->DropReferences.connect (object_connections, invalidator (*this), std::bind (&Pianoroll::unset, this, false), gui_context()); r->DropReferences.connect (object_connections, invalidator (*this), std::bind (&Pianoroll::unset, this, false), gui_context());
r->PropertyChanged.connect (object_connections, invalidator (*this), std::bind (&Pianoroll::region_prop_change, this, _1), gui_context()); r->PropertyChanged.connect (object_connections, invalidator (*this), std::bind (&Pianoroll::region_prop_change, this, _1), gui_context());
bool provided = false;
std::shared_ptr<Temporal::TempoMap> map;
std::shared_ptr<SMFSource> smf (std::dynamic_pointer_cast<SMFSource> (r->midi_source()));
if (smf) {
map = smf->tempo_map (provided);
}
if (!provided) {
Temporal::TempoMap::SharedPtr tmap (Temporal::TempoMap::use());
if (with_transport_controls) {
/* clip editing, timeline irrelevant, sort of */
if (tmap->n_tempos() == 1 && tmap->n_meters() == 1) {
/* Single entry tempo map, use the values there */
map.reset (new Temporal::TempoMap (tmap->tempo_at (timepos_t (0)), tmap->meter_at (timepos_t (0))));
} else {
map.reset (new Temporal::TempoMap (Temporal::Tempo (120, 4), Temporal::Meter (4, 4)));
}
} else {
/* COPY MAIN SESSION TEMPO MAP? */
Meter m (tmap->meter_at (r->source_position()));
Tempo t (tmap->tempo_at (r->source_position()));
map.reset (new Temporal::TempoMap (t, m));
}
}
{
EditingContext::TempoMapScope tms (*this, map);
/* Compute zoom level to show entire source plus some margin if possible */ /* Compute zoom level to show entire source plus some margin if possible */
zoom_to_show (timecnt_t (timepos_t (max_extents_scale() * max_zoom_extent ().second.samples()))); zoom_to_show (timecnt_t (timepos_t (max_extents_scale() * max_zoom_extent ().second.samples())));
}
bg->display_region (*view); bg->display_region (*view);