diff --git a/libs/ardour/delayline.cc b/libs/ardour/delayline.cc index 8e5d8c4227..d3f4982f79 100644 --- a/libs/ardour/delayline.cc +++ b/libs/ardour/delayline.cc @@ -231,30 +231,34 @@ DelayLine::run (BufferSet& bufs, samplepos_t /* start_sample */, samplepos_t /* dly->silence (n_samples); } - // If the delay time changes, iterate over all events in the dly-buffer - // and adjust the time in-place. <= 0 becomes 0. - // - // iterate over all events in dly-buffer and subtract one cycle - // (n_samples) from the timestamp, bringing them closer to de-queue. - for (MidiBuffer::iterator m = dly->begin (); m != dly->end (); ++m) { - MidiBuffer::TimeType *t = m.timeptr (); - if (*t > n_samples + delay_diff) { - *t -= n_samples + delay_diff; - } else { - *t = 0; + if (delay_diff != 0) { + /* If the delay time changes, iterate over all events in the dly-buffer + * and adjust the time in-place. <= 0 becomes 0. + * + * iterate over all events in dly-buffer and subtract one cycle + * (n_samples) from the timestamp, bringing them closer to de-queue. + */ + for (MidiBuffer::iterator m = dly->begin (); m != dly->end (); ++m) { + MidiBuffer::TimeType *t = m.timeptr (); + if (*t > n_samples + delay_diff) { + *t -= n_samples + delay_diff; + } else { + *t = 0; + } } } if (_delay != 0) { - // delay events in current-buffer, in place. + /* delay events in current-buffer, in place. */ for (MidiBuffer::iterator m = mb.begin (); m != mb.end (); ++m) { MidiBuffer::TimeType *t = m.timeptr (); *t += _delay; } } - // move events from dly-buffer into current-buffer until n_samples - // and remove them from the dly-buffer + /* move events from dly-buffer into current-buffer until n_samples + * and remove them from the dly-buffer + */ for (MidiBuffer::iterator m = dly->begin (); m != dly->end ();) { const Evoral::Event ev (*m, false); if (ev.time () >= n_samples) { @@ -269,14 +273,19 @@ DelayLine::run (BufferSet& bufs, samplepos_t /* start_sample */, samplepos_t /* * (ie '_global_port_buffer_offset + _port_buffer_offset' - midi_port.cc) */ if (_delay != 0) { - // move events after n_samples from current-buffer into dly-buffer - // and trim current-buffer after n_samples + /* move events after n_samples from current-buffer into dly-buffer + * and trim current-buffer after n_samples + */ for (MidiBuffer::iterator m = mb.begin (); m != mb.end ();) { const Evoral::Event ev (*m, false); if (ev.time () < n_samples) { ++m; continue; } + /* insert_event() is expensive, if delay_diff is zero, the + * event must be later than the last event in the delay-buffer + * and push_back() would be preferable. + */ dly->insert_event (ev); m = mb.erase (m); } diff --git a/libs/ardour/fixed_delay.cc b/libs/ardour/fixed_delay.cc index b55e4f6f56..6606197047 100644 --- a/libs/ardour/fixed_delay.cc +++ b/libs/ardour/fixed_delay.cc @@ -131,6 +131,39 @@ FixedDelay::delay ( assert (id < _buffers[dt].size ()); DelayBuffer *db = _buffers[dt][id]; + ARDOUR::MidiBuffer const* mb; + if ((mb = dynamic_cast (&in))) { + ARDOUR::MidiBuffer* mout = dynamic_cast (&out); + ARDOUR::MidiBuffer* mdly = dynamic_cast (db->buf); + assert (mout && mdly); + + mout->clear (); + + /* delay events from input buffer and append them to the + * corresponding buffer. + */ + for (MidiBuffer::const_iterator m = mb->begin (); m != mb->end (); ++m) { + Evoral::Event ev (*m, false); + ev.set_time (ev.time () + _delay); + if (ev.time () < n_samples) { + mout->push_back (ev); + } else { + mdly->push_back (ev); + } + } + + /* move events from the delay-buffer into output */ + for (MidiBuffer::iterator m = mdly->begin (); m != mdly->end ();) { + const Evoral::Event ev (*m, false); + if (ev.time () >= n_samples) { + break; + } + mout->push_back (ev); + m = mdly->erase (m); + } + return; + } + if (db->pos + n_samples > _buf_size) { uint32_t w0 = _buf_size - db->pos; uint32_t w1 = db->pos + n_samples - _buf_size;