[Re]-Implement Delayline flush.
authorRobin Gareus <robin@gareus.org>
Sat, 4 Nov 2017 15:24:09 +0000 (16:24 +0100)
committerRobin Gareus <robin@gareus.org>
Sat, 4 Nov 2017 15:24:09 +0000 (16:24 +0100)
Also don't automatically flush the delayline at transport or monitor-
changes anymore.

With full-graph latency compensation, delaylines are before the
disk-reader, aligning input (disk uses read-ahead to align).

Flushing the delayline should only happen when input-monitoring
is disengaged. It's best degated to the Route or object using the
Delayline (potentially latency-aligned delayed flush).

libs/ardour/ardour/delayline.h
libs/ardour/delayline.cc

index 58e2aaca96123fd811c6889b3388b02c400c8fda..6ac4561e5d540ac5e52932de4c674e58e9bf8755 100644 (file)
@@ -40,21 +40,16 @@ public:
   DelayLine (Session& s, const std::string& name);
        ~DelayLine ();
 
-       bool display_to_user () const { return false; }
-
-       void run (BufferSet&, samplepos_t, samplepos_t, double, pframes_t, bool);
+       bool set_name (const std::string& str);
        bool set_delay (samplecnt_t signal_delay);
        samplecnt_t delay () { return _pending_delay; }
 
+       /* processor interface */
+       bool display_to_user () const { return false; }
+       void run (BufferSet&, samplepos_t, samplepos_t, double, pframes_t, bool);
        bool configure_io (ChanCount in, ChanCount out);
        bool can_support_io_configuration (const ChanCount& in, ChanCount& out);
-
        void flush ();
-       void realtime_handle_transport_stopped () { flush (); }
-       void realtime_locate () { flush (); }
-       void monitoring_changed () { flush (); }
-
-       bool set_name (const std::string& str);
 
 protected:
        XMLNode& state ();
index d0a691c5ffdbcf3ed3fbefc05efde1c9ccdb8fdb..72ea208126c2468fec13643dffa9818970bda34b 100644 (file)
@@ -69,6 +69,8 @@ DelayLine::run (BufferSet& bufs, samplepos_t /* start_sample */, samplepos_t /*
        const bool pending_flush = _pending_flush;
        _pending_flush = false;
 
+       // TODO handle pending_flush.
+
        /* Audio buffers */
        if (_buf.size () == bufs.count ().n_audio () && _buf.size () > 0) {
 
@@ -155,6 +157,26 @@ DelayLine::run (BufferSet& bufs, samplepos_t /* start_sample */, samplepos_t /*
                /* set new delay */
                _delay = pending_delay;
 
+               if (pending_flush) {
+                       /* fade out data after read-pointer, clear buffer until write-pointer */
+                       const samplecnt_t fade_out_len = std::min (_delay, (samplecnt_t)FADE_LEN);
+
+                       for (AudioDlyBuf::iterator i = _buf.begin(); i != _buf.end (); ++i) {
+                               Sample* rb = (*i).get ();
+                               uint32_t s = 0;
+                               for (; s < fade_out_len; ++s) {
+                                       sampleoffset_t off = (_roff + s) % _bsiz;
+                                       rb[off] *= 1. - (s / (float) fade_out_len);
+                               }
+                               for (; s < _delay; ++s) {
+                                       sampleoffset_t off = (_roff + s) % _bsiz;
+                                       rb[off] = 0;
+                               }
+                               assert (_woff == ((_roff + s) % _bsiz));
+                       }
+                       // TODO consider adding a fade-in to bufs
+               }
+
                /* delay audio buffers */
                assert (_delay == ((_woff - _roff + _bsiz) % _bsiz));
                AudioDlyBuf::iterator bi = _buf.begin ();