View Issue Details

IDProjectCategoryView StatusLast Update
0009242ardourbugspublic2023-05-18 09:16
Reportergonsolo Assigned To 
PrioritynormalSeveritycrashReproducibilityalways
Status newResolutionopen 
PlatformUbuntuOSLinuxOS Version(any)
Product Version7.3 
Summary0009242: Crash when playing and jumping forward/backward with the mouse
DescriptionArdour crashes with a SIGSEG while playing and trying to jump around with the mouse.


Steps To Reproduce1. Open my session
2. Play
3. Jump in the timeline via mouse clicks
4. Crash
Additional InformationGit commit: 31a3c3c6f30dbcc6a9f0b4a3b8c935c6ea428ae4

Stack trace:

#0 0x00007ffff7e85118 in Temporal::TempoMetric::reftime() const (this=this@entry=0x7fffffffb6f0) at ../libs/temporal/tempo.cc:663
0000001 0x00005555562bbd76 in Temporal::TempoMetric::round_to_bar(Temporal::BBT_Time const&) const (bbt=..., this=0x7fffffffb6f0)
    at ../libs/temporal/temporal/tempo.h:502
#2 Temporal::TempoMap::round_to_bar(Temporal::BBT_Argument const&) const (bbt=..., this=0x55555801b950) at ../libs/temporal/temporal/tempo.h:859
#3 MiniTimeline::render(Cairo::RefPtr<Cairo::Context> const&, _cairo_rectangle*) (this=0x5555572794e8, ctx=<optimized out>)
    at ../gtk2_ardour/mini_timeline.cc:609
0000004 0x00007ffff6bf9f68 in CairoWidget::on_expose_event(_GdkEventExpose*) (this=0x5555572794e8, ev=0x7fffffffbe20)
    at ../libs/gtkmm2ext/cairo_widget.cc:207
0000005 0x00007ffff5e61459 in Gtk::Widget_Class::expose_event_callback(_GtkWidget*, _GdkEventExpose*) (self=0x5555573e9ee0, p0=0x7fffffffbe20)
    at /build/gtkmm2.4-uNdZjB/gtkmm2.4-2.24.5/gtk/gtkmm/widget.cc:4479
#6 0x00007ffff63434d7 in _gtk_marshal_BOOLEAN__BOXED
    (closure=0x5555572fea20, return_value=0x7fffffffba20, n_param_values=<optimized out>, param_values=0x7fffffffba80, invocation_hint=<optimized out>, marshal_data=<optimized out>) at /build/gtk+2.0-AJUhhk/gtk+2.0-2.24.33/debian/build/shared/gtk/gtkmarshalers.c:84
#7 0x00007ffff6999f50 in g_closure_invoke
    (closure=0x5555572fea20, return_value=0x7fffffffba20, n_param_values=2, param_values=0x7fffffffba80, invocation_hint=0x7fffffffba00)
    at ../../../gobject/gclosure.c:832
0000008 0x00007ffff69c7e95 in signal_emit_unlocked_R.isra.0
    (node=<optimized out>, detail=detail@entry=0, instance=instance@entry=0x5555573e9ee0, emission_return=emission_return@entry=0x7fffffffbb90, instance_and_params=instance_and_params@entry=0x7fffffffba80) at ../../../gobject/gsignal.c:3835
0000009 0x00007ffff69b7b86 in g_signal_emit_valist
    (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffbc40)
    at ../../../gobject/gsignal.c:3559
0000010 0x00007ffff69b8403 in g_signal_emit (instance=instance@entry=0x5555573e9ee0, signal_id=<optimized out>, detail=detail@entry=0)
    at ../../../gobject/gsignal.c:3606
0000011 0x00007ffff646f024 in gtk_widget_event_internal (widget=0x5555573e9ee0, event=0x7fffffffbe20) at ../../../../gtk/gtkwidget.c:5017
0000012 0x00007ffff63431c3 in IA__gtk_main_do_event (event=0x7fffffffbe20) at ../../../../gtk/gtkmain.c:1637
0000013 IA__gtk_main_do_event (event=<optimized out>) at ../../../../gtk/gtkmain.c:1517
0000014 0x00007ffff67d94c9 in _gdk_window_process_updates_recurse (window=window@entry=0x55557d989000, expose_region=expose_region@entry=0x555576cca300)
    at ../../../../gdk/gdkwindow.c:5479
#15 0x00007ffff67d9449 in _gdk_window_process_updates_recurse (expose_region=0x555576cca300, window=0x55557d989000)
    at ../../../../gdk/gdkregion-generic.c:1545
0000016 _gdk_window_process_updates_recurse (window=window@entry=0x555558dba360, expose_region=expose_region@entry=0x5555837000f0)
    at ../../../../gdk/gdkwindow.c:5452
#17 0x00007ffff67d9449 in _gdk_window_process_updates_recurse (expose_region=0x5555837000f0, window=0x555558dba360)
    at ../../../../gdk/gdkregion-generic.c:1545
0000018 _gdk_window_process_updates_recurse (window=0x5555572a5c60, expose_region=0x555583880990) at ../../../../gdk/gdkwindow.c:5452
0000019 0x00007ffff67cf155 in gdk_window_process_updates_internal (window=0x5555572a5c60) at ../../../../gdk/gdkregion-generic.c:1545
0000020 0x00007ffff67cf8e8 in IA__gdk_window_process_all_updates () at ../../../../gdk/gdkwindow.c:5752
0000021 0x00007ffff67cf98d in gdk_window_update_idle (data=<optimized out>) at ../../../../gdk/gdkwindow.c:5372

Bisected commits (one bad, one skipped because it didn't compile):

commit 2c7bfa9eadf75e9d71e864886bf15ed3fadcbb45 (refs/bisect/bad)
Author: Paul Davis <paul@linuxaudiosystems.com>
Date: Sun Feb 12 12:02:33 2023 -0700

    require use of BBT_Argument as both parameter and return type from most methods (GUI edition)

commit 259499fc5f9a349a9c729947813bdb5231fbdaa9 (refs/bisect/skip-259499fc5f9a349a9c729947813bdb5231fbdaa9)
Author: Paul Davis <paul@linuxaudiosystems.com>
Date: Sun Feb 12 12:02:22 2023 -0700

    require use of BBT_Argument as both parameter and return type from most methods (libs edition)
TagsNo tags attached.

Activities

gonsolo

2023-02-17 08:40

reporter   ~0027391

Link to session (that crashes at startup but works with 7.3): https://drive.google.com/file/d/1cJAgviVrdxMPJOKR__kJYVSUeN_cGYkX/view?usp=share_link

gonsolo

2023-02-25 22:37

reporter   ~0027411

The attached patch make the crash go away (in my private branch, but mostly on top of 3b0a19d30efe12f1cec17b6a02e2b374964faf2b).

The problematic section seems to be in TempoMap::reftime(TempoMetric const &tm) const, and specifically the dynamic_cast:

       if (dynamic_cast<const MusicTimePoint*> (&*pi)) {
0001-Revert-require-use-of-BBT_Argument-as-both-parameter.patch (25,679 bytes)   
From 4cc6372dc3efe86cb919d62d805590c9155a3c14 Mon Sep 17 00:00:00 2001
From: Gon Solo <gonsolo@gmail.com>
Date: Sat, 25 Feb 2023 23:18:40 +0100
Subject: [PATCH] Revert "require use of BBT_Argument as both parameter and
 return type from most methods (libs edition)"

This reverts commit 259499fc5f9a349a9c729947813bdb5231fbdaa9.
---
 libs/ardour/ardour/triggerbox.h               |  6 +-
 libs/ardour/luabindings.cc                    |  4 +-
 libs/ardour/session_time.cc                   |  2 +-
 libs/ardour/session_transport.cc              |  4 +-
 libs/ardour/session_vst.cc                    |  4 +-
 libs/ardour/triggerbox.cc                     | 36 +++++------
 .../control_protocol/basic_ui.cc              |  2 +-
 libs/temporal/tempo.cc                        | 63 +++++--------------
 libs/temporal/temporal/bbt_argument.h         |  2 +-
 libs/temporal/temporal/tempo.h                | 24 ++++---
 libs/temporal/timeline.cc                     |  6 +-
 11 files changed, 57 insertions(+), 96 deletions(-)

diff --git a/libs/ardour/ardour/triggerbox.h b/libs/ardour/ardour/triggerbox.h
index 95981c339d..052c8cbb0e 100644
--- a/libs/ardour/ardour/triggerbox.h
+++ b/libs/ardour/ardour/triggerbox.h
@@ -292,7 +292,7 @@ class LIBARDOUR_API Trigger : public PBD::Stateful {
 	timepos_t current_pos() const;
 	double position_as_fraction() const;
 
-	Temporal::BBT_Argument compute_start (Temporal::TempoMap::SharedPtr const &, samplepos_t start, samplepos_t end, Temporal::BBT_Offset const & q, samplepos_t& start_samples, bool& will_start);
+	Temporal::BBT_Time compute_start (Temporal::TempoMap::SharedPtr const &, samplepos_t start, samplepos_t end, Temporal::BBT_Offset const & q, samplepos_t& start_samples, bool& will_start);
 	virtual timepos_t compute_end (Temporal::TempoMap::SharedPtr const &, Temporal::BBT_Time const &, samplepos_t, Temporal::Beats &) = 0;
 	virtual void start_and_roll_to (samplepos_t start, samplepos_t position, uint32_t cnt) = 0;
 
@@ -337,11 +337,11 @@ class LIBARDOUR_API Trigger : public PBD::Stateful {
 
 
 	bool compute_quantized_transition (samplepos_t start_sample, Temporal::Beats const & start, Temporal::Beats const & end,
-	                                   Temporal::BBT_Argument& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
+	                                   Temporal::BBT_Time& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
 	                                   Temporal::TempoMap::SharedPtr const & tmap, Temporal::BBT_Offset const & q);
 
 	pframes_t compute_next_transition (samplepos_t start_sample, Temporal::Beats const & start, Temporal::Beats const & end, pframes_t nframes,
-	                                   Temporal::BBT_Argument& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
+	                                   Temporal::BBT_Time& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
 	                                   Temporal::TempoMap::SharedPtr const & tmap);
 
 
diff --git a/libs/ardour/luabindings.cc b/libs/ardour/luabindings.cc
index 2d18248eb7..514cd6c053 100644
--- a/libs/ardour/luabindings.cc
+++ b/libs/ardour/luabindings.cc
@@ -799,8 +799,8 @@ LuaBindings::common (lua_State* L)
 		.addFunction ("meter_at_bbt", (Temporal::MeterPoint const& (Temporal::TempoMap::*)(Temporal::BBT_Argument const &) const) &Temporal::TempoMap::meter_at)
 		.addFunction ("meter_at_beats", (Temporal::MeterPoint const& (Temporal::TempoMap::*)(Temporal::Beats const &) const) &Temporal::TempoMap::meter_at)
 
-		.addFunction ("bbt_at", (Temporal::BBT_Argument (Temporal::TempoMap::*)(Temporal::timepos_t const &) const) &Temporal::TempoMap::bbt_at)
-		.addFunction ("bbt_at_beats", (Temporal::BBT_Argument (Temporal::TempoMap::*)(Temporal::Beats const &) const) &Temporal::TempoMap::bbt_at)
+		.addFunction ("bbt_at", (Temporal::BBT_Time (Temporal::TempoMap::*)(Temporal::timepos_t const &) const) &Temporal::TempoMap::bbt_at)
+		.addFunction ("bbt_at_beats", (Temporal::BBT_Time (Temporal::TempoMap::*)(Temporal::Beats const &) const) &Temporal::TempoMap::bbt_at)
 
 #ifdef WITH_SUPERCLOCK_BINDINGS
 		.addFunction ("tempo_at_sc", (Temporal::TempoPoint const& (Temporal::TempoMap::*)(superclock_t) const) &Temporal::TempoMap::tempo_at)
diff --git a/libs/ardour/session_time.cc b/libs/ardour/session_time.cc
index 3501bb6b84..8be19459f0 100644
--- a/libs/ardour/session_time.cc
+++ b/libs/ardour/session_time.cc
@@ -234,7 +234,7 @@ Session::convert_to_samples (AnyTime const & position)
 
 	switch (position.type) {
 	case AnyTime::BBT:
-		return Temporal::superclock_to_samples (TempoMap::use()->superclock_at (BBT_Argument (timepos_t::zero (Temporal::BeatTime), position.bbt)), _current_sample_rate);
+		return Temporal::superclock_to_samples (TempoMap::use()->superclock_at (position.bbt), _current_sample_rate);
 		break;
 
 	case AnyTime::Timecode:
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index 502e4fa339..2e9713f226 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -2120,8 +2120,8 @@ Session::flush_cue_recording ()
 	_locations->clear_cue_markers (_last_roll_location, _transport_sample);
 
 	while (TriggerBox::cue_records.read (&cr, 1) == 1) {
-		BBT_Argument bbt = tmap->bbt_at (timepos_t (cr.when));
-		bbt = BBT_Argument (bbt.reference(), bbt.round_up_to_bar ());
+		BBT_Time bbt = tmap->bbt_at (timepos_t (cr.when));
+		bbt = bbt.round_up_to_bar ();
 
 		const timepos_t when (tmap->quarters_at (bbt));
 
diff --git a/libs/ardour/session_vst.cc b/libs/ardour/session_vst.cc
index ea1b0a2288..697a1e3b8c 100644
--- a/libs/ardour/session_vst.cc
+++ b/libs/ardour/session_vst.cc
@@ -200,14 +200,14 @@ intptr_t Session::vst_callback (
 				newflags |= (kVstTimeSigValid);
 			}
 			if ((value & (kVstPpqPosValid)) || (value & (kVstBarsValid))) {
-				Temporal::BBT_Argument bbt;
+				Temporal::BBT_Time bbt;
 
 				try {
 					bbt = tmap->bbt_at (timepos_t (now));
 					bbt.beats = 1;
 					bbt.ticks = 0;
 					/* exact quarter note */
-					double ppqBar = DoubleableBeats (tmap->quarters_at (BBT_Argument (bbt))).to_double ();
+					double ppqBar = DoubleableBeats (tmap->quarters_at (bbt)).to_double ();
 					/* quarter note at sample position (not rounded to note subdivision) */
 					double ppqPos = DoubleableBeats (tmap->quarters_at_sample (now)).to_double();
 					if (value & (kVstPpqPosValid)) {
diff --git a/libs/ardour/triggerbox.cc b/libs/ardour/triggerbox.cc
index f13d4575c7..73d1bfedb9 100644
--- a/libs/ardour/triggerbox.cc
+++ b/libs/ardour/triggerbox.cc
@@ -929,18 +929,18 @@ Trigger::process_state_requests (BufferSet& bufs, pframes_t dest_offset)
 	}
 }
 
-Temporal::BBT_Argument
+Temporal::BBT_Time
 Trigger::compute_start (Temporal::TempoMap::SharedPtr const & tmap, samplepos_t start, samplepos_t end, Temporal::BBT_Offset const & q, samplepos_t& start_samples, bool& will_start)
 {
 	Temporal::Beats start_beats (tmap->quarters_at (timepos_t (start)));
 	Temporal::Beats end_beats (tmap->quarters_at (timepos_t (end)));
 
-	Temporal::BBT_Argument t_bbt;
+	Temporal::BBT_Time t_bbt;
 	Temporal::Beats t_beats;
 
 	if (!compute_quantized_transition (start, start_beats, end_beats, t_bbt, t_beats, start_samples, tmap, q)) {
 		will_start = false;
-		return Temporal::BBT_Argument ();
+		return Temporal::BBT_Time ();
 	}
 
 	will_start = true;
@@ -949,7 +949,7 @@ Trigger::compute_start (Temporal::TempoMap::SharedPtr const & tmap, samplepos_t
 
 bool
 Trigger::compute_quantized_transition (samplepos_t start_sample, Temporal::Beats const & start_beats, Temporal::Beats const & end_beats,
-                                       Temporal::BBT_Argument& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
+                                       Temporal::BBT_Time& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
                                        Temporal::TempoMap::SharedPtr const & tmap, Temporal::BBT_Offset const & q)
 {
 	/* XXX need to use global grid here is quantization == zero */
@@ -958,7 +958,7 @@ Trigger::compute_quantized_transition (samplepos_t start_sample, Temporal::Beats
 	 * quantization, the next time for a transition.
 	 */
 
-	Temporal::BBT_Argument possible_bbt;
+	Temporal::BBT_Time possible_bbt;
 	Temporal::Beats possible_beats;
 	samplepos_t possible_samples;
 
@@ -978,7 +978,7 @@ Trigger::compute_quantized_transition (samplepos_t start_sample, Temporal::Beats
 	} else {
 
 		possible_bbt = tmap->bbt_at (timepos_t (start_beats));
-		possible_bbt = Temporal::BBT_Argument (possible_bbt.reference(), possible_bbt.round_up_to_bar ());
+		possible_bbt = possible_bbt.round_up_to_bar ();
 		/* bars are 1-based; 'every 4 bars' means 'on bar 1, 5, 9, ...' */
 		possible_bbt.bars = 1 + ((possible_bbt.bars-1) / q.bars * q.bars);
 		possible_beats = tmap->quarters_at (possible_bbt);
@@ -1004,7 +1004,7 @@ Trigger::compute_quantized_transition (samplepos_t start_sample, Temporal::Beats
 
 pframes_t
 Trigger::compute_next_transition (samplepos_t start_sample, Temporal::Beats const & start, Temporal::Beats const & end, pframes_t nframes,
-                                  Temporal::BBT_Argument& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
+                                  Temporal::BBT_Time& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
                                   Temporal::TempoMap::SharedPtr const & tmap)
 {
 	using namespace Temporal;
@@ -1072,7 +1072,7 @@ Trigger::maybe_compute_next_transition (samplepos_t start_sample, Temporal::Beat
 		return;
 	}
 
-	Temporal::BBT_Argument transition_bbt;
+	Temporal::BBT_Time transition_bbt;
 	TempoMap::SharedPtr tmap (TempoMap::use());
 
 	if (!compute_next_transition (start_sample, start, end, nframes, transition_bbt, transition_beats, transition_samples, tmap)) {
@@ -1449,15 +1449,13 @@ AudioTrigger::compute_end (Temporal::TempoMap::SharedPtr const & tmap, Temporal:
            _beatcnt : the expected duration of the trigger, based on analysis of its tempo .. can be overridden by the user later
 	*/
 
-	const Temporal::BBT_Argument transition_bba (timepos_t::zero (Temporal::BeatTime), transition_bbt);
-
-	samplepos_t end_by_follow_length = tmap->sample_at (tmap->bbt_walk (transition_bba, _follow_length));
+	samplepos_t end_by_follow_length = tmap->sample_at (tmap->bbt_walk(transition_bbt, _follow_length));
 	samplepos_t end_by_data_length = transition_sample + (data.length - _start_offset);
 	/* this could still blow up if the data is less than 1 tick long, but
 	   we should handle that elsewhere.
 	*/
 	const Temporal::Beats bc (Temporal::Beats::from_double (_beatcnt));
-	samplepos_t end_by_beatcnt = tmap->sample_at (tmap->bbt_walk (transition_bba, Temporal::BBT_Offset (0, bc.get_beats(), bc.get_ticks())));
+	samplepos_t end_by_beatcnt = tmap->sample_at (tmap->bbt_walk(transition_bbt, Temporal::BBT_Offset (0, bc.get_beats(), bc.get_ticks())));
 
 	DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 SO %9 @ %2 / %3 / %4 ends: FL %5 (from %6) BC %7 DL %8\n",
 	                                              index(), transition_sample, transition_beats, transition_bbt,
@@ -2317,10 +2315,8 @@ MIDITrigger::start_and_roll_to (samplepos_t start_pos, samplepos_t end_position,
 timepos_t
 MIDITrigger::compute_end (Temporal::TempoMap::SharedPtr const & tmap, Temporal::BBT_Time const & transition_bbt, samplepos_t, Temporal::Beats & effective_length)
 {
-	const Temporal::BBT_Argument transition_bba (timepos_t::zero(Temporal::BeatTime), transition_bbt);
-
-	Temporal::Beats end_by_follow_length = tmap->quarters_at (tmap->bbt_walk (transition_bba, _follow_length));
-	Temporal::Beats end_by_data_length = tmap->quarters_at (tmap->bbt_walk (transition_bba, Temporal::BBT_Offset (0, data_length.get_beats(), data_length.get_ticks())));
+	Temporal::Beats end_by_follow_length = tmap->quarters_at (tmap->bbt_walk (transition_bbt, _follow_length));
+	Temporal::Beats end_by_data_length = tmap->quarters_at (tmap->bbt_walk (transition_bbt, Temporal::BBT_Offset (0, data_length.get_beats(), data_length.get_ticks())));
 
 	DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 ends: TB %2 FL %3 EBFL %4 DL %5 EBDL %6 tbbt %7 fl %8\n",
 	                                              index(), transition_beats, _follow_length, end_by_follow_length, data_length, end_by_data_length, transition_bbt, _follow_length));
@@ -2330,10 +2326,10 @@ MIDITrigger::compute_end (Temporal::TempoMap::SharedPtr const & tmap, Temporal::
 
 		if (internal_use_follow_length()) {
 			final_beat = end_by_follow_length;
-			effective_length = tmap->bbtwalk_to_quarters (transition_bba, _follow_length);
+			effective_length = tmap->bbtwalk_to_quarters (transition_bbt, _follow_length);
 		} else {
 			final_beat = end_by_data_length;
-			effective_length = tmap->bbtwalk_to_quarters (transition_bba, Temporal::BBT_Offset (0, data_length.get_beats(), data_length.get_ticks()));
+			effective_length = tmap->bbtwalk_to_quarters (transition_bbt, Temporal::BBT_Offset (0, data_length.get_beats(), data_length.get_ticks()));
 		}
 
 	} else {
@@ -3196,7 +3192,7 @@ TriggerBox::fast_forward (CueEvents const & cues, samplepos_t transport_position
 	CueEvents::const_reverse_iterator c = cues.rbegin ();
 	samplepos_t pos = c->time;
 	TriggerPtr trig;
-	Temporal::BBT_Argument start_bbt;
+	Temporal::BBT_Time start_bbt;
 	samplepos_t start_samples;
 	Temporal::Beats effective_length;
 	bool will_start;
@@ -3348,7 +3344,7 @@ TriggerBox::fast_forward (CueEvents const & cues, samplepos_t transport_position
 
 	if (start_samples < transport_position) {
 		samplepos_t s = start_samples;
-		BBT_Argument ns = start_bbt;
+		BBT_Time ns = start_bbt;
 		const BBT_Offset step (0, effective_length.get_beats(), effective_length.get_ticks());
 
 		do {
diff --git a/libs/ctrl-interface/control_protocol/basic_ui.cc b/libs/ctrl-interface/control_protocol/basic_ui.cc
index d6b0fe027a..ddf47470e9 100644
--- a/libs/ctrl-interface/control_protocol/basic_ui.cc
+++ b/libs/ctrl-interface/control_protocol/basic_ui.cc
@@ -588,7 +588,7 @@ void
 BasicUI::jump_by_bars (int bars, LocateTransportDisposition ltd)
 {
 	TempoMap::SharedPtr tmap (TempoMap::fetch());
-	Temporal::BBT_Argument bbt (tmap->bbt_at (timepos_t (session->transport_sample())));
+	Temporal::BBT_Time bbt (tmap->bbt_at (timepos_t (session->transport_sample())));
 
 	bbt.bars += bars;
 	if (bbt.bars < 0) {
diff --git a/libs/temporal/tempo.cc b/libs/temporal/tempo.cc
index 996806d04d..65d33cbe64 100644
--- a/libs/temporal/tempo.cc
+++ b/libs/temporal/tempo.cc
@@ -636,36 +636,7 @@ MeterPoint::get_state () const
 	return base;
 }
 
-timepos_t
-TempoMetric::reftime() const
-{
-	return _tempo->map().reftime (*this);
-}
-
-timepos_t
-TempoMap::reftime (TempoMetric const &tm) const
-{
-	Points::const_iterator pi;
-
-	if (tm.meter().sclock() < tm.tempo().sclock()) {
-		pi = _points.s_iterator_to (*(static_cast<const Point*> (&tm.meter())));
-	} else {
-		pi = _points.s_iterator_to (*(static_cast<const Point*> (&tm.tempo())));
-	}
-
-	/* Walk backwards through points to find a BBT markers, or the start */
-
-	while (pi != _points.begin()) {
-		if (dynamic_cast<const MusicTimePoint*> (&*pi)) {
-			break;
-		}
-		--pi;
-	}
-
-	return timepos_t (pi->sclock());
-}
-
-Temporal::BBT_Argument
+Temporal::BBT_Time
 TempoMetric::bbt_at (timepos_t const & pos) const
 {
 	if (pos.is_beats()) {
@@ -704,9 +675,7 @@ TempoMetric::bbt_at (timepos_t const & pos) const
 
 	DEBUG_TRACE (DEBUG::TemporalMap, string_compose ("BBT offset from %3 @ %1: %2\n", (_tempo->beats() < _meter->beats() ?  _meter->bbt() : _tempo->bbt()), bbt_offset,
 	                                                 (_tempo->beats() < _meter->beats() ? "meter" : "tempo")));
-	timepos_t ref (std::min (_meter->sclock(), _tempo->sclock()));
-
-	return BBT_Argument (ref, _meter->bbt_add (reference_point->bbt(), bbt_offset));
+	return _meter->bbt_add (reference_point->bbt(), bbt_offset);
 }
 
 superclock_t
@@ -1696,7 +1665,7 @@ TempoMap::remove_meter (MeterPoint const & mp, bool with_reset)
 	}
 }
 
-Temporal::BBT_Argument
+Temporal::BBT_Time
 TempoMap::bbt_at (timepos_t const & pos) const
 {
 	if (pos.is_beats()) {
@@ -1705,20 +1674,16 @@ TempoMap::bbt_at (timepos_t const & pos) const
 	return bbt_at (pos.superclocks());
 }
 
-Temporal::BBT_Argument
+Temporal::BBT_Time
 TempoMap::bbt_at (superclock_t s) const
 {
-	TempoMetric metric (metric_at (s));
-	timepos_t ref (std::min (metric.tempo().sclock(), metric.meter().sclock()));
-	return BBT_Argument (ref, metric.bbt_at (timepos_t::from_superclock (s)));
+	return metric_at (s).bbt_at (timepos_t::from_superclock (s));
 }
 
-Temporal::BBT_Argument
+Temporal::BBT_Time
 TempoMap::bbt_at (Temporal::Beats const & qn) const
 {
-	TempoMetric metric (metric_at (qn));
-	timepos_t ref (std::min (metric.tempo().sclock(), metric.meter().sclock()));
-	return BBT_Argument (ref, metric.bbt_at (qn));
+	return metric_at (qn).bbt_at (qn);
 }
 
 #if 0
@@ -1976,7 +1941,7 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
 	TempoPoint const * tp = 0;
 	MeterPoint const * mp = 0;
 	Points::const_iterator p = _points.begin();
-	BBT_Argument bbt;
+	BBT_Time bbt;
 	Beats beats;
 
 	/* Find relevant meter for nominal start point */
@@ -2016,7 +1981,7 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
 		 * in effect at that time.
 		 */
 
-		const BBT_Argument new_bbt (metric.reftime(), metric.meter().round_up_to_beat (bbt));
+		const BBT_Time new_bbt = metric.meter().round_up_to_beat (bbt);
 
 		if (new_bbt != bbt) {
 
@@ -2068,7 +2033,8 @@ TempoMap::get_grid (TempoMapPoints& ret, superclock_t start, superclock_t end, u
 
 		if (bar != bbt) {
 
-			bbt = BBT_Argument (bbt.reference(), bar);
+			bbt = bar;
+
 
 			/* rebuild metric */
 
@@ -2369,7 +2335,7 @@ std::operator<<(std::ostream& str, TempoMapPoint const & tmp)
 	return str;
 }
 
-BBT_Argument
+BBT_Time
 TempoMap::bbt_walk (BBT_Argument const & bbt, BBT_Offset const & o) const
 {
 	BBT_Offset offset (o);
@@ -2383,7 +2349,7 @@ TempoMap::bbt_walk (BBT_Argument const & bbt, BBT_Offset const & o) const
 	/* trivial (and common) case: single tempo, single meter */
 
 	if (_tempos.size() == 1 && _meters.size() == 1) {
-		return BBT_Argument (_meters.front().bbt_add (bbt, o));
+		return _meters.front().bbt_add (bbt, o);
 	}
 
 	/* Find tempo,meter pair for bbt, and also for the next tempo and meter
@@ -2489,7 +2455,8 @@ TempoMap::bbt_walk (BBT_Argument const & bbt, BBT_Offset const & o) const
 		start.ticks %= ticks_per_beat;
 	}
 
-	return BBT_Argument (metric.reftime(), start);
+
+	return start;
 }
 
 Temporal::Beats
diff --git a/libs/temporal/temporal/bbt_argument.h b/libs/temporal/temporal/bbt_argument.h
index f6adeb4af9..8213f160f8 100644
--- a/libs/temporal/temporal/bbt_argument.h
+++ b/libs/temporal/temporal/bbt_argument.h
@@ -33,7 +33,7 @@ struct LIBTEMPORAL_API BBT_Argument : public BBT_Time
 	BBT_Argument (Temporal::timepos_t const & r) : BBT_Time (), _reference (r) {}
 	BBT_Argument (Temporal::timepos_t const & r, int32_t B, int32_t b, int32_t t) : BBT_Time (B, b, t), _reference (r) {}
 
-	explicit BBT_Argument (BBT_Time const & bbt) : BBT_Time (bbt),  _reference (Temporal::timepos_t (Temporal::BeatTime)) {}
+	/*explicit*/ BBT_Argument (BBT_Time const & bbt) : BBT_Time (bbt),  _reference (Temporal::timepos_t (Temporal::BeatTime)) {}
 	BBT_Argument (Temporal::timepos_t const & r, BBT_Time const & bbt) : BBT_Time (bbt),  _reference (r) {}
 
 	Temporal::timepos_t reference() const { return _reference; }
diff --git a/libs/temporal/temporal/tempo.h b/libs/temporal/temporal/tempo.h
index 3545839dea..dde1ac45dd 100644
--- a/libs/temporal/temporal/tempo.h
+++ b/libs/temporal/temporal/tempo.h
@@ -471,8 +471,6 @@ class LIBTEMPORAL_API TempoMetric
 	TempoMetric (TempoPoint const & t, MeterPoint const & m) : _tempo (&t), _meter (&m) {}
 	virtual ~TempoMetric () {}
 
-	timepos_t reftime() const;
-
 	TempoPoint const & tempo() const { return *_tempo; }
 	MeterPoint const & meter() const { return *_meter; }
 
@@ -486,7 +484,7 @@ class LIBTEMPORAL_API TempoMetric
 	superclock_t superclock_at (Beats const & qn) const { return _tempo->superclock_at (qn); }
 	samplepos_t  sample_at (Beats const & qn) const { return _tempo->sample_at (qn); }
 	Beats        quarters_at (BBT_Time const & bbt) const { return _meter->quarters_at (bbt); }
-	BBT_Argument     bbt_at (Beats const & beats) const { return BBT_Argument (reftime(), _meter->bbt_at (beats)); }
+	BBT_Time     bbt_at (Beats const & beats) const { return _meter->bbt_at (beats); }
 
 	superclock_t superclocks_per_note_type () const { return _tempo->superclocks_per_note_type (); }
 	superclock_t end_superclocks_per_note_type () const {return _tempo->end_superclocks_per_note_type (); }
@@ -497,9 +495,9 @@ class LIBTEMPORAL_API TempoMetric
 	int note_type () const { return _tempo->note_type(); }
 	int divisions_per_bar () const { return _meter->divisions_per_bar(); }
 	int note_value() const { return _meter->note_value(); }
-	BBT_Argument   bbt_add (BBT_Time const & bbt, BBT_Offset const & add) const { return BBT_Argument (reftime(), _meter->bbt_add (bbt, add)); }
-	BBT_Argument   bbt_subtract (BBT_Time const & bbt, BBT_Offset const & sub) const { return BBT_Argument (reftime(), _meter->bbt_subtract (bbt, sub)); }
-	BBT_Argument round_to_bar (BBT_Time const & bbt) const { return BBT_Argument (reftime(), _meter->round_to_bar (bbt)); }
+	BBT_Time   bbt_add (BBT_Time const & bbt, BBT_Offset const & add) const { return _meter->bbt_add (bbt, add); }
+	BBT_Time   bbt_subtract (BBT_Time const & bbt, BBT_Offset const & sub) const { return _meter->bbt_subtract (bbt, sub); }
+	BBT_Time round_to_bar (BBT_Time const & bbt) const { return _meter->round_to_bar (bbt); }
 	Beats to_quarters (BBT_Offset const & bbo) const { return _meter->to_quarters (bbo); }
 
 	/* combination methods that require both tempo and meter information */
@@ -522,7 +520,7 @@ class LIBTEMPORAL_API TempoMetric
 		return int_div_round (superclocks_per_note_type_at_superclock (sc) * _tempo->note_type(), (int64_t) _meter->note_value());
 	}
 
-	BBT_Argument bbt_at (timepos_t const &) const;
+	BBT_Time bbt_at (timepos_t const &) const;
 	superclock_t superclock_at (BBT_Time const &) const;
 
 	samplepos_t samples_per_bar (samplecnt_t sr) const {
@@ -855,12 +853,12 @@ class /*LIBTEMPORAL_API*/ TempoMap : public PBD::StatefulDestructible
 	LIBTEMPORAL_API double quarters_per_minute_at (timepos_t const & pos) const;
 
 	/* convenience function */
-	LIBTEMPORAL_API BBT_Argument round_to_bar (BBT_Argument const & bbt) const {
-		return metric_at (bbt).round_to_bar (bbt);
+	LIBTEMPORAL_API BBT_Time round_to_bar (BBT_Argument const & bbt) const {
+		return metric_at (bbt).meter().round_to_bar (bbt);
 	}
 
-	LIBTEMPORAL_API BBT_Argument bbt_at (timepos_t const &) const;
-	LIBTEMPORAL_API BBT_Argument bbt_at (Beats const &) const;
+	LIBTEMPORAL_API BBT_Time bbt_at (timepos_t const &) const;
+	LIBTEMPORAL_API BBT_Time bbt_at (Beats const &) const;
 
 	LIBTEMPORAL_API	Beats quarters_at (BBT_Argument const &) const;
 	LIBTEMPORAL_API	Beats quarters_at (timepos_t const &) const;
@@ -886,7 +884,7 @@ class /*LIBTEMPORAL_API*/ TempoMap : public PBD::StatefulDestructible
 
 	LIBTEMPORAL_API	Temporal::timecnt_t convert_duration (Temporal::timecnt_t const & duration, Temporal::timepos_t const &, Temporal::TimeDomain domain) const;
 
-	LIBTEMPORAL_API	BBT_Argument bbt_walk (BBT_Argument const &, BBT_Offset const &) const;
+	LIBTEMPORAL_API	BBT_Time bbt_walk (BBT_Argument const &, BBT_Offset const &) const;
 
 	LIBTEMPORAL_API	void get_grid (TempoMapPoints & points, superclock_t start, superclock_t end, uint32_t bar_mod = 0, uint32_t beat_div = 1) const;
 	LIBTEMPORAL_API	uint32_t count_bars (Beats const & start, Beats const & end) const;
@@ -945,7 +943,7 @@ class /*LIBTEMPORAL_API*/ TempoMap : public PBD::StatefulDestructible
 
 	void copy_points (TempoMap const & other);
 
-	BBT_Argument bbt_at (superclock_t sc) const;
+	BBT_Time bbt_at (superclock_t sc) const;
 
 	template<typename T, typename T1> struct const_traits {
 		typedef Points::const_iterator iterator_type;
diff --git a/libs/temporal/timeline.cc b/libs/temporal/timeline.cc
index 07f1c6d462..2c2798e2e1 100644
--- a/libs/temporal/timeline.cc
+++ b/libs/temporal/timeline.cc
@@ -664,7 +664,7 @@ timepos_t::earlier (Temporal::BBT_Offset const & offset) const
 	TempoMap::SharedPtr tm (TempoMap::use());
 
 	if (is_superclock()) {
-		return timepos_t (tm->superclock_at (BBT_Argument (*this, tm->bbt_walk (BBT_Argument (*this, tm->bbt_at (*this)), -offset))));
+		return timepos_t (tm->superclock_at (tm->bbt_walk (tm->bbt_at (*this), -offset)));
 	}
 
 	return timepos_t (tm->bbtwalk_to_quarters (beats(), -offset));
@@ -763,7 +763,7 @@ timepos_t::shift_earlier (Temporal::BBT_Offset const & offset)
 	TempoMap::SharedPtr tm (TempoMap::use());
 
 	if (is_superclock()) {
-		v = build (false, (tm->superclock_at (tm->bbt_walk (BBT_Argument (*this, tm->bbt_at (*this)), -offset))));
+		v = build (false, (tm->superclock_at (tm->bbt_walk (tm->bbt_at (*this), -offset))));
 	} else {
 		v = build (true, tm->bbtwalk_to_quarters (beats(), -offset).to_ticks());
 	}
@@ -780,7 +780,7 @@ timepos_t::operator+= (Temporal::BBT_Offset const & offset)
 	if (is_beats()) {
 		v = build (true, tm->bbtwalk_to_quarters (beats(), offset).to_ticks());
 	} else {
-		v = build (false, tm->superclock_at (tm->bbt_walk (BBT_Argument (*this, tm->bbt_at (*this)), offset)));
+		v = build (false, tm->superclock_at (tm->bbt_walk (tm->bbt_at (*this), offset)));
 	}
 
 	return *this;
-- 
2.37.2

gonsolo

2023-05-18 09:16

reporter   ~0027660

This seems to be fixed with the latest Temporal fixes. Please close.

Issue History

Date Modified Username Field Change
2023-02-16 11:22 gonsolo New Issue
2023-02-17 08:40 gonsolo Note Added: 0027391
2023-02-25 22:37 gonsolo Note Added: 0027411
2023-02-25 22:37 gonsolo File Added: 0001-Revert-require-use-of-BBT_Argument-as-both-parameter.patch
2023-05-18 09:16 gonsolo Note Added: 0027660