triggerbox: threaded ::set_region() implementation

This commit is contained in:
Paul Davis 2021-11-10 08:45:38 -07:00
parent 431b7c0d4e
commit c4b189336e
3 changed files with 73 additions and 47 deletions

View File

@ -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<Region>) = 0;
void set_region (boost::shared_ptr<Region>);
virtual int set_region_threaded (boost::shared_ptr<Region>) = 0;
boost::shared_ptr<Region> 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<Region>);
int set_region_threaded (boost::shared_ptr<Region>);
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<Region>);
int set_region_threaded (boost::shared_ptr<Region>);
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<Region>);
void set_region (Trigger*, boost::shared_ptr<Region>);
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> 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<Region>);
void set_from_path (uint64_t slot, std::string const & path);
void set_from_selection (uint64_t slot, boost::shared_ptr<Region>);
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 {

View File

@ -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 ();

View File

@ -230,6 +230,12 @@ Trigger::set_quantization (Temporal::BBT_Offset const & q)
PropertyChanged (Properties::quantization);
}
void
Trigger::set_region (boost::shared_ptr<Region> r)
{
TriggerBox::worker->set_region (this, r);
}
void
Trigger::set_region_internal (boost::shared_ptr<Region> r)
{
@ -746,7 +752,7 @@ AudioTrigger::natural_length() const
}
int
AudioTrigger::set_region (boost::shared_ptr<Region> r)
AudioTrigger::set_region_threaded (boost::shared_ptr<Region> r)
{
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
@ -1160,7 +1166,7 @@ MIDITrigger::natural_length() const
}
int
MIDITrigger::set_region (boost::shared_ptr<Region> r)
MIDITrigger::set_region_threaded (boost::shared_ptr<Region> r)
{
boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion> (r);
@ -1373,6 +1379,15 @@ 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);
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> 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<Region> r)
{
TriggerBoxThread::Request* req = new TriggerBoxThread::Request (TriggerBoxThread::SetRegion);
req->trig = t;
req->region = r;
queue_request (req);
}