mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-03 04:09:29 +01:00
Wrap automation on loop-position, split plugin processing
This commit is contained in:
parent
c411e05b6f
commit
c291cb64b1
4 changed files with 85 additions and 0 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue