13
0

triggerbox: use shared_ptr<Trigger> and also change all 64 bit indices to 32 bit

This commit is contained in:
Paul Davis 2021-12-21 13:37:47 -07:00
parent f3fe31da27
commit f69180c8ee
2 changed files with 77 additions and 98 deletions

View File

@ -96,7 +96,7 @@ class LIBARDOUR_API Trigger : public PBD::Stateful {
Stopping
};
Trigger (uint64_t index, TriggerBox&);
Trigger (uint32_t index, TriggerBox&);
virtual ~Trigger() {}
static void make_property_quarks ();
@ -173,7 +173,7 @@ class LIBARDOUR_API Trigger : public PBD::Stateful {
OtherTrigger,
};
FollowAction follow_action (uint64_t n) const { assert (n < 2); return n ? _follow_action1 : _follow_action0; }
FollowAction follow_action (uint32_t n) const { assert (n < 2); return n ? _follow_action1 : _follow_action0; }
void set_follow_action (FollowAction, uint32_t n);
void set_region (boost::shared_ptr<Region>);
@ -184,7 +184,7 @@ class LIBARDOUR_API Trigger : public PBD::Stateful {
Temporal::BBT_Offset quantization() const;
void set_quantization (Temporal::BBT_Offset const &);
uint64_t index() const { return _index; }
uint32_t index() const { return _index; }
/* Managed by TriggerBox, these record the time that the trigger is
* scheduled to start or stop at. Computed in
@ -249,7 +249,7 @@ class LIBARDOUR_API Trigger : public PBD::Stateful {
State _state;
std::atomic<int> _bang;
std::atomic<int> _unbang;
uint64_t _index;
uint32_t _index;
int _next_trigger;
gain_t _pending_gain;
uint32_t _loop_cnt; /* how many times in a row has this played */
@ -283,9 +283,11 @@ class LIBARDOUR_API Trigger : public PBD::Stateful {
virtual void set_usable_length () = 0;
};
typedef boost::shared_ptr<Trigger> TriggerPtr;
class LIBARDOUR_API AudioTrigger : public Trigger {
public:
AudioTrigger (uint64_t index, TriggerBox&);
AudioTrigger (uint32_t index, TriggerBox&);
~AudioTrigger ();
pframes_t run (BufferSet&, samplepos_t start_sample, samplepos_t end_sample, Temporal::Beats const & start, Temporal::Beats const & end, pframes_t nframes, pframes_t offset, bool first, double bpm);
@ -359,7 +361,7 @@ class LIBARDOUR_API AudioTrigger : public Trigger {
class LIBARDOUR_API MIDITrigger : public Trigger {
public:
MIDITrigger (uint64_t index, TriggerBox&);
MIDITrigger (uint32_t index, TriggerBox&);
~MIDITrigger ();
pframes_t run (BufferSet&, samplepos_t start_sample, samplepos_t end_sample, Temporal::Beats const & start_beats, Temporal::Beats const & end_beats, pframes_t nframes, pframes_t offset, bool passthru, double bpm);
@ -420,7 +422,7 @@ class LIBARDOUR_API TriggerBoxThread
static void init_request_pool() { Request::init_pool(); }
void set_region (Trigger*, boost::shared_ptr<Region>);
void set_region (TriggerBox&, uint32_t slot, boost::shared_ptr<Region>);
void summon();
void stop();
@ -441,7 +443,8 @@ class LIBARDOUR_API TriggerBoxThread
RequestType type;
/* for set region */
Trigger* trig; /* XXX lifetime mgmt issues */
TriggerBox* box;
uint32_t slot;
boost::shared_ptr<Region> region;
void* operator new (size_t);
@ -472,25 +475,25 @@ class LIBARDOUR_API TriggerBox : public Processor
int32_t order() const { return _order; }
void set_order(int32_t n);
typedef std::vector<Trigger*> Triggers;
typedef std::vector<TriggerPtr> Triggers;
Trigger* trigger (Triggers::size_type);
TriggerPtr trigger (Triggers::size_type);
bool bang_trigger (Trigger*);
bool unbang_trigger (Trigger*);
void add_trigger (Trigger*);
bool bang_trigger (TriggerPtr);
bool unbang_trigger (TriggerPtr);
void add_trigger (TriggerPtr);
XMLNode& get_state (void);
int set_state (const XMLNode&, int version);
void set_from_path (uint64_t slot, std::string const & path);
void set_from_selection (uint64_t slot, boost::shared_ptr<Region>);
void set_from_path (uint32_t slot, std::string const & path);
void set_from_selection (uint32_t slot, boost::shared_ptr<Region>);
DataType data_type() const { return _data_type; }
void request_stop_all ();
Trigger* currently_playing() const { return _currently_playing; }
TriggerPtr currently_playing() const { return _currently_playing; }
/* Returns a negative value is there is no active Trigger, or a value between 0
* and 1.0 if there is, corresponding to the value of position_as_fraction() for
@ -498,9 +501,9 @@ class LIBARDOUR_API TriggerBox : public Processor
*/
double position_as_fraction() const;
void queue_explict (Trigger*);
Trigger* get_next_trigger ();
Trigger* peek_next_trigger ();
void queue_explict (uint32_t);
TriggerPtr get_next_trigger ();
TriggerPtr peek_next_trigger ();
void add_midi_sidechain (std::string const & name);
@ -508,7 +511,6 @@ class LIBARDOUR_API TriggerBox : public Processor
void set_pass_thru (bool yn);
void request_reload (int32_t slot, void*);
void request_use (int32_t slot, Trigger&);
enum TriggerMidiMapMode {
AbletonPush,
@ -548,14 +550,12 @@ class LIBARDOUR_API TriggerBox : public Processor
static Temporal::BBT_Offset _assumed_trigger_duration;
PBD::RingBuffer<Trigger*> _bang_queue;
PBD::RingBuffer<Trigger*> _unbang_queue;
DataType _data_type;
int32_t _order;
Glib::Threads::RWLock trigger_lock; /* protects all_triggers */
Triggers all_triggers;
PBD::RingBuffer<Trigger*> explicit_queue; /* user queued triggers */
Trigger* _currently_playing;
PBD::RingBuffer<uint32_t> explicit_queue; /* user queued triggers */
TriggerPtr _currently_playing;
Requests _requests;
bool _stop_all;
bool _pass_thru;
@ -569,7 +569,7 @@ class LIBARDOUR_API TriggerBox : public Processor
void drop_triggers ();
void process_ui_trigger_requests ();
void process_midi_trigger_requests (BufferSet&);
int determine_next_trigger (uint64_t n);
int determine_next_trigger (uint32_t n);
void stop_all ();
int note_to_trigger (int node, int channel);
@ -593,14 +593,9 @@ class LIBARDOUR_API TriggerBox : public Processor
Type type;
union {
Trigger* trigger;
void* ptr;
};
union {
int32_t slot;
};
TriggerPtr trigger;
void* ptr;
int32_t slot;
Request (Type t) : type (t) {}
@ -640,7 +635,7 @@ namespace Properties {
LIBARDOUR_API extern PBD::PropertyDescriptor<int> follow_action_probability;
LIBARDOUR_API extern PBD::PropertyDescriptor<float> velocity_effect;
LIBARDOUR_API extern PBD::PropertyDescriptor<gain_t> gain;
LIBARDOUR_API extern PBD::PropertyDescriptor<Trigger*> currently_playing;
LIBARDOUR_API extern PBD::PropertyDescriptor<uint32_t> currently_playing;
LIBARDOUR_API extern PBD::PropertyDescriptor<bool> stretchable;
LIBARDOUR_API extern PBD::PropertyDescriptor<bool> isolated;
}

View File

@ -3,6 +3,8 @@
#include <cstdlib>
#include <sstream>
#include <boost/make_shared.hpp>
#include <glibmm.h>
#include <rubberband/RubberBandStretcher.h>
@ -53,7 +55,7 @@ namespace ARDOUR {
PBD::PropertyDescriptor<Trigger::LaunchStyle> launch_style;
PBD::PropertyDescriptor<Trigger::FollowAction> follow_action0;
PBD::PropertyDescriptor<Trigger::FollowAction> follow_action1;
PBD::PropertyDescriptor<Trigger*> currently_playing;
PBD::PropertyDescriptor<uint32_t> currently_playing;
PBD::PropertyDescriptor<uint32_t> follow_count;
PBD::PropertyDescriptor<int> follow_action_probability;
PBD::PropertyDescriptor<float> velocity_effect;
@ -63,7 +65,7 @@ namespace ARDOUR {
}
}
Trigger::Trigger (uint64_t n, TriggerBox& b)
Trigger::Trigger (uint32_t n, TriggerBox& b)
: _box (b)
, _state (Stopped)
, _bang (0)
@ -272,7 +274,7 @@ Trigger::set_quantization (Temporal::BBT_Offset const & q)
void
Trigger::set_region (boost::shared_ptr<Region> r)
{
TriggerBox::worker->set_region (this, r);
TriggerBox::worker->set_region (_box, index(), r);
}
void
@ -399,7 +401,7 @@ Trigger::process_state_requests ()
case Stopped:
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 %2 stopped => %3\n", index(), enum_2_string (Stopped), enum_2_string (WaitingToStart)));
_box.queue_explict (this);
_box.queue_explict (index());
break;
case WaitingToStart:
@ -554,7 +556,7 @@ Trigger::maybe_compute_next_transition (samplepos_t start_sample, Temporal::Beat
/*--------------------*/
AudioTrigger::AudioTrigger (uint64_t n, TriggerBox& b)
AudioTrigger::AudioTrigger (uint32_t n, TriggerBox& b)
: Trigger (n, b)
, _stretcher (0)
, _start_offset (0)
@ -1142,7 +1144,7 @@ AudioTrigger::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa
for (uint32_t chn = 0; chn < bufs.count().n_audio(); ++chn) {
uint64_t channel = chn % data.size();
uint32_t channel = chn % data.size();
AudioBuffer& buf (bufs.get_audio (chn));
Sample* src = do_stretch ? bufp[channel] : (data[channel] + read_index);
@ -1234,7 +1236,7 @@ AudioTrigger::reload (BufferSet&, void*)
/*--------------------*/
MIDITrigger::MIDITrigger (uint64_t n, TriggerBox& b)
MIDITrigger::MIDITrigger (uint32_t n, TriggerBox& b)
: Trigger (n, b)
, data_length (Temporal::Beats ())
, usable_length (Temporal::Beats ())
@ -1657,8 +1659,6 @@ TriggerBox::start_transport_stop (Session& s)
TriggerBox::TriggerBox (Session& s, DataType dt)
: Processor (s, _("TriggerBox"), Temporal::BeatTime)
, _bang_queue (1024)
, _unbang_queue (1024)
, _data_type (dt)
, _order (-1)
, explicit_queue (64)
@ -1672,12 +1672,12 @@ TriggerBox::TriggerBox (Session& s, DataType dt)
/* default number of possible triggers. call ::add_trigger() to increase */
if (_data_type == DataType::AUDIO) {
for (uint64_t n = 0; n < default_triggers_per_box; ++n) {
all_triggers.push_back (new AudioTrigger (n, *this));
for (uint32_t n = 0; n < default_triggers_per_box; ++n) {
all_triggers.push_back (boost::make_shared<AudioTrigger> (n, *this));
}
} else {
for (uint64_t n = 0; n < default_triggers_per_box; ++n) {
all_triggers.push_back (new MIDITrigger (n, *this));
for (uint32_t n = 0; n < default_triggers_per_box; ++n) {
all_triggers.push_back (boost::make_shared<MIDITrigger> (n, *this));
}
}
@ -1721,24 +1721,24 @@ TriggerBox::set_order (int32_t n)
}
void
TriggerBox::queue_explict (Trigger* t)
TriggerBox::queue_explict (uint32_t n)
{
assert (t);
explicit_queue.write (&t, 1);
DEBUG_TRACE (DEBUG::Triggers, string_compose ("explicit queue %1, EQ = %2\n", t->index(), explicit_queue.read_space()));
assert (n < all_triggers.size());
explicit_queue.write (&n, 1);
DEBUG_TRACE (DEBUG::Triggers, string_compose ("explicit queue %1, EQ = %2\n", n, explicit_queue.read_space()));
if (_currently_playing) {
_currently_playing->unbang ();
}
}
Trigger*
TriggerPtr
TriggerBox::get_next_trigger ()
{
Trigger* r;
if (explicit_queue.read (&r, 1) == 1) {
uint32_t n;
if (explicit_queue.read (&n, 1) == 1) {
TriggerPtr r = trigger (n);
DEBUG_TRACE (DEBUG::Triggers, string_compose ("next trigger from explicit queue = %1\n", r->index()));
return r;
}
@ -1746,7 +1746,7 @@ TriggerBox::get_next_trigger ()
}
void
TriggerBox::set_from_selection (uint64_t slot, boost::shared_ptr<Region> region)
TriggerBox::set_from_selection (uint32_t slot, boost::shared_ptr<Region> region)
{
DEBUG_TRACE (DEBUG::Triggers, string_compose ("load %1 into %2\n", region->name(), slot));
@ -1758,7 +1758,7 @@ TriggerBox::set_from_selection (uint64_t slot, boost::shared_ptr<Region> region)
}
void
TriggerBox::set_from_path (uint64_t slot, std::string const & path)
TriggerBox::set_from_path (uint32_t slot, std::string const & path)
{
if (slot >= all_triggers.size()) {
return;
@ -1822,7 +1822,6 @@ TriggerBox::set_from_path (uint64_t slot, std::string const & path)
TriggerBox::~TriggerBox ()
{
drop_triggers ();
}
void
@ -1838,7 +1837,7 @@ TriggerBox::stop_all ()
DEBUG_TRACE (DEBUG::Triggers, "stop-all request received\n");
for (uint64_t n = 0; n < all_triggers.size(); ++n) {
for (uint32_t n = 0; n < all_triggers.size(); ++n) {
all_triggers[n]->request_stop ();
}
@ -1851,18 +1850,10 @@ void
TriggerBox::drop_triggers ()
{
Glib::Threads::RWLock::WriterLock lm (trigger_lock);
for (Triggers::iterator t = all_triggers.begin(); t != all_triggers.end(); ++t) {
if (*t) {
delete *t;
(*t) = 0;
}
}
all_triggers.clear ();
}
Trigger*
TriggerPtr
TriggerBox::trigger (Triggers::size_type n)
{
Glib::Threads::RWLock::ReaderLock lm (trigger_lock);
@ -1917,7 +1908,7 @@ TriggerBox::configure_io (ChanCount in, ChanCount out)
bool ret = Processor::configure_io (in, out);
if (ret) {
for (uint64_t n = 0; n < all_triggers.size(); ++n) {
for (uint32_t n = 0; n < all_triggers.size(); ++n) {
all_triggers[n]->io_change ();
}
}
@ -1925,7 +1916,7 @@ TriggerBox::configure_io (ChanCount in, ChanCount out)
}
void
TriggerBox::add_trigger (Trigger* trigger)
TriggerBox::add_trigger (TriggerPtr trigger)
{
Glib::Threads::RWLock::WriterLock lm (trigger_lock);
all_triggers.push_back (trigger);
@ -2008,7 +1999,7 @@ TriggerBox::process_midi_trigger_requests (BufferSet& bufs)
continue;
}
Trigger* t = all_triggers[trigger_number];
TriggerPtr t = all_triggers[trigger_number];
if (!t) {
continue;
@ -2106,9 +2097,9 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
/* STEP SEVEN: let each slot process any individual state requests
*/
std::vector<uint64_t> to_run;
std::vector<uint32_t> to_run;
for (uint64_t n = 0; n < all_triggers.size(); ++n) {
for (uint32_t n = 0; n < all_triggers.size(); ++n) {
all_triggers[n]->process_state_requests ();
}
@ -2150,7 +2141,7 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
const Temporal::Beats end_beats (timepos_t (end_sample).beats());
Temporal::TempoMap::SharedPtr tmap (Temporal::TempoMap::use());
uint32_t max_chans = 0;
Trigger* nxt = 0;
TriggerPtr nxt;
pframes_t dest_offset = 0;
while (nframes) {
@ -2164,7 +2155,7 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
/* see if there's another trigger explicitly queued */
RingBuffer<Trigger*>::rw_vector rwv;
RingBuffer<uint32_t>::rw_vector rwv;
explicit_queue.get_read_vector (&rwv);
if (rwv.len[0] > 0) {
@ -2173,7 +2164,8 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
/* peek at it without dequeing it */
nxt = *(rwv.buf[0]);
uint32_t n = *(rwv.buf[0]);
nxt = trigger (n);
/* if user triggered same clip, that will have been handled as
* it processed bang requests. Nothing to do here otherwise.
@ -2292,7 +2284,7 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
* doing pass thru, so silence whatever is left.
*/
for (uint64_t chn = 0; chn < bufs.count().n_audio(); ++chn) {
for (uint32_t chn = 0; chn < bufs.count().n_audio(); ++chn) {
AudioBuffer& buf (bufs.get_audio (chn));
buf.silence (nframes, (orig_nframes - nframes));
}
@ -2320,14 +2312,14 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
}
int
TriggerBox::determine_next_trigger (uint64_t current)
TriggerBox::determine_next_trigger (uint32_t current)
{
uint64_t n;
uint64_t runnable = 0;
uint32_t n;
uint32_t runnable = 0;
/* count number of triggers that can actually be run (i.e. they have a region) */
for (uint64_t n = 0; n < all_triggers.size(); ++n) {
for (uint32_t n = 0; n < all_triggers.size(); ++n) {
if (all_triggers[n]->region()) {
runnable++;
}
@ -2451,7 +2443,7 @@ TriggerBox::determine_next_trigger (uint64_t current)
case Trigger::OtherTrigger:
while (true) {
n = _pcg.rand (all_triggers.size());
if ((uint64_t) n == current) {
if ((uint32_t) n == current) {
continue;
}
if (!all_triggers[n]->region()) {
@ -2526,14 +2518,14 @@ TriggerBox::set_state (const XMLNode& node, int version)
Glib::Threads::RWLock::WriterLock lm (trigger_lock);
for (XMLNodeList::const_iterator t = tchildren.begin(); t != tchildren.end(); ++t) {
Trigger* trig;
TriggerPtr trig;
if (_data_type == DataType::AUDIO) {
trig = new AudioTrigger (all_triggers.size(), *this);
trig = boost::make_shared<AudioTrigger> (all_triggers.size(), *this);
all_triggers.push_back (trig);
trig->set_state (**t, version);
} else if (_data_type == DataType::MIDI) {
trig = new MIDITrigger (all_triggers.size(), *this);
trig = boost::make_shared<MIDITrigger> (all_triggers.size(), *this);
all_triggers.push_back (trig);
trig->set_state (**t, version);
}
@ -2611,15 +2603,6 @@ TriggerBox::request_reload (int32_t slot, void* ptr)
requests.write (&r, 1);
}
void
TriggerBox::request_use (int32_t slot, Trigger& t)
{
Request* r = new Request (Request::Use);
r->slot = slot;
r->trigger = &t;
requests.write (&r, 1);
}
void
TriggerBox::process_requests (BufferSet& bufs)
{
@ -2659,7 +2642,7 @@ TriggerBox::reload (BufferSet& bufs, int32_t slot, void* ptr)
double
TriggerBox::position_as_fraction () const
{
Trigger* cp = _currently_playing;
TriggerPtr cp = _currently_playing;
if (!cp) {
return -1;
}
@ -2717,7 +2700,7 @@ TriggerBoxThread::thread_work ()
while (requests.read (&req, 1) == 1) {
switch (req->type) {
case SetRegion:
req->trig->set_region_threaded (req->region);
req->box->trigger (req->slot)->set_region_threaded (req->region);
break;
default:
break;
@ -2767,11 +2750,12 @@ TriggerBoxThread::Request::init_pool ()
}
void
TriggerBoxThread::set_region (Trigger* t, boost::shared_ptr<Region> r)
TriggerBoxThread::set_region (TriggerBox& box, uint32_t slot, boost::shared_ptr<Region> r)
{
TriggerBoxThread::Request* req = new TriggerBoxThread::Request (TriggerBoxThread::SetRegion);
req->trig = t;
req->box = &box;
req->slot = slot;
req->region = r;
queue_request (req);