towards export latency compensation
authorRobin Gareus <robin@gareus.org>
Sun, 10 Jul 2016 01:20:35 +0000 (03:20 +0200)
committerRobin Gareus <robin@gareus.org>
Sun, 10 Jul 2016 01:21:29 +0000 (03:21 +0200)
libs/ardour/ardour/session.h
libs/ardour/session.cc
libs/ardour/session_export.cc

index 82c9231cfb95fa2f10cee157b67525541e0ae50c..2f2b774c30c8c654185032c31c52c101e887bc52 100644 (file)
@@ -1266,6 +1266,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
        bool _exporting;
        bool _export_rolling;
        framepos_t _export_preroll;
+       framepos_t _export_latency;
 
        boost::shared_ptr<ExportHandler> export_handler;
        boost::shared_ptr<ExportStatus>  export_status;
index bb80621c258d7bd3adba9ea866432675b6c756bb..fb73ecbd3662bc8fbae70f53b40cbfa61e9b90a1 100644 (file)
@@ -213,6 +213,7 @@ Session::Session (AudioEngine &eng,
        , _exporting (false)
        , _export_rolling (false)
        , _export_preroll (0)
+       , _export_latency (0)
        , _pre_export_mmc_enabled (false)
        , _name (snapshot_name)
        , _is_new (true)
index efb731463f7151e2adcc50688e08f5669416655c..1dee1f8d3cef30e3716027116271433722358abb 100644 (file)
@@ -111,6 +111,21 @@ Session::start_audio_export (framepos_t position)
        }
 
        _export_preroll = Config->get_export_preroll() * nominal_frame_rate ();
+       if (_export_preroll == 0) {
+               // must be > 0 so that transport is started in sync.
+               _export_preroll = 1;
+       }
+
+       /* "worst_track_latency" is the correct value for stem-exports
+        * see to Route::add_export_point(),
+        *
+        * for master-bus export, we'd need to add the master's latency.
+        * or actually longest-total-session-latency.
+        *
+        * We can't use worst_playback_latency because that includes
+        * includes external latencies and would overcompensate.
+        */
+       _export_latency = worst_track_latency ();
 
        /* We're about to call Track::seek, so the butler must have finished everything
           up otherwise it could be doing do_refill in its thread while we are doing
@@ -212,9 +227,25 @@ Session::process_export_fw (pframes_t nframes)
                butler_transport_work ();
                g_atomic_int_set (&_butler->should_do_transport_work, 0);
                post_transport ();
+
                return 0;
        }
 
+       if (_export_latency > 0) {
+               framepos_t remain = std::min ((framepos_t)nframes, _export_latency);
+
+               _engine.main_thread()->get_buffers ();
+               process_without_events (remain);
+               _engine.main_thread()->drop_buffers ();
+
+               _export_latency -= remain;
+               nframes -= remain;
+
+               if (nframes == 0) {
+                       return 0;
+               }
+       }
+
        _engine.main_thread()->get_buffers ();
        process_export (nframes);
        _engine.main_thread()->drop_buffers ();