framework for silent-roll-while-slave-syncing
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 20 Jul 2017 21:53:56 +0000 (17:53 -0400)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 18 Sep 2017 15:40:53 +0000 (11:40 -0400)
libs/ardour/ardour/disk_reader.h
libs/ardour/disk_reader.cc
libs/ardour/session_process.cc

index faeeaf1f529e4a75c0aa64f1a8b8ecdf3a3e3791..c07dbab585b1465474837cf03ff7684af34297ca 100644 (file)
@@ -99,6 +99,8 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor
 
        static void set_midi_readahead_frames (framecnt_t frames_ahead) { midi_readahead = frames_ahead; }
 
+       static void set_no_disk_output (bool yn);
+
   protected:
        friend class Track;
        friend class MidiTrack;
@@ -126,6 +128,7 @@ class LIBARDOUR_API DiskReader : public DiskIOProcessor
 
        static framecnt_t _chunk_frames;
        static framecnt_t midi_readahead;
+       static bool       no_disk_output;
 
        /* The MIDI stuff */
 
index 918761e5371cb6812a3456d256bca5d838f7fc88..c7221ad90fa7fc99bdc37d1558a75e37f425b030 100644 (file)
@@ -44,6 +44,7 @@ PBD::Signal0<void> DiskReader::Underrun;
 Sample* DiskReader::_mixdown_buffer = 0;
 gain_t* DiskReader::_gain_buffer = 0;
 framecnt_t DiskReader::midi_readahead = 4096;
+bool DiskReader::no_disk_output = false;
 
 DiskReader::DiskReader (Session& s, string const & str, DiskIOProcessor::Flag f)
        : DiskIOProcessor (s, str, f)
@@ -289,7 +290,7 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
                        }
                }
 
-               /* if monitoring disk but locating, put silence in the buffers */
+               /* if monitoring disk but locating put silence in the buffers */
 
                if (still_locating && (ms == MonitoringDisk)) {
                        bufs.silence (playback_distance, 0);
@@ -380,7 +381,7 @@ DiskReader::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame,
 
                        chaninfo->buf->increment_read_ptr (playback_distance);
 
-                       if ((speed != 0.0) && (ms & MonitoringInput)) {
+                       if (!no_disk_output && (speed != 0.0) && (ms & MonitoringInput)) {
                                /* mix the disk signal into the input signal (already in bufs) */
                                mix_buffers_no_gain (output.data(), disk_signal, speed == 0.0 ? nframes : playback_distance);
                        }
@@ -1465,3 +1466,16 @@ DiskReader::refill_midi ()
 
        return ret;
 }
+
+void
+DiskReader::set_no_disk_output (bool yn)
+{
+       /* this MUST be called as part of the process call tree, before any
+          disk readers are invoked. We use it when the session needs the
+          transport (and thus effective read position for DiskReaders) to keep
+          advancing as part of syncing up with a transport master, but we
+          don't want any actual disk output yet because we are still not
+          synced.
+       */
+       no_disk_output = yn;
+}
index 19a6b647209294879c886d5fab2124dd58669e10..9229372b4396bdcf106d7fbc55bdce56b89b03f8 100644 (file)
@@ -32,6 +32,7 @@
 #include "ardour/butler.h"
 #include "ardour/cycle_timer.h"
 #include "ardour/debug.h"
+#include "ardour/disk_reader.h"
 #include "ardour/graph.h"
 #include "ardour/port.h"
 #include "ardour/process_thread.h"
@@ -235,43 +236,10 @@ Session::process_routes (pframes_t nframes, bool& need_butler)
 int
 Session::silent_process_routes (pframes_t nframes, bool& need_butler)
 {
-       boost::shared_ptr<RouteList> r = routes.reader ();
-
-       const framepos_t start_frame = _transport_frame;
-       const framepos_t end_frame = _transport_frame + lrintf(nframes * _transport_speed);
-
-       VCAList v = _vca_manager->vcas ();
-       for (VCAList::const_iterator i = v.begin(); i != v.end(); ++i) {
-               (*i)->automation_run (start_frame, nframes);
-       }
-
-       _global_locate_pending = locate_pending();
-
-       if (_process_graph) {
-               _process_graph->silent_process_routes (nframes, start_frame, end_frame, need_butler);
-       } else {
-               for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
-
-                       int ret;
-
-                       if ((*i)->is_auditioner()) {
-                               continue;
-                       }
-
-                       bool b = false;
-
-                       if ((ret = (*i)->silent_roll (nframes, start_frame, end_frame, b)) < 0) {
-                               stop_transport ();
-                               return -1;
-                       }
-
-                       if (b) {
-                               need_butler = true;
-                       }
-               }
-       }
-
-       return 0;
+       DiskReader::set_no_disk_output (true);
+       int ret = process_routes (nframes, need_butler);
+       DiskReader::set_no_disk_output (false);
+       return ret;
 }
 
 void