From b9de15d2850e1a2f4ae6d9390bacd09e1e354730 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sun, 20 Feb 2022 09:20:47 -0700 Subject: [PATCH] triggerbox: split apart semantics of WaitingToStop This allows for a different quantization to be used when WaitingToSwitch, used when we explicitly start a different Trigger. When "just stopping" we continue to use 1 bar quantization; when switching to a different Trigger we use the quantization of the next Trigger --- libs/ardour/ardour/triggerbox.h | 14 ++++++++++++-- libs/ardour/enums.cc | 1 + libs/ardour/triggerbox.cc | 29 +++++++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/libs/ardour/ardour/triggerbox.h b/libs/ardour/ardour/triggerbox.h index 602c125dfc..d460346897 100644 --- a/libs/ardour/ardour/triggerbox.h +++ b/libs/ardour/ardour/triggerbox.h @@ -69,6 +69,10 @@ typedef uint32_t color_t; LIBARDOUR_API std::string cue_marker_name (int32_t); +class Trigger; + +typedef boost::shared_ptr TriggerPtr; + class LIBARDOUR_API Trigger : public PBD::Stateful { public: enum State { @@ -97,6 +101,12 @@ class LIBARDOUR_API Trigger : public PBD::Stateful { * transition to Stopping and then Stopped. */ WaitingToStop, + /* a Trigger in this state is delivering data during calls to ::run(), but + * is waiting for the next occurence of another Trigger's quantization to occur when it will + * transition to Stopping and then Stopped (and be followed by + * the other Trigger. + */ + WaitingToSwitch, /* a Trigger in this state was Running but noticed that it should stop * during the current call to ::run(). By the end of that call, it will * have transitioned to Stopped. @@ -323,6 +333,7 @@ class LIBARDOUR_API Trigger : public PBD::Stateful { virtual void jump_start (); virtual void jump_stop (BufferSet& bufs, pframes_t dest_offset); void begin_stop (bool explicit_stop = false); + void begin_switch (TriggerPtr); bool explicitly_stopped() const { return _explicitly_stopped; } @@ -409,6 +420,7 @@ class LIBARDOUR_API Trigger : public PBD::Stateful { samplepos_t expected_end_sample; Temporal::BBT_Offset _start_quantization; + Temporal::BBT_Offset _nxt_quantization; std::atomic _pending; std::atomic last_property_generation; @@ -421,8 +433,6 @@ class LIBARDOUR_API Trigger : public PBD::Stateful { void send_property_change (PBD::PropertyChange pc); }; -typedef boost::shared_ptr TriggerPtr; - class LIBARDOUR_API AudioTrigger : public Trigger { public: AudioTrigger (uint32_t index, TriggerBox&); diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc index 3ecca5ca87..d23f4eca38 100644 --- a/libs/ardour/enums.cc +++ b/libs/ardour/enums.cc @@ -855,6 +855,7 @@ setup_enum_writer () REGISTER_CLASS_ENUM (Trigger, Running); REGISTER_CLASS_ENUM (Trigger, WaitingForRetrigger); REGISTER_CLASS_ENUM (Trigger, WaitingToStop); + REGISTER_CLASS_ENUM (Trigger, WaitingToSwitch); REGISTER_CLASS_ENUM (Trigger, Stopping); REGISTER (_TriggerState); diff --git a/libs/ardour/triggerbox.cc b/libs/ardour/triggerbox.cc index d84da6a9ff..b5e4ffbde3 100644 --- a/libs/ardour/triggerbox.cc +++ b/libs/ardour/triggerbox.cc @@ -695,6 +695,18 @@ Trigger::begin_stop (bool explicit_stop) send_property_change (ARDOUR::Properties::running); } +void +Trigger::begin_switch (TriggerPtr nxt) +{ + /* this is used when we start a tell a currently playing trigger to + stop, but wait for quantization first. + */ + _state = WaitingToSwitch; + _nxt_quantization = nxt->_quantization; + DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 begin_switch() requested state %2\n", index(), enum_2_string (_state))); + send_property_change (ARDOUR::Properties::running); +} + void Trigger::process_state_requests (BufferSet& bufs, pframes_t dest_offset) { @@ -759,6 +771,7 @@ Trigger::process_state_requests (BufferSet& bufs, pframes_t dest_offset) case WaitingToStart: case WaitingToStop: + case WaitingToSwitch: case WaitingForRetrigger: case Stopping: break; @@ -780,6 +793,7 @@ Trigger::process_state_requests (BufferSet& bufs, pframes_t dest_offset) case Stopped: case Stopping: /* theoretically not possible */ case WaitingToStop: + case WaitingToSwitch: case WaitingForRetrigger: /* do nothing */ break; @@ -872,7 +886,13 @@ Trigger::compute_next_transition (samplepos_t start_sample, Temporal::Beats cons /* Clips don't stop on their own quantize; in Live they stop on the Global Quantize setting; we will choose 1 bar (Live's default) for now */ #warning when Global Quantize is implemented, use that instead of '1 bar' here if (_state == WaitingToStop) { + q = BBT_Offset(1,0,0); + + } else if (_state == WaitingToSwitch) { + + q = _nxt_quantization; + } if (!compute_quantized_transition (start_sample, start, end, t_bbt, t_beats, t_samples, tmap, q)) { @@ -882,6 +902,7 @@ Trigger::compute_next_transition (samplepos_t start_sample, Temporal::Beats cons switch (_state) { case WaitingToStop: + case WaitingToSwitch: nframes = t_samples - start_sample; break; @@ -934,6 +955,7 @@ Trigger::maybe_compute_next_transition (samplepos_t start_sample, Temporal::Beat switch (_state) { case WaitingToStop: + case WaitingToSwitch: _state = Stopping; send_property_change (ARDOUR::Properties::running); @@ -1684,6 +1706,7 @@ AudioTrigger::audio_run (BufferSet& bufs, samplepos_t start_sample, samplepos_t return nframes; case Running: case WaitingToStop: + case WaitingToSwitch: case Stopping: /* stuff to do */ break; @@ -2405,6 +2428,7 @@ MIDITrigger::midi_run (BufferSet& bufs, samplepos_t start_sample, samplepos_t en return nframes; case Running: case WaitingToStop: + case WaitingToSwitch: case Stopping: break; } @@ -3644,7 +3668,7 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp _currently_playing = nxt; PropertyChanged (Properties::currently_playing); - } else if (_currently_playing->state() != Trigger::WaitingToStop) { + } else if (_currently_playing->state() != Trigger::WaitingToSwitch) { /* Notice that this condition * leaves the next trigger to @@ -3652,10 +3676,11 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp */ /* but just begin stoppingthe currently playing slot */ - _currently_playing->begin_stop (); + _currently_playing->begin_switch (nxt); DEBUG_TRACE (DEBUG::Triggers, string_compose ("start stop for %1 before switching to %2\n", _currently_playing->index(), nxt->index())); } + } } }