improve debug output
[ardour.git] / libs / ardour / delayline.cc
1 /*
2  * Copyright (C) 2014-2017 Robin Gareus <robin@gareus.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include <assert.h>
20 #include <cmath>
21
22 #include "pbd/compose.h"
23
24 #include "ardour/audio_buffer.h"
25 #include "ardour/buffer_set.h"
26 #include "ardour/debug.h"
27 #include "ardour/delayline.h"
28 #include "ardour/midi_buffer.h"
29 #include "ardour/runtime_functions.h"
30
31 #define MAX_BUFFER_SIZE 8192
32
33 using namespace std;
34 using namespace PBD;
35 using namespace ARDOUR;
36
37 DelayLine::DelayLine (Session& s, const std::string& name)
38     : Processor (s, string_compose ("latcomp-%1-%2", name, this))
39                 , _bsiz (0)
40                 , _delay (0)
41                 , _pending_delay (0)
42                 , _roff (0)
43                 , _woff (0)
44                 , _pending_flush (false)
45 {
46 }
47
48 DelayLine::~DelayLine ()
49 {
50 }
51
52 bool
53 DelayLine::set_name (const string& name)
54 {
55         return Processor::set_name (string_compose ("latcomp-%1-%2", name, this));
56 }
57
58 #define FADE_LEN (128)
59
60 void
61 DelayLine::run (BufferSet& bufs, samplepos_t /* start_sample */, samplepos_t /* end_sample */, double /* speed */, pframes_t n_samples, bool)
62 {
63 #ifndef NDEBUG
64         Glib::Threads::Mutex::Lock lm (_set_delay_mutex, Glib::Threads::TRY_LOCK);
65         assert (lm.locked ());
66 #endif
67         assert (n_samples <= MAX_BUFFER_SIZE);
68
69         const sampleoffset_t pending_delay = _pending_delay;
70         sampleoffset_t delay_diff = _delay - pending_delay;
71         const bool pending_flush = _pending_flush;
72
73         if (delay_diff == 0 && _delay == 0) {
74                 return;
75         }
76
77         _pending_flush = false;
78
79         // TODO handle pending_flush.
80
81         /* Audio buffers */
82         if (_buf.size () == bufs.count ().n_audio () && _buf.size () > 0) {
83
84                 /* handle delay-changes first */
85                 if (delay_diff < 0) {
86                         /* delay increases: fade out, insert silence, fade-in */
87                         const samplecnt_t fade_in_len = std::min (n_samples, (pframes_t)FADE_LEN);
88                         samplecnt_t fade_out_len;
89
90                         if (_delay < FADE_LEN) {
91                                 /* if old delay was 0 or smaller than new-delay, add some data to fade.
92                                  * Add at most (FADE_LEN - _delay) samples, but no more than -delay_diff
93                                  */
94                                 samplecnt_t add = std::min ((samplecnt_t)FADE_LEN - _delay, (samplecnt_t) -delay_diff);
95                                 fade_out_len = std::min (_delay + add, (samplecnt_t)FADE_LEN);
96
97                                 if (add > 0) {
98                                         AudioDlyBuf::iterator bi = _buf.begin ();
99                                         for (BufferSet::audio_iterator i = bufs.audio_begin (); i != bufs.audio_end (); ++i, ++bi) {
100                                                 Sample* rb = (*bi).get ();
101                                                 write_to_rb (rb, i->data (), add);
102                                         }
103                                         _woff = (_woff + add) & _bsiz_mask;
104                                         delay_diff += add;
105                                 }
106                         } else {
107                                 fade_out_len = FADE_LEN;
108                         }
109
110                         /* fade-out, end of previously written data */
111                         for (AudioDlyBuf::iterator i = _buf.begin(); i != _buf.end (); ++i) {
112                                 Sample* rb = (*i).get ();
113                                 for (uint32_t s = 0; s < fade_out_len; ++s) {
114                                         sampleoffset_t off = (_woff + _bsiz - s) & _bsiz_mask;
115                                         rb[off] *= s / (float) fade_out_len;
116                                 }
117                                 /* clear data in rb */
118                                 // TODO optimize this using memset
119                                 for (uint32_t s = 0; s < -delay_diff; ++s) {
120                                         sampleoffset_t off = (_woff + _bsiz + s) & _bsiz_mask;
121                                         rb[off] = 0.f;
122                                 }
123                         }
124
125                         _woff = (_woff - delay_diff) & _bsiz_mask;
126
127                         /* fade-in, directly apply to input buffer */
128                         for (BufferSet::audio_iterator i = bufs.audio_begin (); i != bufs.audio_end (); ++i) {
129                                 Sample* src = i->data ();
130                                 for (uint32_t s = 0; s < fade_in_len; ++s) {
131                                         src[s] *= s / (float) fade_in_len;
132                                 }
133                         }
134                 } else if (delay_diff > 0) {
135                         /* delay decreases: cross-fade, if possible */
136                         const samplecnt_t fade_out_len = std::min (_delay, (samplecnt_t)FADE_LEN);
137                         const samplecnt_t fade_in_len = std::min (n_samples, (pframes_t)FADE_LEN);
138                         const samplecnt_t xfade_len = std::min (fade_out_len, fade_in_len);
139
140                         AudioDlyBuf::iterator bi = _buf.begin ();
141                         for (BufferSet::audio_iterator i = bufs.audio_begin (); i != bufs.audio_end (); ++i, ++bi) {
142                                 Sample* rb = (*bi).get ();
143                                 Sample* src = i->data ();
144
145                                 // TODO consider handling fade_out & fade_in separately
146                                 // if fade_out_len < fade_in_len.
147                                 for (uint32_t s = 0; s < xfade_len; ++s) {
148                                         sampleoffset_t off = (_roff + s) & _bsiz_mask;
149                                         const gain_t g = s / (float) xfade_len;
150                                         src[s] *= g;
151                                         src[s] += (1.f - g) * rb[off];
152                                 }
153                         }
154
155 #ifndef NDEBUG
156                         sampleoffset_t check = (_roff + delay_diff) & _bsiz_mask;
157 #endif
158                         _roff = (_woff + _bsiz - pending_delay) & _bsiz_mask;
159 #ifndef NDEBUG
160                         assert (_roff == check);
161 #endif
162                 }
163
164                 /* set new delay */
165                 _delay = pending_delay;
166
167                 if (pending_flush) {
168                         /* fade out data after read-pointer, clear buffer until write-pointer */
169                         const samplecnt_t fade_out_len = std::min (_delay, (samplecnt_t)FADE_LEN);
170
171                         for (AudioDlyBuf::iterator i = _buf.begin(); i != _buf.end (); ++i) {
172                                 Sample* rb = (*i).get ();
173                                 uint32_t s = 0;
174                                 for (; s < fade_out_len; ++s) {
175                                         sampleoffset_t off = (_roff + s) & _bsiz_mask;
176                                         rb[off] *= 1. - (s / (float) fade_out_len);
177                                 }
178                                 for (; s < _delay; ++s) {
179                                         sampleoffset_t off = (_roff + s) & _bsiz_mask;
180                                         rb[off] = 0;
181                                 }
182                                 assert (_woff == ((_roff + s) & _bsiz_mask));
183                         }
184                         // TODO consider adding a fade-in to bufs
185                 }
186
187                 /* delay audio buffers */
188                 assert (_delay == ((_woff - _roff + _bsiz) & _bsiz_mask));
189                 AudioDlyBuf::iterator bi = _buf.begin ();
190                 if (_delay == 0) {
191                         /* do nothing */
192                 } else if (n_samples <= _delay) {
193                         /* write all samples to rb, read all from rb */
194                         for (BufferSet::audio_iterator i = bufs.audio_begin (); i != bufs.audio_end (); ++i, ++bi) {
195                                 Sample* rb = (*bi).get ();
196                                 write_to_rb (rb, i->data (), n_samples);
197                                 read_from_rb (rb, i->data (), n_samples);
198                         }
199                         _roff = (_roff + n_samples) & _bsiz_mask;
200                         _woff = (_woff + n_samples) & _bsiz_mask;
201                 } else {
202                         /* only write _delay samples to ringbuffer, memmove buffer */
203                         samplecnt_t tail = n_samples - _delay;
204                         for (BufferSet::audio_iterator i = bufs.audio_begin (); i != bufs.audio_end (); ++i, ++bi) {
205                                 Sample* rb = (*bi).get ();
206                                 Sample* src = i->data ();
207                                 write_to_rb (rb, &src[tail], _delay);
208                                 memmove (&src[_delay], src, tail * sizeof(Sample));
209                                 read_from_rb (rb, src, _delay);
210                         }
211                         _roff = (_roff + _delay) & _bsiz_mask;
212                         _woff = (_woff + _delay) & _bsiz_mask;
213                 }
214         } else {
215                 /* set new delay for MIDI only */
216                 _delay = pending_delay;
217
218                 /* prepare for the case that an audio-port is added */
219                 _woff = _delay;
220                 _roff = 0;
221         }
222
223         if (_midi_buf.get ()) {
224                 for (BufferSet::midi_iterator i = bufs.midi_begin (); i != bufs.midi_end (); ++i) {
225                         if (i != bufs.midi_begin ()) { break; } // XXX only one buffer for now
226
227                         MidiBuffer* dly = _midi_buf.get ();
228                         MidiBuffer& mb (*i);
229                         if (pending_flush) {
230                                 dly->silence (n_samples);
231                         }
232
233                         // If the delay time changes, iterate over all events in the dly-buffer
234                         // and adjust the time in-place. <= 0 becomes 0.
235                         //
236                         // iterate over all events in dly-buffer and subtract one cycle
237                         // (n_samples) from the timestamp, bringing them closer to de-queue.
238                         for (MidiBuffer::iterator m = dly->begin (); m != dly->end (); ++m) {
239                                 MidiBuffer::TimeType *t = m.timeptr ();
240                                 if (*t > n_samples + delay_diff) {
241                                         *t -= n_samples + delay_diff;
242                                 } else {
243                                         *t = 0;
244                                 }
245                         }
246
247                         if (_delay != 0) {
248                                 // delay events in current-buffer, in place.
249                                 for (MidiBuffer::iterator m = mb.begin (); m != mb.end (); ++m) {
250                                         MidiBuffer::TimeType *t = m.timeptr ();
251                                         *t += _delay;
252                                 }
253                         }
254
255                         // move events from dly-buffer into current-buffer until n_samples
256                         // and remove them from the dly-buffer
257                         for (MidiBuffer::iterator m = dly->begin (); m != dly->end ();) {
258                                 const Evoral::Event<MidiBuffer::TimeType> ev (*m, false);
259                                 if (ev.time () >= n_samples) {
260                                         break;
261                                 }
262                                 mb.insert_event (ev);
263                                 m = dly->erase (m);
264                         }
265
266                         /* For now, this is only relevant if there is there's a positive delay.
267                          * In the future this could also be used to delay 'too early' events
268                          * (ie '_global_port_buffer_offset + _port_buffer_offset' - midi_port.cc)
269                          */
270                         if (_delay != 0) {
271                                 // move events after n_samples from current-buffer into dly-buffer
272                                 // and trim current-buffer after n_samples
273                                 for (MidiBuffer::iterator m = mb.begin (); m != mb.end ();) {
274                                         const Evoral::Event<MidiBuffer::TimeType> ev (*m, false);
275                                         if (ev.time () < n_samples) {
276                                                 ++m;
277                                                 continue;
278                                         }
279                                         dly->insert_event (ev);
280                                         m = mb.erase (m);
281                                 }
282                         }
283                 }
284         }
285 }
286
287 bool
288 DelayLine::set_delay (samplecnt_t signal_delay)
289 {
290 #ifndef NDEBUG
291         Glib::Threads::Mutex::Lock lm (_set_delay_mutex, Glib::Threads::TRY_LOCK);
292         assert (lm.locked ());
293 #endif
294
295         if (signal_delay < 0) {
296                 signal_delay = 0;
297                 cerr << "WARNING: latency compensation is not possible.\n";
298         }
299
300         if (signal_delay == _pending_delay) {
301                 DEBUG_TRACE (DEBUG::LatencyCompensation,
302                                 string_compose ("%1 set_delay - no change: %2 samples for %3 channels\n",
303                                         name (), signal_delay, _configured_output.n_audio ()));
304                 return false;
305         }
306
307         DEBUG_TRACE (DEBUG::LatencyCompensation,
308                         string_compose ("%1 set_delay to %2 samples for %3 channels\n",
309                                 name (), signal_delay, _configured_output.n_audio ()));
310
311         if (signal_delay + MAX_BUFFER_SIZE + 1 > _bsiz) {
312                 allocate_pending_buffers (signal_delay, _configured_output);
313         }
314
315         _pending_delay = signal_delay;
316         return true;
317 }
318
319 bool
320 DelayLine::can_support_io_configuration (const ChanCount& in, ChanCount& out)
321 {
322         out = in;
323         return true;
324 }
325
326 void
327 DelayLine::allocate_pending_buffers (samplecnt_t signal_delay, ChanCount const& cc)
328 {
329         assert (signal_delay >= 0);
330 #if 1
331         /* If no buffers are required, don't allocate any.
332          * This may backfire later, allocating buffers on demand
333          * may take time and cause x-runs.
334          *
335          * The default buffersize is 4 * 16kB and - once allocated -
336          * usually sufficies for the lifetime of the delayline instance.
337          */
338         if (signal_delay == _pending_delay && signal_delay == 0) {
339                 return;
340         }
341 #endif
342         samplecnt_t rbs = signal_delay + MAX_BUFFER_SIZE + 1;
343         rbs = std::max (_bsiz, rbs);
344
345         uint64_t power_of_two;
346         for (power_of_two = 1; 1 << power_of_two < rbs; ++power_of_two) {}
347         rbs = 1 << power_of_two;
348
349         if (cc.n_audio () == _buf.size () && _bsiz == rbs) {
350                 return;
351         }
352
353         if (cc.n_audio () == 0) {
354                 return;
355         }
356
357         AudioDlyBuf pending_buf;
358         for (uint32_t i = 0; i < cc.n_audio (); ++i) {
359                 boost::shared_array<Sample> b (new Sample[rbs]);
360                 pending_buf.push_back (b);
361                 memset (b.get (), 0, rbs * sizeof (Sample));
362         }
363
364         AudioDlyBuf::iterator bo = _buf.begin ();
365         AudioDlyBuf::iterator bn = pending_buf.begin ();
366
367         sampleoffset_t offset = (_roff <= _woff) ? 0 : rbs - _bsiz;
368
369         for (; bo != _buf.end () && bn != pending_buf.end(); ++bo, ++bn) {
370                 Sample* rbo = (*bo).get ();
371                 Sample* rbn = (*bn).get ();
372                 if (_roff == _woff) {
373                         continue;
374                 } else if (_roff < _woff) {
375                         /* copy data between _roff .. _woff to new buffer */
376                         copy_vector (&rbn[_roff], &rbo[_roff], _woff - _roff);
377                 } else {
378                         /* copy data between _roff .. old_size to end of new buffer, increment _roff
379                          * copy data from 0.._woff to beginning of new buffer
380                          */
381                         copy_vector (&rbn[_roff + offset], &rbo[_roff], _bsiz - _roff);
382                         copy_vector (rbn, rbo, _woff);
383                 }
384         }
385
386         assert (signal_delay >= _pending_delay);
387         assert ((_roff <= (_woff + signal_delay - _pending_delay) & (rbs -1)) || offset > 0);
388         _roff += offset;
389         assert (_roff < rbs);
390
391         _bsiz = rbs;
392         _bsiz_mask = _bsiz - 1;
393         _buf.swap (pending_buf);
394 }
395
396 bool
397 DelayLine::configure_io (ChanCount in, ChanCount out)
398 {
399 #ifndef NDEBUG
400         Glib::Threads::Mutex::Lock lm (_set_delay_mutex, Glib::Threads::TRY_LOCK);
401         assert (lm.locked ());
402 #endif
403
404         if (out != in) { // always 1:1
405                 return false;
406         }
407
408         if (_configured_output != out) {
409                 allocate_pending_buffers (_pending_delay, out);
410         }
411
412         DEBUG_TRACE (DEBUG::LatencyCompensation,
413                         string_compose ("configure IO: %1 Ain: %2 Aout: %3 Min: %4 Mout: %5\n",
414                                 name (), in.n_audio (), out.n_audio (), in.n_midi (), out.n_midi ()));
415
416         // TODO support multiple midi buffers
417         if (in.n_midi () > 0 && !_midi_buf) {
418                 _midi_buf.reset (new MidiBuffer (16384));
419         }
420 #ifndef NDEBUG
421         lm.release ();
422 #endif
423
424         return Processor::configure_io (in, out);
425 }
426
427 void
428 DelayLine::flush ()
429 {
430         _pending_flush = true;
431 }
432
433 XMLNode&
434 DelayLine::state ()
435 {
436         XMLNode& node (Processor::state ());
437         node.set_property ("type", "delay");
438         return node;
439 }
440
441 void
442 DelayLine::write_to_rb (Sample* rb, Sample* src, samplecnt_t n_samples)
443 {
444         assert (n_samples < _bsiz);
445         if (_woff + n_samples < _bsiz) {
446                 copy_vector (&rb[_woff], src, n_samples);
447         } else {
448                 const samplecnt_t s0 = _bsiz - _woff;
449                 const samplecnt_t s1 = n_samples - s0;
450
451                 copy_vector (&rb[_woff], src, s0);
452                 copy_vector (rb, &src[s0], s1);
453         }
454 }
455
456 void
457 DelayLine::read_from_rb (Sample* rb, Sample* dst, samplecnt_t n_samples)
458 {
459         assert (n_samples < _bsiz);
460         if (_roff + n_samples < _bsiz) {
461                 copy_vector (dst, &rb[_roff], n_samples);
462         } else {
463                 const samplecnt_t s0 = _bsiz - _roff;
464                 const samplecnt_t s1 = n_samples - s0;
465
466                 copy_vector (dst, &rb[_roff], s0);
467                 copy_vector (&dst[s0], rb, s1);
468         }
469 }