diff options
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/export_graph_builder.h | 7 | ||||
-rw-r--r-- | libs/ardour/ardour/export_handler.h | 6 | ||||
-rw-r--r-- | libs/ardour/ardour/session.h | 3 | ||||
-rw-r--r-- | libs/ardour/export_graph_builder.cc | 34 | ||||
-rw-r--r-- | libs/ardour/export_handler.cc | 38 | ||||
-rw-r--r-- | libs/ardour/session_export.cc | 63 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 1 |
7 files changed, 85 insertions, 67 deletions
diff --git a/libs/ardour/ardour/export_graph_builder.h b/libs/ardour/ardour/export_graph_builder.h index 1244afd647..2f57aaf583 100644 --- a/libs/ardour/ardour/export_graph_builder.h +++ b/libs/ardour/ardour/export_graph_builder.h @@ -62,6 +62,7 @@ class ExportGraphBuilder ~ExportGraphBuilder (); int process (nframes_t frames, bool last_cycle); + bool process_normalize (); // returns true when finished void reset (); void add_config (FileSpec const & config); @@ -124,6 +125,9 @@ class ExportGraphBuilder void add_child (FileSpec const & new_config); bool operator== (FileSpec const & other_config) const; + /// Returns true when finished + bool process (); + private: typedef boost::shared_ptr<AudioGrapher::PeakReader> PeakReaderPtr; typedef boost::shared_ptr<AudioGrapher::Normalizer> NormalizerPtr; @@ -132,7 +136,6 @@ class ExportGraphBuilder typedef boost::shared_ptr<AudioGrapher::AllocatingProcessContext<Sample> > BufferPtr; void start_post_processing(); - void do_post_processing(); ExportGraphBuilder & parent; @@ -217,6 +220,8 @@ class ExportGraphBuilder Sample * process_buffer; nframes_t process_buffer_frames; + std::list<Normalizer *> normalizers; + Glib::ThreadPool thread_pool; }; diff --git a/libs/ardour/ardour/export_handler.h b/libs/ardour/ardour/export_handler.h index f7f3b863b9..971c0c4940 100644 --- a/libs/ardour/ardour/export_handler.h +++ b/libs/ardour/ardour/export_handler.h @@ -112,17 +112,21 @@ class ExportHandler : public ExportElementFactory private: + int process (nframes_t frames); + Session & session; GraphBuilderPtr graph_builder; StatusPtr export_status; ConfigMap config_map; bool realtime; + bool normalizing; /* Timespan management */ void start_timespan (); int process_timespan (nframes_t frames); + int process_normalize (); void finish_timespan (); typedef std::pair<ConfigMap::iterator, ConfigMap::iterator> TimespanBounds; @@ -131,8 +135,6 @@ class ExportHandler : public ExportElementFactory PBD::ScopedConnection process_connection; sframes_t process_position; - - PBD::ScopedConnection export_read_finished_connection; /* CD Marker stuff */ diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index ae9c1f58a5..b72822bd1c 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -530,7 +530,6 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi int start_audio_export (nframes_t position, bool realtime); PBD::Signal1<int,nframes_t> ProcessExport; - PBD::Signal0<void> ExportReadFinished; static PBD::Signal2<void,std::string, std::string> Exported; void add_source (boost::shared_ptr<Source>); @@ -934,7 +933,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi nframes_t post_export_position; bool _exporting; - bool _exporting_realtime; + bool _export_rolling; boost::shared_ptr<ExportHandler> export_handler; boost::shared_ptr<ExportStatus> export_status; diff --git a/libs/ardour/export_graph_builder.cc b/libs/ardour/export_graph_builder.cc index 5b5ec16b36..3b1d1e3838 100644 --- a/libs/ardour/export_graph_builder.cc +++ b/libs/ardour/export_graph_builder.cc @@ -56,11 +56,26 @@ ExportGraphBuilder::process (nframes_t frames, bool last_cycle) return 0; } +bool +ExportGraphBuilder::process_normalize () +{ + for (std::list<Normalizer *>::iterator it = normalizers.begin(); it != normalizers.end(); /* ++ in loop */) { + if ((*it)->process()) { + it = normalizers.erase (it); + } else { + ++it; + } + } + + return normalizers.empty(); +} + void ExportGraphBuilder::reset () { channel_configs.clear (); channels.clear (); + normalizers.clear (); } void @@ -252,20 +267,21 @@ ExportGraphBuilder::Normalizer::operator== (FileSpec const & other_config) const config.format->normalize_target() == other_config.format->normalize_target(); } -void -ExportGraphBuilder::Normalizer::start_post_processing() +bool +ExportGraphBuilder::Normalizer::process() { - normalizer->set_peak (peak_reader->get_peak()); - tmp_file->seek (0, SndfileReader<Sample>::SeekBeginning); - parent.thread_pool.push (sigc::mem_fun (*this, &Normalizer::do_post_processing)); + ProcessContext<Sample> buffer_copy (*buffer); + tmp_file->read (buffer_copy); + normalizer->process (buffer_copy); + return buffer_copy.frames() != buffer->frames(); } void -ExportGraphBuilder::Normalizer::do_post_processing() +ExportGraphBuilder::Normalizer::start_post_processing() { - while (tmp_file->read (*buffer) == buffer->frames()) { - normalizer->process (*buffer); - } + normalizer->set_peak (peak_reader->get_peak()); + tmp_file->seek (0, SndfileReader<Sample>::SeekBeginning); + parent.normalizers.push_back (this); } /* SRC */ diff --git a/libs/ardour/export_handler.cc b/libs/ardour/export_handler.cc index 3ce07cf44d..a9335add37 100644 --- a/libs/ardour/export_handler.cc +++ b/libs/ardour/export_handler.cc @@ -119,7 +119,7 @@ ExportHandler::add_export_config (TimespanPtr timespan, ChannelConfigPtr channel FileSpec spec (channel_config, format, filename); ConfigPair pair (timespan, spec); config_map.insert (pair); - + return true; } @@ -138,8 +138,6 @@ ExportHandler::do_export (bool rt) /* Start export */ realtime = rt; - - session.ExportReadFinished.connect_same_thread (export_read_finished_connection, boost::bind (&ExportHandler::finish_timespan, this)); start_timespan (); } @@ -149,6 +147,7 @@ ExportHandler::start_timespan () export_status->timespan++; if (config_map.empty()) { + // freewheeling has to be stopped from outside the process cycle export_status->running = false; return; } @@ -160,17 +159,33 @@ ExportHandler::start_timespan () timespan_bounds = config_map.equal_range (current_timespan); graph_builder->reset (); for (ConfigMap::iterator it = timespan_bounds.first; it != timespan_bounds.second; ++it) { - graph_builder->add_config (it->second); + // Filenames can be shared across timespans + FileSpec & spec = it->second; + spec.filename->set_timespan (it->first); + graph_builder->add_config (spec); } /* start export */ - session.ProcessExport.connect_same_thread (process_connection, boost::bind (&ExportHandler::process_timespan, this, _1)); + normalizing = false; + session.ProcessExport.connect_same_thread (process_connection, boost::bind (&ExportHandler::process, this, _1)); process_position = current_timespan->get_start(); session.start_audio_export (process_position, realtime); } int +ExportHandler::process (nframes_t frames) +{ + if (!export_status->running) { + return 0; + } else if (normalizing) { + return process_normalize (); + } else { + return process_timespan (frames); + } +} + +int ExportHandler::process_timespan (nframes_t frames) { /* update position */ @@ -184,6 +199,7 @@ ExportHandler::process_timespan (nframes_t frames) if (last_cycle) { frames_to_read = end - process_position; export_status->stop = true; + normalizing = true; } else { frames_to_read = frames; } @@ -196,11 +212,19 @@ ExportHandler::process_timespan (nframes_t frames) return graph_builder->process (frames_to_read, last_cycle); } +int +ExportHandler::process_normalize () +{ + if (graph_builder->process_normalize ()) { + finish_timespan (); + } + + return 0; +} + void ExportHandler::finish_timespan () { - process_connection.disconnect (); - while (config_map.begin() != timespan_bounds.second) { config_map.erase (config_map.begin()); } diff --git a/libs/ardour/session_export.cc b/libs/ardour/session_export.cc index 86a6250ffd..9a277f5655 100644 --- a/libs/ardour/session_export.cc +++ b/libs/ardour/session_export.cc @@ -123,8 +123,6 @@ Session::start_audio_export (nframes_t position, bool realtime) */ _transport_frame = position; - - _exporting_realtime = realtime; export_status->stop = false; /* get transport ready. note how this is calling butler functions @@ -144,39 +142,30 @@ Session::start_audio_export (nframes_t position, bool realtime) return -1; } - if (realtime) { - last_process_function = process_function; - process_function = &Session::process_export; - } else { - _engine.Freewheel.connect_same_thread (export_freewheel_connection, boost::bind (&Session::process_export_fw, this, _1)); - return _engine.freewheel (true); - } - - return 0; + _engine.Freewheel.connect_same_thread (export_freewheel_connection, boost::bind (&Session::process_export_fw, this, _1)); + _export_rolling = true; + return _engine.freewheel (true); } void Session::process_export (nframes_t nframes) { - try { - - if (export_status->stop) { - stop_audio_export (); - return; - } - - if (!_exporting_realtime) { - /* make sure we've caught up with disk i/o, since - we're running faster than realtime c/o JACK. - */ + if (_export_rolling && export_status->stop) { + stop_audio_export (); + } - _butler->wait_until_finished (); - } + if (_export_rolling) { + /* make sure we've caught up with disk i/o, since + we're running faster than realtime c/o JACK. + */ + _butler->wait_until_finished (); /* do the usual stuff */ process_without_events (nframes); - + } + + try { /* handle export - XXX what about error handling? */ ProcessExport (nframes); @@ -197,23 +186,16 @@ Session::process_export_fw (nframes_t nframes) int Session::stop_audio_export () { - if (_exporting_realtime) { - process_function = last_process_function; - } else { - export_freewheel_connection.disconnect(); - } - /* can't use stop_transport() here because we need an immediate halt and don't require all the declick stuff that stop_transport() implements. */ realtime_stop (true, true); + _export_rolling = false; _butler->schedule_transport_work (); - if (!export_status->aborted()) { - ExportReadFinished (); - } else { + if (export_status->aborted()) { finalize_audio_export (); } @@ -225,20 +207,11 @@ void Session::finalize_audio_export () { _exporting = false; - export_status->running = false; - - if (!_exporting_realtime) { - _engine.freewheel (false); - _exporting_realtime = false; - } + _export_rolling = false; /* Clean up */ - /* BOOST SIGNAL are these necessary? - ProcessExport.clear(); - ExportReadFinished.clear(); - */ - + _engine.freewheel (false); export_freewheel_connection.disconnect(); export_handler.reset(); export_status.reset(); diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 13b9112866..9394cd7bec 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -209,7 +209,6 @@ Session::first_stage_init (string fullpath, string snapshot_name) g_atomic_int_set (&_capture_load_min, 100); _play_range = false; _exporting = false; - _exporting_realtime = false; _gain_automation_buffer = 0; _pan_automation_buffer = 0; _npan_buffers = 0; |