triggerbox: threaded ::set_region() implementation
This commit is contained in:
parent
431b7c0d4e
commit
c4b189336e
|
@ -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 {
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue