Compare commits

...

2 Commits

3 changed files with 51 additions and 34 deletions

View File

@ -272,7 +272,7 @@ TriggerEntry::draw_launch_icon (Cairo::RefPtr<Cairo::Context> context, float sz,
bool active = trigger ()->active ();
if (!trigger ()->region ()) {
if (!trigger ()->has_data ()) {
/* no content in this slot, it is only a Stop button */
context->move_to (margin, margin);
context->rel_line_to (size, 0);
@ -454,7 +454,7 @@ TriggerEntry::render (ArdourCanvas::Rect const& area, Cairo::RefPtr<Cairo::Conte
}
/* follow-action icon */
if (trigger ()->region () && trigger ()->will_follow ()) {
if (trigger ()->has_data () && trigger ()->will_follow ()) {
context->set_identity_matrix ();
context->translate (self.x0, self.y0 - 0.5);
context->translate (width - height, 0); // right side of the widget
@ -467,7 +467,7 @@ void
TriggerEntry::on_trigger_changed (PropertyChange const& change)
{
if (change.contains (ARDOUR::Properties::name)) {
if (trigger ()->region ()) {
if (trigger ()->has_data ()) {
name_text->set (short_version (trigger ()->name (), 16));
play_button->set_tooltip (_("Launch this clip\nRight-click to select Launch Options for this clip"));
} else {
@ -587,7 +587,7 @@ TriggerEntry::name_button_event (GdkEvent* ev)
bool
TriggerEntry::play_button_event (GdkEvent* ev)
{
if (!trigger ()->region ()) {
if (!trigger ()->has_data ()) {
/* empty slot; this is just a stop button */
switch (ev->type) {
case GDK_BUTTON_PRESS:
@ -688,7 +688,7 @@ TriggerEntry::follow_button_event (GdkEvent* ev)
bool
TriggerEntry::event (GdkEvent* ev)
{
if (!trigger ()->region ()) {
if (!trigger ()->has_data ()) {
return false;
}
@ -784,9 +784,13 @@ TriggerEntry::drag_begin (Glib::RefPtr<Gdk::DragContext> const& context)
/* ctx leaves scope, cr is destroyed, and pixmap surface is flush()ed */
}
std::shared_ptr<Region> region = trigger ()->region ();
if (region) {
PublicEditor::instance ().pbdid_dragged_dt = region->data_type ();
if (trigger()->has_data()) {
std::shared_ptr<AudioTrigger> att = std::dynamic_pointer_cast<AudioTrigger> (trigger());
if (att) {
PublicEditor::instance ().pbdid_dragged_dt = DataType::AUDIO;
} else {
PublicEditor::instance ().pbdid_dragged_dt = DataType::MIDI;
}
} else {
PublicEditor::instance ().pbdid_dragged_dt = DataType::NIL;
}

View File

@ -315,6 +315,8 @@ class LIBARDOUR_API Trigger : public PBD::Stateful {
bool active() const { return _state >= Running; }
State state() const { return _state; }
virtual bool has_data() const = 0;
void set_region (std::shared_ptr<Region>, bool use_thread = true);
void clear_region ();
virtual int set_region_in_worker_thread (std::shared_ptr<Region>) = 0;
@ -495,6 +497,9 @@ class LIBARDOUR_API AudioTrigger : public Trigger {
return audio_run<true> (bufs, start_sample, end_sample, start, end, nframes, dest_offset, bpm, quantize_offset);
}
bool has_data() const { return data.length > 0; }
uint32_t n_channels() const { return data.size(); }
StretchMode stretch_mode() const { return _stretch_mode; }
void set_stretch_mode (StretchMode);
@ -559,6 +564,7 @@ class LIBARDOUR_API AudioTrigger : public Trigger {
void drop_data ();
int load_data (std::shared_ptr<AudioRegion>);
int load_data (BufferSet const &);
void estimate_tempo ();
void reset_stretcher ();
void _startup (BufferSet&, pframes_t dest_offset, Temporal::BBT_Offset const &);
@ -577,6 +583,8 @@ class LIBARDOUR_API MIDITrigger : public Trigger {
return midi_run<true> (bufs, start_sample, end_sample, start, end, nframes, dest_offset, bpm, quantize_offset);
}
bool has_data() const { return (bool) model; }
void set_start (timepos_t const &);
void set_end (timepos_t const &);
void set_legato_offset (timepos_t const &);
@ -645,6 +653,7 @@ class LIBARDOUR_API MIDITrigger : public Trigger {
bool map_change;
int load_data (std::shared_ptr<MidiRegion>);
int load_data (BufferSet const &);
void compute_and_set_length ();
void _startup (BufferSet&, pframes_t dest_offset, Temporal::BBT_Offset const &);
};

View File

@ -562,7 +562,7 @@ Trigger::set_ui (void* p)
void
Trigger::bang (float velocity)
{
if (!_region) {
if (!has_data()) {
return;
}
_pending_velocity_gain = velocity;
@ -573,7 +573,7 @@ Trigger::bang (float velocity)
void
Trigger::unbang ()
{
if (!_region) {
if (!has_data()) {
return;
}
_unbang.fetch_add (1);
@ -1285,7 +1285,7 @@ AudioTrigger::set_stretch_mode (Trigger::StretchMode sm)
void
AudioTrigger::set_segment_tempo (double t)
{
if (!_region) {
if (data.length <= 0) {
_segment_tempo = 0;
return;
}
@ -1772,12 +1772,11 @@ AudioTrigger::setup_stretcher ()
using namespace RubberBand;
using namespace Temporal;
if (!_region) {
if (!has_data()) {
return;
}
std::shared_ptr<AudioRegion> ar (std::dynamic_pointer_cast<AudioRegion> (_region));
const uint32_t nchans = std::min (_box.input_streams().n_audio(), ar->n_channels());
const uint32_t nchans = std::min (_box.input_streams().n_audio(), n_channels());
//map our internal enum to a rubberband option
RubberBandStretcher::Option ro = RubberBandStretcher::Option (0);
@ -1802,6 +1801,13 @@ AudioTrigger::drop_data ()
delete [] d;
}
data.clear ();
data.length = 0;
}
int
AudioTrigger::load_data (BufferSet const & bufs)
{
return 0;
}
int
@ -1809,8 +1815,8 @@ AudioTrigger::load_data (std::shared_ptr<AudioRegion> ar)
{
const uint32_t nchans = ar->n_channels();
data.length = ar->length_samples();
drop_data ();
data.length = ar->length_samples();
try {
for (uint32_t n = 0; n < nchans; ++n) {
@ -1849,9 +1855,8 @@ AudioTrigger::audio_run (BufferSet& bufs, samplepos_t start_sample, samplepos_t
Temporal::Beats const & start, Temporal::Beats const & end,
pframes_t nframes, pframes_t dest_offset, double bpm, pframes_t& quantize_offset)
{
std::shared_ptr<AudioRegion> ar = std::dynamic_pointer_cast<AudioRegion>(_region);
/* We do not modify the I/O of our parent route, so we process only min (bufs.n_audio(),region.channels()) */
const uint32_t nchans = (in_process_context ? std::min (bufs.count().n_audio(), ar->n_channels()) : ar->n_channels());
const uint32_t nchans = (in_process_context ? std::min (bufs.count().n_audio(), n_channels()) : n_channels());
int avail = 0;
BufferSet* scratch;
std::unique_ptr<BufferSet> scratchp;
@ -3262,7 +3267,7 @@ TriggerBox::fast_forward (CueEvents const & cues, samplepos_t transport_position
pos = c->time;
cnt = 0;
if (!trig->region()) {
if (!trig->has_data()) {
fast_forward_nothing_to_do ();
return;
}
@ -3480,7 +3485,7 @@ TriggerBox::maybe_swap_pending (uint32_t slot)
if (p) {
if (p == Trigger::MagicClearPointerValue) {
if (all_triggers[slot]->region()) {
if (all_triggers[slot]->has_data()) {
if (_active_slots) {
_active_slots--;
}
@ -3490,7 +3495,7 @@ TriggerBox::maybe_swap_pending (uint32_t slot)
}
all_triggers[slot]->clear_region ();
} else {
if (!all_triggers[slot]->region()) {
if (!all_triggers[slot]->has_data()) {
if (_active_slots == 0) {
empty_changed = true;
}
@ -3772,7 +3777,7 @@ void
TriggerBox::bang_trigger_at (Triggers::size_type row, float velocity)
{
TriggerPtr t = trigger(row);
if (t && t->region()) {
if (t && t->has_data()) {
t->bang (velocity);
} else {
/* by convention, an empty slot is effectively a STOP button */
@ -3784,7 +3789,7 @@ void
TriggerBox::unbang_trigger_at (Triggers::size_type row)
{
TriggerPtr t = trigger(row);
if (t && t->region()) {
if (t && t->has_data()) {
t->unbang();
} else {
/* you shouldn't be able to unbang an empty slot; but if this somehow happens we'll just treat it as a */
@ -4174,7 +4179,7 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
DEBUG_TRACE (DEBUG::Triggers, string_compose ("tb noticed active scene %1\n", _active_scene));
if (_active_scene < (int32_t) all_triggers.size()) {
if (!all_triggers[_active_scene]->cue_isolated()) {
if (all_triggers[_active_scene]->region()) {
if (all_triggers[_active_scene]->has_data()) {
all_triggers[_active_scene]->bang ();
} else {
stop_all_quantized (); //empty slot, this should work as a Stop for the running clips
@ -4428,10 +4433,9 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
pframes_t frames_covered;
std::shared_ptr<AudioRegion> ar = std::dynamic_pointer_cast<AudioRegion> (_currently_playing->region());
if (ar) {
max_chans = std::max (ar->n_channels(), max_chans);
std::shared_ptr<AudioTrigger> att = std::dynamic_pointer_cast<AudioTrigger> (_currently_playing);
if (att) {
max_chans = std::max (att->n_channels(), max_chans);
}
/* Quantize offset will generally be zero, but if non-zero, it
@ -4506,12 +4510,12 @@ TriggerBox::determine_next_trigger (uint32_t current)
/* count number of triggers that can actually be run (i.e. they have a region) */
for (uint32_t n = 0; n < all_triggers.size(); ++n) {
if (all_triggers[n]->region()) {
if (all_triggers[n]->has_data()) {
runnable++;
}
}
if (runnable == 0 || !all_triggers[current]->region()) {
if (runnable == 0 || !all_triggers[current]->has_data()) {
return -1;
}
@ -4572,7 +4576,7 @@ TriggerBox::determine_next_trigger (uint32_t current)
break;
}
if (all_triggers[n]->region() && !all_triggers[n]->active()) {
if (all_triggers[n]->has_data() && !all_triggers[n]->active()) {
return n;
}
}
@ -4591,7 +4595,7 @@ TriggerBox::determine_next_trigger (uint32_t current)
break;
}
if (all_triggers[n]->region() && !all_triggers[n]->active ()) {
if (all_triggers[n]->has_data() && !all_triggers[n]->active ()) {
return n;
}
}
@ -4599,14 +4603,14 @@ TriggerBox::determine_next_trigger (uint32_t current)
case FollowAction::FirstTrigger:
for (n = 0; n < all_triggers.size(); ++n) {
if (all_triggers[n]->region() && !all_triggers[n]->active ()) {
if (all_triggers[n]->has_data() && !all_triggers[n]->active ()) {
return n;
}
}
break;
case FollowAction::LastTrigger:
for (int i = all_triggers.size() - 1; i >= 0; --i) {
if (all_triggers[i]->region() && !all_triggers[i]->active ()) {
if (all_triggers[i]->has_data() && !all_triggers[i]->active ()) {
return i;
}
}
@ -4614,7 +4618,7 @@ TriggerBox::determine_next_trigger (uint32_t current)
case FollowAction::JumpTrigger:
for (std::size_t n = 0; n < TriggerBox::default_triggers_per_box; ++n) {
if (fa.targets.test (n) && all_triggers[n]->region()) {
if (fa.targets.test (n) && all_triggers[n]->has_data()) {
possible_targets.push_back (n);
}
}