modify and extend both Session and TriggerBox API to allow better transport control
This allows a stop transport request to first stop all active triggers and then stop the transport
This commit is contained in:
parent
4b5fbeb455
commit
91a28b78c4
@ -485,7 +485,8 @@ public:
|
||||
double default_play_speed ();
|
||||
void reset_transport_speed (TransportRequestSource origin = TRS_UI);
|
||||
|
||||
void start_transport_from_processor ();
|
||||
void start_transport_from_trigger ();
|
||||
void stop_transport_from_trigger ();
|
||||
void request_transport_speed (double speed, TransportRequestSource origin = TRS_UI);
|
||||
void request_default_play_speed (double speed, TransportRequestSource origin = TRS_UI);
|
||||
void request_transport_speed_nonzero (double, TransportRequestSource origin = TRS_UI);
|
||||
@ -1430,6 +1431,7 @@ private:
|
||||
bool _was_seamless;
|
||||
bool _under_nsm_control;
|
||||
unsigned int _xrun_count;
|
||||
bool transport_started_by_trigger;
|
||||
|
||||
std::string _missing_file_replacement;
|
||||
|
||||
|
@ -454,6 +454,8 @@ class LIBARDOUR_API TriggerBox : public Processor
|
||||
|
||||
static TriggerBoxThread* worker;
|
||||
|
||||
static void start_transport_stop (Session&);
|
||||
|
||||
private:
|
||||
static Temporal::BBT_Offset _assumed_trigger_duration;
|
||||
|
||||
@ -530,7 +532,12 @@ class LIBARDOUR_API TriggerBox : public Processor
|
||||
|
||||
void reload (BufferSet& bufs, int32_t slot, void* ptr);
|
||||
|
||||
PBD::ScopedConnection stop_all_connection;
|
||||
|
||||
static void init_pool();
|
||||
|
||||
static std::atomic<int> active_trigger_boxes;
|
||||
static PBD::Signal0<void> StopAllTriggers;
|
||||
};
|
||||
|
||||
namespace Properties {
|
||||
|
@ -215,6 +215,7 @@ Session::Session (AudioEngine &eng,
|
||||
, _writable (false)
|
||||
, _under_nsm_control (false)
|
||||
, _xrun_count (0)
|
||||
, transport_started_by_trigger (false)
|
||||
, master_wait_end (0)
|
||||
, post_export_sync (false)
|
||||
, post_export_position (0)
|
||||
|
@ -262,6 +262,7 @@ Session::process_routes (pframes_t nframes, bool& need_butler)
|
||||
bool b = false;
|
||||
|
||||
if ((ret = (*i)->roll (nframes, start_sample, end_sample, b)) < 0) {
|
||||
cerr << "ERR1 STOP\n";
|
||||
TFSM_STOP (false, false);
|
||||
return -1;
|
||||
}
|
||||
@ -953,7 +954,11 @@ Session::process_event (SessionEvent* ev)
|
||||
break;
|
||||
|
||||
case SessionEvent::EndRoll:
|
||||
TFSM_STOP (ev->yes_or_no, ev->second_yes_or_no);
|
||||
if (transport_started_by_trigger) {
|
||||
TriggerBox::start_transport_stop (*this);
|
||||
} else {
|
||||
TFSM_STOP (ev->yes_or_no, ev->second_yes_or_no);
|
||||
}
|
||||
break;
|
||||
|
||||
case SessionEvent::SetTransportMaster:
|
||||
@ -988,6 +993,7 @@ Session::process_event (SessionEvent* ev)
|
||||
break;
|
||||
|
||||
case SessionEvent::RangeStop:
|
||||
cerr << "RANGE STOP\n";
|
||||
TFSM_STOP (ev->yes_or_no, false);
|
||||
remove = false;
|
||||
del = false;
|
||||
@ -1571,6 +1577,7 @@ Session::implement_master_strategy ()
|
||||
TFSM_EVENT (TransportFSM::StartTransport);
|
||||
break;
|
||||
case TransportMasterStop:
|
||||
cerr << "MASTER STOP\n";
|
||||
TFSM_STOP (false, false);
|
||||
break;
|
||||
}
|
||||
|
@ -58,10 +58,11 @@
|
||||
#include "ardour/profile.h"
|
||||
#include "ardour/scene_changer.h"
|
||||
#include "ardour/session.h"
|
||||
#include "ardour/tempo.h"
|
||||
#include "ardour/transport_fsm.h"
|
||||
#include "ardour/transport_master.h"
|
||||
#include "ardour/transport_master_manager.h"
|
||||
#include "ardour/tempo.h"
|
||||
#include "ardour/triggerbox.h"
|
||||
#include "ardour/operations.h"
|
||||
#include "ardour/vca.h"
|
||||
#include "ardour/vca_manager.h"
|
||||
@ -446,12 +447,21 @@ Session::stop_transport (bool abort, bool clear_state)
|
||||
|
||||
/** Called from the process thread */
|
||||
void
|
||||
Session::start_transport_from_processor ()
|
||||
Session::start_transport_from_trigger ()
|
||||
{
|
||||
transport_started_by_trigger = true;
|
||||
ENSURE_PROCESS_THREAD;
|
||||
TFSM_ROLL();
|
||||
}
|
||||
|
||||
/** Called from the process thread */
|
||||
void
|
||||
Session::stop_transport_from_trigger ()
|
||||
{
|
||||
ENSURE_PROCESS_THREAD;
|
||||
TFSM_STOP (false, false);
|
||||
}
|
||||
|
||||
/** Called from the process thread */
|
||||
void
|
||||
Session::start_transport (bool after_loop)
|
||||
|
@ -1379,7 +1379,9 @@ TriggerBox::TriggerMidiMapMode TriggerBox::_midi_map_mode (TriggerBox::Sequentia
|
||||
int TriggerBox::_first_midi_note = 60;
|
||||
std::atomic<int32_t> TriggerBox::_pending_scene (-1);
|
||||
std::atomic<int32_t> TriggerBox::_active_scene (-1);
|
||||
std::atomic<int> TriggerBox::active_trigger_boxes (0);
|
||||
TriggerBoxThread* TriggerBox::worker = 0;
|
||||
PBD::Signal0<void> TriggerBox::StopAllTriggers;
|
||||
|
||||
void
|
||||
TriggerBox::init ()
|
||||
@ -1389,6 +1391,16 @@ TriggerBox::init ()
|
||||
init_pool ();
|
||||
}
|
||||
|
||||
void
|
||||
TriggerBox::start_transport_stop (Session& s)
|
||||
{
|
||||
if (active_trigger_boxes.load ()) {
|
||||
StopAllTriggers(); /* EMIT SIGNAL */
|
||||
} else {
|
||||
s.stop_transport_from_trigger ();
|
||||
}
|
||||
}
|
||||
|
||||
TriggerBox::TriggerBox (Session& s, DataType dt)
|
||||
: Processor (s, _("TriggerBox"), Temporal::BeatTime)
|
||||
, _bang_queue (1024)
|
||||
@ -1417,6 +1429,8 @@ TriggerBox::TriggerBox (Session& s, DataType dt)
|
||||
Temporal::TempoMap::MapChanged.connect_same_thread (tempo_map_connection, boost::bind (&TriggerBox::tempo_map_change, this));
|
||||
|
||||
Config->ParameterChanged.connect_same_thread (*this, boost::bind (&TriggerBox::parameter_changed, this, _1));
|
||||
|
||||
StopAllTriggers.connect_same_thread (stop_all_connection, boost::bind (&TriggerBox::request_stop_all, this));
|
||||
}
|
||||
|
||||
void
|
||||
@ -1592,6 +1606,8 @@ TriggerBox::stop_all ()
|
||||
|
||||
clear_implicit ();
|
||||
explicit_queue.reset ();
|
||||
|
||||
_stop_all = false;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1823,9 +1839,14 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
||||
if (!currently_playing) {
|
||||
if ((currently_playing = get_next_trigger ()) != 0) {
|
||||
currently_playing->startup ();
|
||||
active_trigger_boxes.fetch_add (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (_stop_all) {
|
||||
stop_all ();
|
||||
}
|
||||
|
||||
if (!currently_playing) {
|
||||
return;
|
||||
}
|
||||
@ -1833,7 +1854,7 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
||||
/* transport must be active for triggers */
|
||||
|
||||
if (!_session.transport_state_rolling()) {
|
||||
_session.start_transport_from_processor ();
|
||||
_session.start_transport_from_trigger ();
|
||||
}
|
||||
|
||||
timepos_t start (start_sample);
|
||||
@ -1887,11 +1908,6 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
||||
}
|
||||
}
|
||||
|
||||
if (_stop_all) {
|
||||
stop_all ();
|
||||
_stop_all = false;
|
||||
}
|
||||
|
||||
while (currently_playing) {
|
||||
|
||||
assert (currently_playing->state() >= Trigger::WaitingToStart);
|
||||
@ -1999,6 +2015,10 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
||||
|
||||
} else {
|
||||
currently_playing = 0;
|
||||
if (active_trigger_boxes.fetch_sub (1) == 1) {
|
||||
/* last active trigger box */
|
||||
_session.stop_transport_from_trigger ();
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user