Fix MIDI delaylines
MidiBuffer::read_from() clears the buffer, so events were not accumulated into the delay-buffer. This also includes a small optimization and comments for the variable delayline.
This commit is contained in:
parent
a899136cae
commit
25098edfc1
@ -231,30 +231,34 @@ DelayLine::run (BufferSet& bufs, samplepos_t /* start_sample */, samplepos_t /*
|
|||||||
dly->silence (n_samples);
|
dly->silence (n_samples);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the delay time changes, iterate over all events in the dly-buffer
|
if (delay_diff != 0) {
|
||||||
// and adjust the time in-place. <= 0 becomes 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.
|
* iterate over all events in dly-buffer and subtract one cycle
|
||||||
for (MidiBuffer::iterator m = dly->begin (); m != dly->end (); ++m) {
|
* (n_samples) from the timestamp, bringing them closer to de-queue.
|
||||||
MidiBuffer::TimeType *t = m.timeptr ();
|
*/
|
||||||
if (*t > n_samples + delay_diff) {
|
for (MidiBuffer::iterator m = dly->begin (); m != dly->end (); ++m) {
|
||||||
*t -= n_samples + delay_diff;
|
MidiBuffer::TimeType *t = m.timeptr ();
|
||||||
} else {
|
if (*t > n_samples + delay_diff) {
|
||||||
*t = 0;
|
*t -= n_samples + delay_diff;
|
||||||
|
} else {
|
||||||
|
*t = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_delay != 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) {
|
for (MidiBuffer::iterator m = mb.begin (); m != mb.end (); ++m) {
|
||||||
MidiBuffer::TimeType *t = m.timeptr ();
|
MidiBuffer::TimeType *t = m.timeptr ();
|
||||||
*t += _delay;
|
*t += _delay;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// move events from dly-buffer into current-buffer until n_samples
|
/* move events from dly-buffer into current-buffer until n_samples
|
||||||
// and remove them from the dly-buffer
|
* and remove them from the dly-buffer
|
||||||
|
*/
|
||||||
for (MidiBuffer::iterator m = dly->begin (); m != dly->end ();) {
|
for (MidiBuffer::iterator m = dly->begin (); m != dly->end ();) {
|
||||||
const Evoral::Event<MidiBuffer::TimeType> ev (*m, false);
|
const Evoral::Event<MidiBuffer::TimeType> ev (*m, false);
|
||||||
if (ev.time () >= n_samples) {
|
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)
|
* (ie '_global_port_buffer_offset + _port_buffer_offset' - midi_port.cc)
|
||||||
*/
|
*/
|
||||||
if (_delay != 0) {
|
if (_delay != 0) {
|
||||||
// move events after n_samples from current-buffer into dly-buffer
|
/* move events after n_samples from current-buffer into dly-buffer
|
||||||
// and trim current-buffer after n_samples
|
* and trim current-buffer after n_samples
|
||||||
|
*/
|
||||||
for (MidiBuffer::iterator m = mb.begin (); m != mb.end ();) {
|
for (MidiBuffer::iterator m = mb.begin (); m != mb.end ();) {
|
||||||
const Evoral::Event<MidiBuffer::TimeType> ev (*m, false);
|
const Evoral::Event<MidiBuffer::TimeType> ev (*m, false);
|
||||||
if (ev.time () < n_samples) {
|
if (ev.time () < n_samples) {
|
||||||
++m;
|
++m;
|
||||||
continue;
|
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);
|
dly->insert_event (ev);
|
||||||
m = mb.erase (m);
|
m = mb.erase (m);
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,39 @@ FixedDelay::delay (
|
|||||||
assert (id < _buffers[dt].size ());
|
assert (id < _buffers[dt].size ());
|
||||||
DelayBuffer *db = _buffers[dt][id];
|
DelayBuffer *db = _buffers[dt][id];
|
||||||
|
|
||||||
|
ARDOUR::MidiBuffer const* mb;
|
||||||
|
if ((mb = dynamic_cast<ARDOUR::MidiBuffer const*> (&in))) {
|
||||||
|
ARDOUR::MidiBuffer* mout = dynamic_cast<ARDOUR::MidiBuffer*> (&out);
|
||||||
|
ARDOUR::MidiBuffer* mdly = dynamic_cast<ARDOUR::MidiBuffer*> (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<MidiBuffer::TimeType> 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<MidiBuffer::TimeType> 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) {
|
if (db->pos + n_samples > _buf_size) {
|
||||||
uint32_t w0 = _buf_size - db->pos;
|
uint32_t w0 = _buf_size - db->pos;
|
||||||
uint32_t w1 = db->pos + n_samples - _buf_size;
|
uint32_t w1 = db->pos + n_samples - _buf_size;
|
||||||
|
Loading…
Reference in New Issue
Block a user