From c4b189336e4bc9f759a38410aa101f8a8d89817b Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 10 Nov 2021 08:45:38 -0700 Subject: [PATCH] triggerbox: threaded ::set_region() implementation --- libs/ardour/ardour/triggerbox.h | 34 +++++++------- libs/ardour/globals.cc | 3 +- libs/ardour/triggerbox.cc | 83 ++++++++++++++++++++++----------- 3 files changed, 73 insertions(+), 47 deletions(-) diff --git a/libs/ardour/ardour/triggerbox.h b/libs/ardour/ardour/triggerbox.h index ae11121402..3564ab0184 100644 --- a/libs/ardour/ardour/triggerbox.h +++ b/libs/ardour/ardour/triggerbox.h @@ -128,7 +128,8 @@ class LIBARDOUR_API Trigger : public PBD::Stateful { FollowAction follow_action (uint64_t n) const { assert (n < 2); return _follow_action[n]; } void set_follow_action (FollowAction, uint64_t n); - virtual int set_region (boost::shared_ptr) = 0; + void set_region (boost::shared_ptr); + virtual int set_region_threaded (boost::shared_ptr) = 0; boost::shared_ptr region() const { return _region; } Temporal::BBT_Offset quantization() const; @@ -245,7 +246,7 @@ class LIBARDOUR_API AudioTrigger : public Trigger { double position_as_fraction() const; - int set_region (boost::shared_ptr); + int set_region_threaded (boost::shared_ptr); void startup (); void jump_start (); void jump_stop (); @@ -296,7 +297,7 @@ class LIBARDOUR_API MIDITrigger : public Trigger { double position_as_fraction() const; - int set_region (boost::shared_ptr); + int set_region_threaded (boost::shared_ptr); void startup (); void jump_start (); void jump_stop (); @@ -341,12 +342,7 @@ class LIBARDOUR_API TriggerBoxThread static void init_request_pool() { Request::init_pool(); } - enum RequestType { - Quit, - SetRegion - }; - - void set_region (int32_t slot, boost::shared_ptr); + void set_region (Trigger*, boost::shared_ptr); void summon(); void stop(); @@ -356,13 +352,18 @@ class LIBARDOUR_API TriggerBoxThread static void* _thread_work(void *arg); void* thread_work(); + enum RequestType { + Quit, + SetRegion + }; + struct Request { Request (RequestType t) : type (t) {} RequestType type; /* for set region */ - int32_t slot; + Trigger* trig; /* XXX lifetime mgmt issues */ boost::shared_ptr region; void* operator new (size_t); @@ -404,8 +405,8 @@ class LIBARDOUR_API TriggerBox : public Processor XMLNode& get_state (void); int set_state (const XMLNode&, int version); - int set_from_path (uint64_t slot, std::string const & path); - int set_from_selection (uint64_t slot, boost::shared_ptr); + void set_from_path (uint64_t slot, std::string const & path); + void set_from_selection (uint64_t slot, boost::shared_ptr); DataType data_type() const { return _data_type; } @@ -447,10 +448,12 @@ class LIBARDOUR_API TriggerBox : public Processor static void scene_bang (uint32_t scene_number); static void scene_unbang (uint32_t scene_number); - static void init_pool(); + static void init (); static const int32_t default_triggers_per_box; + static TriggerBoxThread* worker; + private: static Temporal::BBT_Offset _assumed_trigger_duration; @@ -527,10 +530,7 @@ class LIBARDOUR_API TriggerBox : public Processor void reload (BufferSet& bufs, int32_t slot, void* ptr); - - - - + static void init_pool(); }; namespace Properties { diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index 90585ad978..d19996b6df 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -551,8 +551,7 @@ ARDOUR::init (bool try_optimization, const char* localedir, bool with_gui) SessionEvent::init_event_pool (); TransportFSM::Event::init_pool (); - TriggerBox::init_pool (); - TriggerBoxThread::init_request_pool (); + TriggerBox::init (); Operations::make_operations_quarks (); SessionObject::make_property_quarks (); diff --git a/libs/ardour/triggerbox.cc b/libs/ardour/triggerbox.cc index 9d4e7aa836..a71843b36c 100644 --- a/libs/ardour/triggerbox.cc +++ b/libs/ardour/triggerbox.cc @@ -230,6 +230,12 @@ Trigger::set_quantization (Temporal::BBT_Offset const & q) PropertyChanged (Properties::quantization); } +void +Trigger::set_region (boost::shared_ptr r) +{ + TriggerBox::worker->set_region (this, r); +} + void Trigger::set_region_internal (boost::shared_ptr r) { @@ -746,7 +752,7 @@ AudioTrigger::natural_length() const } int -AudioTrigger::set_region (boost::shared_ptr r) +AudioTrigger::set_region_threaded (boost::shared_ptr r) { boost::shared_ptr ar = boost::dynamic_pointer_cast (r); @@ -1160,7 +1166,7 @@ MIDITrigger::natural_length() const } int -MIDITrigger::set_region (boost::shared_ptr r) +MIDITrigger::set_region_threaded (boost::shared_ptr r) { boost::shared_ptr mr = boost::dynamic_pointer_cast (r); @@ -1373,6 +1379,15 @@ TriggerBox::TriggerMidiMapMode TriggerBox::_midi_map_mode (TriggerBox::Sequentia int TriggerBox::_first_midi_note = 60; std::atomic TriggerBox::_pending_scene (-1); std::atomic TriggerBox::_active_scene (-1); +TriggerBoxThread* TriggerBox::worker = 0; + +void +TriggerBox::init () +{ + worker = new TriggerBoxThread; + TriggerBoxThread::init_request_pool (); + init_pool (); +} TriggerBox::TriggerBox (Session& s, DataType dt) : Processor (s, _("TriggerBox"), Temporal::BeatTime) @@ -1495,23 +1510,23 @@ TriggerBox::get_next_trigger () return 0; } -int +void TriggerBox::set_from_selection (uint64_t slot, boost::shared_ptr region) { DEBUG_TRACE (DEBUG::Triggers, string_compose ("load %1 into %2\n", region->name(), slot)); if (slot >= all_triggers.size()) { - return 0; + return; } - return all_triggers[slot]->set_region (region); + all_triggers[slot]->set_region (region); } -int +void TriggerBox::set_from_path (uint64_t slot, std::string const & path) { if (slot >= all_triggers.size()) { - return 0; + return; } try { @@ -1520,7 +1535,7 @@ TriggerBox::set_from_path (uint64_t slot, std::string const & path) if (!SndFileSource::get_soundfile_info (path, info, errmsg)) { error << string_compose (_("Cannot get info from audio file %1 (%2)"), path, errmsg) << endmsg; - return -1; + return; } SourceList src_list; @@ -1530,7 +1545,7 @@ TriggerBox::set_from_path (uint64_t slot, std::string const & path) if (!source) { error << string_compose (_("Cannot create source from %1"), path) << endmsg; src_list.clear (); - return -1; + return; } src_list.push_back (source); } @@ -1551,10 +1566,8 @@ TriggerBox::set_from_path (uint64_t slot, std::string const & path) } catch (std::exception& e) { cerr << "loading sample from " << path << " failed: " << e.what() << endl; - return -1; + return; } - - return 0; } TriggerBox::~TriggerBox () @@ -2367,8 +2380,8 @@ TriggerBoxThread::TriggerBoxThread () TriggerBoxThread::~TriggerBoxThread() { void* status; - Request* q = new Request (Quit); - queue_request (q); + char msg = (char) Quit; + _xthread.deliver (msg); pthread_join (thread, &status); } @@ -2388,24 +2401,27 @@ TriggerBoxThread::thread_work () char msg; if (_xthread.receive (msg, true) >= 0) { - RequestType req = (RequestType) msg; - switch (req) { - case Quit: - DEBUG_TRACE (DEBUG::Butler, string_compose ("%1: tbthread asked to quit @ %2\n", DEBUG_THREAD_SELF, g_get_monotonic_time())); - return 0; - abort(); /*NOTREACHED*/ - break; - default: - /* something woke us up. We'll check the - ringbuffer to see what needs doing - */ - break; + if (msg == (char) Quit) { + return (void *) 0; + abort(); /*NOTREACHED*/ } - } + Temporal::TempoMap::fetch (); - Temporal::TempoMap::fetch (); + Request* req; + + while (requests.read (&req, 1) == 1) { + switch (req->type) { + case SetRegion: + req->trig->set_region_threaded (req->region); + break; + default: + break; + } + delete req; /* back to pool */ + } + } } return (void *) 0; @@ -2453,3 +2469,14 @@ TriggerBoxThread::Request::init_pool () { pool = new MultiAllocSingleReleasePool (X_("TriggerBoxThreadRequests"), sizeof (TriggerBoxThread::Request), 1024); } + +void +TriggerBoxThread::set_region (Trigger* t, boost::shared_ptr r) +{ + TriggerBoxThread::Request* req = new TriggerBoxThread::Request (TriggerBoxThread::SetRegion); + + req->trig = t; + req->region = r; + + queue_request (req); +}