From c291cb64b1e3ebf3ba6458fec3c1b446e0db3b9c Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 1 Nov 2017 15:46:23 +0100 Subject: Wrap automation on loop-position, split plugin processing --- libs/ardour/ardour/plugin_insert.h | 3 +++ libs/ardour/ardour/processor.h | 2 ++ libs/ardour/plugin_insert.cc | 52 ++++++++++++++++++++++++++++++++++++++ libs/ardour/processor.cc | 28 ++++++++++++++++++++ 4 files changed, 85 insertions(+) diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h index e13986c2c7..f0d3f463a4 100644 --- a/libs/ardour/ardour/plugin_insert.h +++ b/libs/ardour/ardour/plugin_insert.h @@ -77,6 +77,9 @@ public: bool write_immediate_event (size_t size, const uint8_t* buf); + void automation_run (samplepos_t, pframes_t); + bool find_next_event (double, double, Evoral::ControlEvent&, bool only_active = true) const; + int set_block_size (pframes_t nframes); ChanMapping input_map (uint32_t num) const { diff --git a/libs/ardour/ardour/processor.h b/libs/ardour/ardour/processor.h index 139a5cf592..ea982035bc 100644 --- a/libs/ardour/ardour/processor.h +++ b/libs/ardour/ardour/processor.h @@ -152,6 +152,8 @@ protected: virtual XMLNode& state (); virtual int set_state_2X (const XMLNode&, int version); + bool map_loop_range (samplepos_t& start, samplepos_t& end) const; + int _pending_active; bool _active; bool _next_ab_is_active; diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc index 21bc6b5d3d..5add2a2fe6 100644 --- a/libs/ardour/plugin_insert.cc +++ b/libs/ardour/plugin_insert.cc @@ -588,6 +588,53 @@ PluginInsert::set_block_size (pframes_t nframes) return ret; } +void +PluginInsert::automation_run (samplepos_t start, pframes_t nframes) +{ + // XXX does not work when rolling backwards + if (_loop_location && nframes > 0) { + const samplepos_t loop_start = _loop_location->start (); + const samplepos_t loop_end = _loop_location->end (); + const samplecnt_t looplen = loop_end - loop_start; + + samplecnt_t remain = nframes; + samplepos_t start_pos = start; + + while (remain > 0) { + if (start_pos >= loop_end) { + sampleoffset_t start_off = (start_pos - loop_start) % looplen; + start_pos = loop_start + start_off; + } + samplecnt_t move = std::min ((samplecnt_t)nframes, loop_end - start_pos); + + Automatable::automation_run (start_pos, move); + remain -= move; + start_pos += move; + } + return; + } + Automatable::automation_run (start, nframes); +} + +bool +PluginInsert::find_next_event (double now, double end, Evoral::ControlEvent& next_event, bool only_active) const +{ + bool rv = Automatable::find_next_event (now, end, next_event, only_active); + + if (_loop_location && now < end) { + if (rv) { + end = ceil (next_event.when); + } + const samplepos_t loop_end = _loop_location->end (); + assert (now < loop_end); // due to map_loop_range () + if (end > loop_end) { + next_event.when = loop_end; + rv = true; + } + } + return rv; +} + void PluginInsert::activate () { @@ -1215,6 +1262,9 @@ PluginInsert::automate_and_run (BufferSet& bufs, samplepos_t start, samplepos_t return; } + /* map start back into loop-range, adjust end */ + map_loop_range (start, end); + if (!find_next_event (start, end, next_event) || _plugins.front()->requires_fixed_sized_buffers()) { /* no events have a time within the relevant range */ @@ -1233,6 +1283,8 @@ PluginInsert::automate_and_run (BufferSet& bufs, samplepos_t start, samplepos_t offset += cnt; start += cnt; + map_loop_range (start, end); + if (!find_next_event (start, end, next_event)) { break; } diff --git a/libs/ardour/processor.cc b/libs/ardour/processor.cc index 19b6f30367..39c3d68ad7 100644 --- a/libs/ardour/processor.cc +++ b/libs/ardour/processor.cc @@ -275,6 +275,34 @@ Processor::configure_io (ChanCount in, ChanCount out) return true; } +bool +Processor::map_loop_range (samplepos_t& start, samplepos_t& end) const +{ + if (!_loop_location) { + return false; + } + if (start >= end) { + /* no backwards looping */ + return false; + } + + const samplepos_t loop_end = _loop_location->end (); + if (start < loop_end) { + return false; + } + + const samplepos_t loop_start = _loop_location->start (); + const samplecnt_t looplen = loop_end - loop_start; + const sampleoffset_t start_off = (start - loop_start) % looplen; + const samplepos_t start_pos = loop_start + start_off; + + assert (start >= start_pos); + end -= start - start_pos; + start = start_pos; + assert (end > start); + return true; +} + void Processor::set_display_to_user (bool yn) { -- cgit v1.2.3