diff options
author | Robin Gareus <robin@gareus.org> | 2016-07-14 04:34:18 +0200 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2016-07-14 04:35:48 +0200 |
commit | e55ef88ee9c95cb7e24077e78f459dbbbf615202 (patch) | |
tree | 7ea86fca55dbe72e25f0a2a6b81637618ab2c8d7 /libs/ardour | |
parent | d46e8a3d8b0077b9e31f02a1d024a41618f05704 (diff) |
refactoring to prepare for real-time export
* add a threaded TmpFile Writer
* update API calls to that process_export_fw() can be used as
process_function
The idea is to re-use export infrastructure from normalization:
export to a tmp-file and then encode target formats after that.
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/audioengine.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/export_graph_builder.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 7 | ||||
-rw-r--r-- | libs/ardour/export_graph_builder.cc | 1 | ||||
-rw-r--r-- | libs/ardour/session.cc | 1 | ||||
-rw-r--r-- | libs/ardour/session_export.cc | 74 |
6 files changed, 59 insertions, 28 deletions
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index 7bb7aa3a4d..cb5b82d058 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -161,7 +161,7 @@ class LIBARDOUR_API AudioEngine : public PortManager, public SessionHandlePtr (the regular process() call to session->process() is not made) */ - PBD::Signal1<int, pframes_t> Freewheel; + PBD::Signal1<void, pframes_t> Freewheel; PBD::Signal0<void> Xrun; diff --git a/libs/ardour/ardour/export_graph_builder.h b/libs/ardour/ardour/export_graph_builder.h index df02c9eb57..68eb927513 100644 --- a/libs/ardour/ardour/export_graph_builder.h +++ b/libs/ardour/ardour/export_graph_builder.h @@ -41,6 +41,7 @@ namespace AudioGrapher { template <typename T> class SndfileWriter; template <typename T> class SilenceTrimmer; template <typename T> class TmpFile; + template <typename T> class TmpFileRt; template <typename T> class Threader; template <typename T> class AllocatingProcessContext; } @@ -164,6 +165,7 @@ class LIBARDOUR_API ExportGraphBuilder typedef boost::shared_ptr<AudioGrapher::LoudnessReader> LoudnessReaderPtr; typedef boost::shared_ptr<AudioGrapher::Normalizer> NormalizerPtr; typedef boost::shared_ptr<AudioGrapher::TmpFile<Sample> > TmpFilePtr; + typedef boost::shared_ptr<AudioGrapher::TmpFileRt<Sample> > TmpFileRtPtr; typedef boost::shared_ptr<AudioGrapher::Threader<Sample> > ThreaderPtr; typedef boost::shared_ptr<AudioGrapher::AllocatingProcessContext<Sample> > BufferPtr; diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index c6f32bbe07..db80ddcae3 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -704,7 +704,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop boost::shared_ptr<ExportHandler> get_export_handler (); boost::shared_ptr<ExportStatus> get_export_status (); - int start_audio_export (framepos_t position); + int start_audio_export (framepos_t position, bool realtime = false); PBD::Signal1<int, framecnt_t> ProcessExport; static PBD::Signal2<void,std::string, std::string> Exported; @@ -1230,8 +1230,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop void process_without_events (pframes_t); void process_with_events (pframes_t); void process_audition (pframes_t); - int process_export (pframes_t); - int process_export_fw (pframes_t); + void process_export (pframes_t); + void process_export_fw (pframes_t); void block_processing() { g_atomic_int_set (&processing_prohibited, 1); } void unblock_processing() { g_atomic_int_set (&processing_prohibited, 0); } @@ -1268,6 +1268,7 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop bool _exporting; bool _export_rolling; + bool _realtime_export; framepos_t _export_preroll; framepos_t _export_latency; diff --git a/libs/ardour/export_graph_builder.cc b/libs/ardour/export_graph_builder.cc index 27b2f6948e..49b40a6736 100644 --- a/libs/ardour/export_graph_builder.cc +++ b/libs/ardour/export_graph_builder.cc @@ -36,6 +36,7 @@ #include "audiographer/general/silence_trimmer.h" #include "audiographer/general/threader.h" #include "audiographer/sndfile/tmp_file.h" +#include "audiographer/sndfile/tmp_file_rt.h" #include "audiographer/sndfile/sndfile_writer.h" #include "ardour/audioengine.h" diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 67f43dc470..9ab82c7106 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -213,6 +213,7 @@ Session::Session (AudioEngine &eng, , post_export_position (0) , _exporting (false) , _export_rolling (false) + , _realtime_export (false) , _export_preroll (0) , _export_latency (0) , _pre_export_mmc_enabled (false) diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index 1dee1f8d3c..84342fa3d9 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -104,13 +104,20 @@ Session::pre_export () /** Called for each range that is being exported */ int -Session::start_audio_export (framepos_t position) +Session::start_audio_export (framepos_t position, bool realtime) { if (!_exporting) { pre_export (); } - _export_preroll = Config->get_export_preroll() * nominal_frame_rate (); + _realtime_export = realtime; + + if (realtime) { + _export_preroll = nominal_frame_rate (); + } else { + _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; @@ -170,12 +177,19 @@ Session::start_audio_export (framepos_t position) return -1; } - _engine.Freewheel.connect_same_thread (export_freewheel_connection, boost::bind (&Session::process_export_fw, this, _1)); - _export_rolling = true; - return _engine.freewheel (true); + if (_realtime_export) { + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + _export_rolling = true; + process_function = &Session::process_export_fw; + return 0; + } else { + _engine.Freewheel.connect_same_thread (export_freewheel_connection, boost::bind (&Session::process_export_fw, this, _1)); + _export_rolling = true; + return _engine.freewheel (true); + } } -int +void Session::process_export (pframes_t nframes) { if (_export_rolling && export_status->stop) { @@ -201,26 +215,27 @@ Session::process_export (pframes_t nframes) } catch (std::exception & e) { error << string_compose (_("Export ended unexpectedly: %1"), e.what()) << endmsg; export_status->abort (true); - return -1; } - - return 0; } -int +void Session::process_export_fw (pframes_t nframes) { if (_export_preroll > 0) { - _engine.main_thread()->get_buffers (); + if (!_realtime_export) { + _engine.main_thread()->get_buffers (); + } fail_roll (nframes); - _engine.main_thread()->drop_buffers (); + if (!_realtime_export) { + _engine.main_thread()->drop_buffers (); + } _export_preroll -= std::min ((framepos_t)nframes, _export_preroll); if (_export_preroll > 0) { // clear out buffers (reverb tails etc). - return 0; + return; } set_transport_speed (1.0, 0, false); @@ -228,29 +243,36 @@ Session::process_export_fw (pframes_t nframes) g_atomic_int_set (&_butler->should_do_transport_work, 0); post_transport (); - return 0; + return; } if (_export_latency > 0) { framepos_t remain = std::min ((framepos_t)nframes, _export_latency); - _engine.main_thread()->get_buffers (); + if (!_realtime_export) { + _engine.main_thread()->get_buffers (); + } process_without_events (remain); - _engine.main_thread()->drop_buffers (); + if (!_realtime_export) { + _engine.main_thread()->drop_buffers (); + } _export_latency -= remain; nframes -= remain; if (nframes == 0) { - return 0; + return; } } - - _engine.main_thread()->get_buffers (); + if (!_realtime_export) { + _engine.main_thread()->get_buffers (); + } process_export (nframes); - _engine.main_thread()->drop_buffers (); + if (!_realtime_export) { + _engine.main_thread()->drop_buffers (); + } - return 0; + return; } int @@ -279,9 +301,13 @@ Session::finalize_audio_export () /* Clean up */ - _engine.freewheel (false); - - export_freewheel_connection.disconnect(); + if (_realtime_export) { + Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ()); + process_function = &Session::process_with_events; + } else { + _engine.freewheel (false); + export_freewheel_connection.disconnect(); + } _mmc->enable_send (_pre_export_mmc_enabled); |